diff options
author | Keith Seitz <keiths@redhat.com> | 2017-08-17 13:58:01 -0700 |
---|---|---|
committer | Keith Seitz <keiths@redhat.com> | 2017-08-17 13:58:01 -0700 |
commit | b5f28d7abc02ca509e389fa932d725cf111e4b40 (patch) | |
tree | 57a0dc0feaff890630a6ba2c9fab811d56b1f9cf /gdb | |
parent | 2a95a158fae932f758d75a1178a40d4cc4804ff0 (diff) | |
parent | 1a457753cfad05989574c671a221ffce2d5df703 (diff) | |
download | gdb-users/pmuldoon/c++compile.zip gdb-users/pmuldoon/c++compile.tar.gz gdb-users/pmuldoon/c++compile.tar.bz2 |
Update w/HEADusers/pmuldoon/c++compile
Problems:
gdb/compile/compile.c
gdb/cp-support.c
gdb/cp-support.h
gdb/gdbtypes.h
gdb/language.c
gdb/linespec.c
Diffstat (limited to 'gdb')
375 files changed, 12973 insertions, 7874 deletions
diff --git a/gdb/.dir-locals.el b/gdb/.dir-locals.el index a2aa196..48325b1 100644 --- a/gdb/.dir-locals.el +++ b/gdb/.dir-locals.el @@ -26,4 +26,6 @@ (c-basic-offset . 2) (eval . (c-set-offset 'innamespace 0)) )) + (c++-mode . ((eval . (when (fboundp 'c-toggle-comment-style) + (c-toggle-comment-style 1))))) ) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ac5965a..ea5dd32 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,1776 @@ +2017-08-15 Stafford Horne <shorne@gmail.com> + + * MAINTAINERS (Write After Approval): Add Stafford Horne. + +2017-08-15 Stafford Horne <shorne@gmail.com> + + * xtensa-tdep.c (xtensa_init_reggroups): Use xstrdup for cpname. + +2017-08-15 Sergio Durigan Junior <sergiodj@redhat.com> + + PR gdb/21954 + * infcmd.c (unset_environment_command): Use the 'clear' method on + the environment instead of resetting it. + +2017-08-15 John Baldwin <jhb@FreeBSD.org> + + * fbsd-nat.c (fbsd_convert_siginfo): Fix compile on big-endian + platforms. + +2017-08-14 Tom Tromey <tom@tromey.com> + + * valprint.c (print_octal_chars): Use HOST_CHAR_BIT. + (print_binary_chars): Likewise. + (BITS_IN_BYTES): Remove. + +2017-08-14 Tom Tromey <tom@tromey.com> + + PR gdb/21675 + * valprint.c (LOW_ZERO): Change value to 034. + (print_octal_chars): Add static_asserts for octal constants. + * printcmd.c (print_scalar_formatted): Add 'd' case. + +2017-08-11 Tom Tromey <tom@tromey.com> + + * symfile.c (add_symbol_file_command): Use std::vector. + +2017-08-14 Tom Tromey <tom@tromey.com> + + * break-catch-throw.c (handle_gnu_v3_exceptions): Use std::move. + * break-catch-syscall.c (create_syscall_event_catchpoint): Use + std::move. + * break-catch-sig.c (create_signal_catchpoint): Use std::move. + +2017-08-11 Pedro Alves <palves@redhat.com> + + * infrun.c (process_event_stop_test): Adjust + function_name_is_marked_for_skip call. + * skip.c: Include <list>. + (skiplist_entry): Make it a class with private fields, and + getters/setters. + (skiplist_entry_chain): Delete. + (skiplist_entries): New. + (skiplist_entry_count): Delete. + (highest_skiplist_entry_num): New. + (ALL_SKIPLIST_ENTRIES, ALL_SKIPLIST_ENTRIES_SAFE): Delete. + (add_skiplist_entry): Delete. + (skiplist_entry::skiplist_entry): New. + (skiplist_entry::add_entry): New. + (skip_file_command, skip_function): Adjust. + (compile_skip_regexp): Delete. + (skip_command): Don't compile regexp here. Adjust to use + skiplist_entry::add_entry. + (skip_info): Adjust to use range-for and getters. + (skip_enable_command, skip_disable_command): Adjust to use + range-for and setters. + (skip_delete_command): Adjust to use std::list. + (add_skiplist_entry): Delete. + (skip_file_p): Delete, refactored as ... + (skiplist_entry::do_skip_file_p): ... this new method. + (skip_gfile_p): Delete, refactored as ... + (skiplist_entry::do_gskip_file_p): ... this new method. + (skip_function_p, skip_rfunction_p): Delete, refactored as ... + (skiplist_entry::skip_function_p): ... this new method. + (function_name_is_marked_for_skip): Now returns bool, and takes + the function sal by const reference. Adjust to use range-for and + skiplist_entry methods. + (_initialize_step_skip): Remove references to + skiplist_entry_chain, skiplist_entry_count. + * skip.h (function_name_is_marked_for_skip): Now returns bool, and + takes the function sal by const reference. + +2017-08-11 Yao Qi <yao.qi@linaro.org> + + * dwarf2-frame.c (clear_pointer_cleanup): Remove. + (dwarf2_frame_cache): Remove reset_cache_cleanup. + (dwarf2_frame_cache): + * frame-unwind.c (frame_unwind_try_unwinder): Catch + RETURN_MASK_ALL and set *this_case to NULL. + * frame-unwind.h: Update comments. + +2017-08-11 Yao Qi <yao.qi@linaro.org> + + * dwarf2-frame.c (dwarf2_frame_state_alloc_regs): Remove. + (dwarf2_frame_state_copy_regs): Remove. + (dwarf2_frame_state_free_regs): Remove. + (dwarf2_frame_state::~dwarf2_frame_state): Remove. + (dwarf2_restore_rule): Call method .alloc_regs instead of + dwarf2_frame_state_alloc_regs. + (execute_cfa_program): Likewise. Call dwarf2_frame_state_reg_info + constructor. Call std::move. + (dwarf2_fetch_cfa_info): Don't call dwarf2_frame_state_copy_regs. + (dwarf2_frame_cache): Likewise. + + [GDB_SELF_TEST]: Include selftest.h and + selftest-arch.h. + [GDB_SELF_TEST] (execute_cfa_program_test): New function. + (_initialize_dwarf2_frame) [GDB_SELF_TEST]: Register + execute_cfa_program_test. + + * dwarf2-frame.h (dwarf2_frame_state_reg_info): Add ctor, dtor, + copy ctor, assignment operator, move assignment. + <alloc_regs>: New method. + <swap>: New method. + (struct dwarf2_frame_state): Delete dtor. + (dwarf2_frame_state_alloc_regs): Remove declaration. + * sparc-tdep.c (sparc_execute_dwarf_cfa_vendor_op): Don't call + dwarf2_frame_state_alloc_regs, use .alloc_regs instead. + +2017-08-11 Yao Qi <yao.qi@linaro.org> + + * dwarf2-frame.c (dwarf2_frame_state_free): Remove. + (dwarf2_frame_state::dwarf2_frame_state): New. + (dwarf2_frame_state::~dwarf2_frame_state): New. + (dwarf2_fetch_cfa_info): Update. + (dwarf2_frame_cache): Remove old_chain. Change 'fs' to an object + rather than a pointer. Update code. + * dwarf2-frame.h (struct dwarf2_frame_state): Declare ctor and + dtor. + <data_align, code_align, retaddr_column>: Change them to const. + <armcc_cfa_offsets_sf, armcc_cfa_offsets_reversed>: Change them + to bool. + +2017-08-11 Yao Qi <yao.qi@linaro.org> + + * dwarf2-frame.h (struct dwarf2_frame_state_reg) <exp_len>: Remove. + <loc.exp>: New field. + * dwarf2-frame.c (execute_cfa_program): Update. + (dwarf2_frame_prev_register): Update. + +2017-08-10 Pedro Alves <palves@redhat.com> + + * common/gdb_unique_ptr.h (xfree_deleter<T[]>): Define. + +2017-08-09 John Baldwin <jhb@FreeBSD.org> + + * fbsd-nat.c (struct fbsd_fork_info): Remove. + (fbsd_pending_children): Use std::list. + (fbsd_remember_child): Likewise. + (fbsd_is_child_pending): Likewise. + (fbsd_pending_vfork_done): Use std::forward_list. + (fbsd_add_vfork_done): Likewise. + (fbsd_is_vfork_done_pending): Likewise. + (fbsd_next_vfork_done): Likewise. + +2017-08-09 John Baldwin <jhb@FreeBSD.org> + + * fbsd-nat.c [HAVE_KINFO_GETVMMAP] (struct free_deleter): New. + (fbsd_find_memory_regions): Use free_deleter with std::unique_ptr. + [!HAVE_KINFO_GETVMMAP] (fbsd_find_memory_regions): Use std::string + for `mapfilename'. + (fbsd_xfer_partial): Use gdb::byte_vector. + (fbsd_add_threads): Likewise. + +2017-08-09 John Baldwin <jhb@FreeBSD.org> + + * fbsd-nat.c: [!HAVE_KINFO_GETVMMAP]: Include <sys/user.h> and + "filestuff.h". + (fbsd_find_memory_regions): Fix `mapfile' initialization. + +2017-08-09 Tom Tromey <tom@tromey.com> + + * skip.c (skiplist_entry): New constructor. + (skiplist_entry::enabled, skiplist_entry::function_is_regexp) + (skiplist_entry::file_is_glob): Now bool. + (skiplist_entry::file, skiplist_entry::function): Now + std::string. + (make_skip_entry): Return a unique_ptr. Use new. + (free_skiplist_entry, free_skiplist_entry_cleanup) + (make_free_skiplist_entry_cleanup): Remove. + (skip_command, skip_disable_command, add_skiplist_entry) + (skip_form_bytes, compile_skip_regexp, skip_command, skip_info) + (skip_file_p, skip_gfile_p, skip_function_p, skip_rfunction_p) + (function_name_is_marked_for_skip): Update. + (skip_delete_command): Update. Use delete. + +2017-08-09 Jiong Wang <jiong.wang@arm.com> + + * aarch64-linux-tdep.c: Include "auxv.h" and "elf/common.h". + (aarch64_linux_core_read_description): New function. + (aarch64_linux_init_abi): Register gdbarch_core_read_description. + +2017-08-09 Pedro Alves <palves@redhat.com> + + * cp-name-parser.y (cp_comp_to_string): Return a + gdb::unique_xmalloc_ptr<char>. + * cp-support.c (replace_typedefs_qualified_name) + (replace_typedefs): Adjust to use gdb::unique_xmalloc_ptr<char>. + (cp_canonicalize_string_full): Use op= instead of explicit + convertion. + (cp_class_name_from_physname, method_name_from_physname) + (cp_func_name, cp_remove_params): Adjust to use + gdb::unique_xmalloc_ptr<char>. + * cp-support.h (cp_comp_to_string): Return a + gdb::unique_xmalloc_ptr<char>. + * python/py-type.c (typy_lookup_type): Adjust to use + gdb::unique_xmalloc_ptr<char>. + +2017-08-09 H.J. Lu <hongjiu.lu@intel.com> + + * dwarf2read.c (dwarf2_string_attr): Fix a typo. + +2017-08-09 Alex Lindsay <alexlindsay239@gmail.com> + Yao Qi <yao.qi@linaro.org> + + * cp-support.c (cp_canonicalize_string_full): Use + gdb::unique_xmalloc_ptr<char>. + (cp_canonicalize_string): Likewise. + +2017-08-09 Yao Qi <yao.qi@linaro.org> + + * features/Makefile (WHICH): Remove i386/ non-linux stuff. + * regformats/i386/amd64-avx-avx512.dat: Remove. + * regformats/i386/amd64-avx-mpx-avx512-pku.dat: Remove. + * regformats/i386/amd64-avx-mpx.dat:Remove. + * regformats/i386/amd64-avx.dat: Remove. + * regformats/i386/amd64-mpx.dat: Remove. + * regformats/i386/i386-avx-avx512.dat: Remove. + * regformats/i386/i386-avx-mpx-avx512-pku.dat: Remove. + * regformats/i386/i386-avx-mpx.dat: Remove. + * regformats/i386/i386-mmx.dat: Remove. + * regformats/i386/i386-mpx.dat: Remove. + +2017-08-09 Yao Qi <yao.qi@linaro.org> + + * amd64-tdep.h (tdesc_x32): Remove the declaration. + * amd64-tdep.c: Don't include features/i386/x32*.c. + (_initialize_amd64_tdep): Don't call initialize_tdesc_x32* + functions. + * features/Makefile (WHICH): Remove i386/x32, i386/x32-avx, + and i386/x32-avx-avx512. + (XMLTOC): Remove i386/x32-avx.xml, i386/x32-avx-avx512.xml, + and i386/x32.xml. + * features/i386/x32-avx-avx512.c: Removed. + * features/i386/x32-avx-avx512.xml: Removed. + * features/i386/x32-avx.c: Removed. + * features/i386/x32-avx.xml: Removed. + * features/i386/x32.c: Removed. + * features/i386/x32.xml: Removed. + * regformats/i386/x32-avx-avx512.dat: Removed. + * regformats/i386/x32-avx.dat: Removed. + * regformats/i386/x32.dat: Removed. + +2017-08-07 Maciej W. Rozycki <macro@imgtec.com> + + PR breakpoints/21886 + * mem-break.c (default_memory_insert_breakpoint): Use + `->placed_address' rather than `->reqstd_address' for the + breakpoint location. + +2017-08-07 Maciej W. Rozycki <macro@imgtec.com> + + * arch-utils.c (default_print_insn): Remove arch/mach/endian + assertions. + +2017-08-07 Maciej W. Rozycki <macro@imgtec.com> + + * gdbarch.sh (gdbarch_info): Replace the `tdep_info' member with + a union of `tdep_info', `tdesc_data' and `id'. + * aarch64-tdep.c (aarch64_gdbarch_init): Use `info.tdesc_data' + rather than `info.tdep_info'. + * amd64-linux-tdep.c (amd64_linux_init_abi): Likewise. + * i386-linux-tdep.c (i386_linux_init_abi): Likewise. + * i386-tdep.c (i386_gdbarch_init): Likewise. + * mips-linux-tdep.c (mips_linux_init_abi): Likewise. + * mips-tdep.c (mips_gdbarch_init): Likewise. + * nds32-tdep.c (nds32_gdbarch_init): Likewise. + * rs6000-tdep.c (rs6000_gdbarch_init): Likewise. + * ppc-linux-tdep.c (ppu2spu_sniffer): Use `info.id' rather than + `info.tdep_info'. + (ppc_linux_init_abi): Use `info.tdesc_data' rather than + `info.tdep_info'. + * sparc-tdep.c (sparc32_gdbarch_init): Likewise. + * spu-multiarch.c (spu_gdbarch): Use `info.id' rather than + `info.tdep_info'. + * spu-tdep.c (spu_gdbarch_init): Likewise. + * gdbarch.h: Regenerate. + +2017-08-07 Leszek Swirski <leszeks@google.com> + + PR symtab/20899 + * dwarf2read.c (dwarf2_string_attr): Allow DW_FORM_GNU_strp_alt. + +2017-08-07 Simon Marchi <simon.marchi@ericsson.com> + + * remote-sim.c (gdbsim_load): Remove char **argv local variable. + (gdbsim_open): Rename gdb_argv args object to argv. + +2017-08-05 Tom Tromey <tom@tromey.com> + + * compile/compile-object-load.c (compile_object_load): Use + gdb::unique_xmalloc_ptr. + * cli/cli-dump.c (scan_filename): Rename from + scan_filename_with_cleanup. Change return type. + (scan_expression): Rename from scan_expression_with_cleanup. + Change return type. + (dump_memory_to_file, dump_value_to_file, restore_command): + Use gdb::unique_xmalloc_ptr. Update. + * cli/cli-cmds.c (find_and_open_script): Use + gdb::unique_xmalloc_ptr. + * tracefile-tfile.c (tfile_open): Use gdb::unique_xmalloc_ptr. + * symmisc.c (maintenance_print_symbols) + (maintenance_print_msymbols): Use gdb::unique_xmalloc_ptr. + * symfile.c (symfile_bfd_open, generic_load) + (add_symbol_file_command, remove_symbol_file_command): Use + gdb::unique_xmalloc_ptr. + * source.c (openp): Use gdb::unique_xmalloc_ptr. + * psymtab.c (maintenance_print_psymbols): Use + gdb::unique_xmalloc_ptr. + * corelow.c (core_open): Use gdb::unique_xmalloc_ptr. + * breakpoint.c (save_breakpoints): Use gdb::unique_xmalloc_ptr. + * solib.c (solib_map_sections): Use gdb::unique_xmalloc_ptr. + (reload_shared_libraries_1): Likewise. + +2017-08-05 Tom Tromey <tom@tromey.com> + + * rust-exp.y (rust_op_ptr, set_field): Remove typedefs. + (rust_op_vector, rust_set_vector): New typedefs. + (current_parser): New global. + (work_obstack): Change to pointer type. Update all users. + (rust_ast, pstate): Remove globals. + (struct rust_parser): New. + (%union) <params, field_inits>: Change type. + (start, tuple_expr, unit_expr, struct_expr_list, literal) + (field_expr, expr_list, maybe_expr_list, type_list): Update. + (ast_call_ish, ast_path, ast_function_type, ast_tuple_type) + (convert_params_to_types, convert_params_to_expression): Change + type of "params". + (ast_string): Change type of "fields". + (rust_parse): Make a rust_parser. Remove cleanups. + (rust_lex_tests): Make and install an auto_obstack. + +2017-08-04 Yao Qi <yao.qi@linaro.org> + + * configure.srv (ipa_x32_linux_regobj): New. + * linux-amd64-ipa.c (get_ipa_tdesc): Use X86_TDESC_AVX_AVX512 + instead of X86_TDESC_AVX512. + (initialize_low_tracepoint): Call + init_registers_x32_avx_avx512_linux. + +2017-08-04 Yao Qi <yao.qi@linaro.org> + + * utils.h (gdb_argv): Add namespace std for nullptr_t. + +2017-08-03 Ruslan Kabatsayev <b7.10110111@gmail.com> + + * MAINTAINERS (Write After Approval): Add Ruslan Kabatsayev. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * utils.c (make_cleanup_freeargv, do_freeargv, gdb_buildargv): + Remove. + * utils.h (make_cleanup_freeargv, gdb_buildargv): Remove. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * python/py-param.c (compute_enum_values): Use gdb_argv. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * utils.h (struct gdb_argv_deleter): New. + (gdb_argv): New class. + * utils.c (gdb_argv::reset): New method. + * tracepoint.c (delete_trace_variable_command): Use gdb_argv. + * tracefile.c (tsave_command): Use gdb_argv. + * top.c (new_ui_command): Use gdb_argv. + * symmisc.c (maintenance_print_symbols) + (maintenance_print_msymbols, maintenance_expand_symtabs): Use gdb_argv. + * symfile.c (symbol_file_command, generic_load) + (remove_symbol_file_command): Use gdb_argv. + * stack.c (backtrace_command): Use gdb_argv. + * source.c (add_path, show_substitute_path_command) + (unset_substitute_path_command, set_substitute_path_command): + Use gdb_argv. + * skip.c (skip_command): Use gdb_argv. Use gdb_buildargv. + * ser-mingw.c (pipe_windows_open): Use gdb_argv. + * remote.c (extended_remote_run, remote_put_command) + (remote_get_command, remote_delete_command): Use gdb_argv. + * remote-sim.c (gdbsim_load, gdbsim_create_inferior) + (gdbsim_open): Use gdb_argv. + * python/py-cmd.c (gdbpy_string_to_argv): Use gdb_argv. + * psymtab.c (maintenance_print_psymbols): Use gdb_argv. + * procfs.c (procfs_info_proc): Use gdb_argv. + * interps.c (interpreter_exec_cmd): Use gdb_argv. + * infrun.c (handle_command): Use gdb_argv. + * inferior.c (add_inferior_command, clone_inferior_command): + Use gdb_argv. + * guile/scm-string.c (gdbscm_string_to_argv): Use gdb_argv. + * exec.c (exec_file_command): Use gdb_argv. + * cli/cli-cmds.c (alias_command): Use gdb_argv. + * compile/compile.c (build_argc_argv): Use gdb_argv. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * python/python.c (gdbpy_decode_line): Use unique_xmalloc_ptr. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * python/python.c (compute_python_string): Return std::string. + (gdbpy_eval_from_control_command): Update. + (do_start_initialization): Use std::string. + * python/py-varobj.c (py_varobj_iter_next): Use string_printf, not + xstrprintf. + * python/py-breakpoint.c (local_setattro): Use string_printf, not + xstrprintf. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * top.h (do_restore_instream_cleanup): Remove. + * top.c (do_restore_instream_cleanup): Remove. + (read_command_file): Use scoped_restore. + * cli/cli-script.c (execute_user_command): Use scoped_restore. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * cli/cli-script.c (execute_user_command) + (execute_control_command): Use scoped_restore. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * cli/cli-script.c (do_restore_user_call_depth): Remove. + (execute_user_command): Remove user_call_depth; use + user_args_stack's size instead. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * top.h (in_user_command): Remove. + * top.c (in_user_command): Remove. + * cli/cli-script.c (do_restore_user_call_depth) + (execute_user_command): Update. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * valops.c (search_struct_method): Use gdb::byte_vector. + * valarith.c (value_concat): Use std::vector. + * target.c (memory_xfer_partial): Use gdb::byte_vector. + (simple_search_memory): Likewise. + * printcmd.c (find_string_backward): Use gdb::byte_vector. + * mi/mi-main.c (mi_cmd_data_write_memory): Use gdb::byte_vector. + * gcore.c (gcore_copy_callback): Use gdb::byte_vector. + * elfread.c (elf_rel_plt_read): Use std::string. + * cp-valprint.c (cp_print_value): Use gdb::byte_vector. + * cli/cli-dump.c (restore_section_callback): Use + gdb::byte_vector. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * jit.c (jit_reader_load_command): Use unique_xmalloc_ptr. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * tui/tui-regs.c (tui_restore_gdbout): Remove. + (tui_register_format): Use scoped_restore. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * reverse.c (exec_direction_default): Remove. + (exec_reverse_once): Use scoped_restore. + * remote.c (restore_remote_timeout): Remove. + (remote_flash_erase, remote_flash_write, remote_flash_done) + (readchar, remote_serial_write): Use scoped_restore. + * cli/cli-script.c (struct source_cleanup_lines_args) + (source_cleanup_lines): Remove. + (script_from_file): Use scoped_restore. + * cli/cli-cmds.c (source_verbose_cleanup): Remove. + (source_command): Use scoped_restore. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * utils.h (make_cleanup_free_so): Remove. + * utils.c (do_free_so, make_cleanup_free_so): Remove. + * solist.h (struct so_deleter): New. + (so_list_up): New typedef. + * solib-svr4.c (svr4_read_so_list): Use so_list_up. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * utils.h (make_cleanup_restore_current_language): Remove. + * utils.c (do_restore_current_language) + (make_cleanup_restore_current_language): Remove. + * parse.c (parse_exp_in_context_1) + (parse_expression_with_language): Use + scoped_restore_current_language. + * mi/mi-main.c (mi_cmd_execute): Use + scoped_restore_current_language. + * language.h (scoped_restore_current_language): New class. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * compile/compile.c (cleanup_unlink_file): Remove. + (compile_to_object): Use gdb::unlinker. + (eval_compile_command): Likewise. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * utils.h (make_cleanup_fclose): Remove. + * utils.c (do_fclose_cleanup, make_cleanup_fclose): Remove. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * top.c (open_terminal_stream): Return gdb_file_up. + (new_ui_command): Update. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * source.c (print_source_lines_base, forward_search_command) + (reverse_search_command): Use gdb_file_up. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * fbsd-nat.c (fbsd_find_memory_regions): Update. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * cli/cli-cmds.c (find_and_open_script): Change return type. + Remove "streamp" and "full_path" parameters. + (source_script_with_search): Update. + * auto-load.c (source_script_file): Update. + * cli/cli-cmds.h (find_and_open_script): Change type. + (open_script): New struct. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * xml-support.c (xml_fetch_content_from_file): Update. + * ui-file.c (stdio_file::open): Update. + * tracefile-tfile.c (tfile_start): Update. + * remote.c (remote_file_put, remote_file_get): Update. + * nat/linux-procfs.c (linux_proc_get_int) + (linux_proc_pid_get_state, linux_proc_tid_get_name): Update. + * nat/linux-osdata.c (linux_common_core_of_thread): Update. + (command_from_pid, commandline_from_pid, linux_xfer_osdata_cpus) + (print_sockets, linux_xfer_osdata_shm, linux_xfer_osdata_sem) + (linux_xfer_osdata_msg, linux_xfer_osdata_modules): Update. + * nat/linux-btrace.c (linux_determine_kernel_start): Update. + * linux-nat.c (linux_proc_pending_signals): Update. + * dwarf2read.c (write_psymtabs_to_index): Use gdb_file_up. + (file_closer): Remove. + * compile/compile.c (compile_to_object): Update. + * common/filestuff.h (struct gdb_file_deleter): New. + (gdb_file_up): New typedef. + (gdb_fopen_cloexec): Change return type. + * common/filestuff.c (gdb_fopen_cloexec): Return gdb_file_up. + * cli/cli-dump.c (fopen_with_cleanup): Remove. + (dump_binary_file, restore_binary_file): Update. + * auto-load.c (auto_load_objfile_script_1): Update. + +2017-08-03 Tom Tromey <tom@tromey.com> + + * tracepoint.c (tvariables_info_1): Use ui_out_emit_table. + (info_static_tracepoint_markers_command): Likewise. + * solib.c (info_sharedlibrary_command): Use ui_out_emit_table. + * skip.c (skip_info): Use ui_out_emit_table. + * progspace.c (print_program_space): Use ui_out_emit_table. + * osdata.c (info_osdata): Use ui_out_emit_table. + * mi/mi-cmd-info.c (mi_cmd_info_ada_exceptions): Use + ui_out_emit_table. + * linux-thread-db.c (info_auto_load_libthread_db): Use + ui_out_emit_table. + * inferior.c (print_inferior): Use ui_out_emit_table. + * gdb_bfd.c (maintenance_info_bfds): Use ui_out_emit_table. + * breakpoint.c (breakpoint_1): Use ui_out_emit_table. + * auto-load.c (auto_load_info_scripts): Use ui_out_emit_table. + * ada-tasks.c (print_ada_task_info): Use ui_out_emit_table. + * ui-out.h (class ui_out_emit_table): New. + +2017-08-02 Maciej W. Rozycki <macro@imgtec.com> + + * mips-tdep.c (mips_fpu_type_str): New function. + (mips_dump_tdep): Call it. + +2017-08-01 Maciej W. Rozycki <macro@imgtec.com> + + * mips-tdep.c (mips_gdbarch_init): Use MIPS_FPU_TYPE to access + `->mips_fpu_type'. + +2017-07-31 Xavier Roirand <roirand@adacore.com> + + * solib-darwin.c (DYLD_VERSION_MAX): Increase value. + +2017-07-27 Xavier Roirand <roirand@adacore.com> + + * MAINTAINERS (Write After Approval): Add Xavier Roirand. + +2017-07-26 Yao Qi <yao.qi@linaro.org> + + * cli/cli-cmds.c (maintenancechecklist): New variable. + * gdbcmd.h (maintenancechecklist): Declare it. + * i386-linux-tdep.c (_initialize_i386_linux_tdep) [GDB_SELF_TEST]: + Call i386_linux_read_description with different masks. + * maint.c (maintenance_check_command): New function. + (_initialize_maint_cmds): Call add_prefix_cmd. + * target-descriptions.c (tdesc_reg): override operator != and ==. + (tdesc_type): Likewise. + (tdesc_feature): Likewise. + (target_desc): Likewise. + [GDB_SELF_TEST] (selftests::record_xml_tdesc): New function. + (maintenance_check_xml_descriptions): New function. + (_initialize_target_descriptions) Add command "xml-descriptions". + * target-descriptions.h (selftests::record_xml_tdesc): Declare. + +2017-07-26 Yao Qi <yao.qi@linaro.org> + + * i386-linux-tdep.c: Don't include features/i386/i386-*linux.c. + Include features/i386/32bit-*.c. + (i386_linux_read_description): Generate target description if it + doesn't exist. + (_initialize_i386_linux_tdep): Don't call _initialize_tdesc_i386 + functions. + * features/i386/32bit-linux.c: Re-generated. + * features/i386/32bit-sse.c: Likewise. + * target-descriptions.c (print_c_feature::visit): Print code to + set register number if needed. + (print_c_feature) <m_next_regnum>: New field. + +2017-07-26 Yao Qi <yao.qi@linaro.org> + + * features/Makefile (CFILES): Rename with TDESC_CFILES. + (FEATURE_XMLFILES): New. + (FEATURE_CFILES): New. + New rules. + (clean-cfiles): Remove generated c files. + * features/i386/32bit-avx.c: Generated. + * features/i386/32bit-avx512.c: Generated. + * features/i386/32bit-core.c: Generated. + * features/i386/32bit-linux.c: Generated. + * features/i386/32bit-mpx.c: Generated. + * features/i386/32bit-pkeys.c: Generated. + * features/i386/32bit-sse.c: Generated. + * target-descriptions.c: Include algorithm. + (tdesc_element_visitor): Add method visit_end. + (print_c_tdesc): Implement visit_end. + (print_c_tdesc:: m_filename_after_features): Move it to + protected. + (print_c_feature): New class. + (maint_print_c_tdesc_cmd): Use print_c_feature if XML file + name starts with "i386/32bit-". + +2017-07-26 Yao Qi <yao.qi@linaro.org> + + * target-descriptions.c (tdesc_element_visitor): New class. + (tdesc_element): New class. + (tdesc_reg): Inherit from tdesc_element. + (tdesc_reg::accept): New function. + (tdesc_type): Inherit from tdesc_element. + (tdesc_type::accept): New function. + (tdesc_feature): Inherit from tdesc_element. + (tdesc_feature::accept): New function. + (target_desc): Inherit from tdesc_element. + (target_desc::target_desc): New. + (target_desc::~target_desc): New. + (target_desc::accept): New. + (allocate_target_description): Use new. + (free_target_description): Use delete. + (print_c_tdesc): New class. + (maint_print_c_tdesc_cmd): Adjust. + + * features/aarch64.c: Re-generated. + * features/arc-arcompact.c: Re-generated. + * features/arc-v2.c: Re-generated. + * features/arm/arm-with-iwmmxt.c: Re-generated. + * features/arm/arm-with-m.c: Re-generated. + * features/arm/arm-with-m-fpa-layout.c: Re-generated. + * features/arm/arm-with-m-vfp-d16.c: Re-generated. + * features/arm/arm-with-neon.c: Re-generated. + * features/arm/arm-with-vfpv2.c: Re-generated. + * features/arm/arm-with-vfpv3.c: Re-generated. + * features/i386/amd64-avx-avx512.c: Re-generated. + * features/i386/amd64-avx-avx512-linux.c: Re-generated. + * features/i386/amd64-avx.c: Re-generated. + * features/i386/amd64-avx-linux.c: Re-generated. + * features/i386/amd64-avx-mpx-avx512-pku.c: Re-generated. + * features/i386/amd64-avx-mpx-avx512-pku-linux.c: Re-generated. + * features/i386/amd64-avx-mpx.c: Re-generated. + * features/i386/amd64-avx-mpx-linux.c: Re-generated. + * features/i386/amd64.c: Re-generated. + * features/i386/amd64-linux.c: Re-generated. + * features/i386/amd64-mpx.c: Re-generated. + * features/i386/amd64-mpx-linux.c: Re-generated. + * features/i386/i386-avx-avx512.c: Re-generated. + * features/i386/i386-avx-avx512-linux.c: Re-generated. + * features/i386/i386-avx.c: Re-generated. + * features/i386/i386-avx-linux.c: Re-generated. + * features/i386/i386-avx-mpx-avx512-pku.c: Re-generated. + * features/i386/i386-avx-mpx-avx512-pku-linux.c: Re-generated. + * features/i386/i386-avx-mpx.c: Re-generated. + * features/i386/i386-avx-mpx-linux.c: Re-generated. + * features/i386/i386.c: Re-generated. + * features/i386/i386-linux.c: Re-generated. + * features/i386/i386-mmx.c: Re-generated. + * features/i386/i386-mmx-linux.c: Re-generated. + * features/i386/i386-mpx.c: Re-generated. + * features/i386/i386-mpx-linux.c: Re-generated. + * features/i386/x32-avx-avx512.c: Re-generated. + * features/i386/x32-avx-avx512-linux.c: Re-generated. + * features/i386/x32-avx.c: Re-generated. + * features/i386/x32-avx-linux.c: Re-generated. + * features/i386/x32.c: Re-generated. + * features/i386/x32-linux.c: Re-generated. + * features/microblaze.c: Re-generated. + * features/microblaze-with-stack-protect.c: Re-generated. + * features/mips64-dsp-linux.c: Re-generated. + * features/mips64-linux.c: Re-generated. + * features/mips-dsp-linux.c: Re-generated. + * features/mips-linux.c: Re-generated. + * features/nds32.c: Re-generated. + * features/nios2.c: Re-generated. + * features/nios2-linux.c: Re-generated. + * features/rs6000/powerpc-32.c: Re-generated. + * features/rs6000/powerpc-32l.c: Re-generated. + * features/rs6000/powerpc-403.c: Re-generated. + * features/rs6000/powerpc-403gc.c : Re-generated. + * features/rs6000/powerpc-405.c: Re-generated. + * features/rs6000/powerpc-505.c: Re-generated. + * features/rs6000/powerpc-601.c: Re-generated. + * features/rs6000/powerpc-602.c: Re-generated. + * features/rs6000/powerpc-603.c: Re-generated. + * features/rs6000/powerpc-604.c: Re-generated. + * features/rs6000/powerpc-64.c: Re-generated. + * features/rs6000/powerpc-64l.c: Re-generated. + * features/rs6000/powerpc-7400.c: Re-generated. + * features/rs6000/powerpc-750.c: Re-generated. + * features/rs6000/powerpc-860.c: Re-generated. + * features/rs6000/powerpc-altivec32.c: Re-generated. + * features/rs6000/powerpc-altivec32l.c: Re-generated. + * features/rs6000/powerpc-altivec64.c: Re-generated. + * features/rs6000/powerpc-altivec64l.c: Re-generated. + * features/rs6000/powerpc-cell32l.c: Re-generated. + * features/rs6000/powerpc-cell64l.c: Re-generated. + * features/rs6000/powerpc-e500.c: Re-generated. + * features/rs6000/powerpc-e500l.c: Re-generated. + * features/rs6000/powerpc-isa205-32l.c: Re-generated. + * features/rs6000/powerpc-isa205-64l.c: Re-generated. + * features/rs6000/powerpc-isa205-altivec32l.c: Re-generated. + * features/rs6000/powerpc-isa205-altivec64l.c: Re-generated. + * features/rs6000/powerpc-isa205-vsx32l.c: Re-generated. + * features/rs6000/powerpc-isa205-vsx64l.c: Re-generated. + * features/rs6000/powerpc-vsx32.c: Re-generated. + * features/rs6000/powerpc-vsx32l.c: Re-generated. + * features/rs6000/powerpc-vsx64.c: Re-generated. + * features/rs6000/powerpc-vsx64l.c: Re-generated. + * features/rs6000/rs6000.c: Re-generated. + * features/s390-linux32.c: Re-generated. + * features/s390-linux32v1.c: Re-generated. + * features/s390-linux32v2.c: Re-generated. + * features/s390-linux64.c: Re-generated. + * features/s390-linux64v1.c: Re-generated. + * features/s390-linux64v2.c: Re-generated. + * features/s390-te-linux64.c: Re-generated. + * features/s390-tevx-linux64.c: Re-generated. + * features/s390-vx-linux64.c: Re-generated. + * features/s390x-linux64.c: Re-generated. + * features/s390x-linux64v1.c: Re-generated. + * features/s390x-linux64v2.c: Re-generated. + * features/s390x-te-linux64.c: Re-generated. + * features/s390x-tevx-linux64.c: Re-generated. + * features/s390x-vx-linux64.c: Re-generated. + * features/sparc/sparc32-solaris.c: Re-generated. + * features/sparc/sparc64-solaris.c: Re-generated. + * features/tic6x-c62x.c: Re-generated. + * features/tic6x-c62x-linux.c: Re-generated. + * features/tic6x-c64x.c: Re-generated. + * features/tic6x-c64x-linux.c: Re-generated. + * features/tic6x-c64xp.c: Re-generated. + * features/tic6x-c64xp-linux.c: Re-generated. + +2017-07-26 Yao Qi <yao.qi@linaro.org> + + * i386-linux-tdep.c (i386_linux_read_description): New function. + (i386_linux_core_read_description): Call + i386_linux_read_description. + * i386-linux-tdep.h (i386_linux_read_description): Declare. + (tdesc_i386_linux, tdesc_i386_mmx_linux): Remove declarations. + (tdesc_i386_avx_linux, tdesc_i386_mpx_linux): Likewise + (tdesc_i386_avx_mpx_linux, tdesc_i386_avx_avx512_linux): Likewise. + (tdesc_i386_avx_mpx_avx512_pku_linux): Likewise. + * x86-linux-nat.c (x86_linux_read_description): Call + i386_linux_read_description. + +2017-07-26 Yao Qi <yao.qi@linaro.org> + + * NEWS: Mention it. + * features/Makefile (%.c: %.xml): Pass the xml file name to + command "maint print c-tdesc". + * target-descriptions.c (maint_print_c_tdesc_cmd): Get file + name from 'arg'. + +2017-07-26 Yao Qi <yao.qi@linaro.org> + + * target-descriptions.c (target_desc): Add ctor and dtor. Do + in-class initialization. + (tdesc_create_feature): Call new instead of XCNEW. + (free_target_description): Ue delete. + +2017-07-25 John Baldwin <jhb@FreeBSD.org> + + * configure.nat: Add "-lkvm" for NetBSD/sparc64 and fix typo. + +2017-07-25 Yao Qi <yao.qi@linaro.org> + + * amd64-tdep.c (amd64_init_abi): Make argument default_tdesc + constant. + (amd64_x32_init_abi): Likewise. + * amd64-tdep.h (amd64_init_abi): Update declaration. + (amd64_x32_init_abi): Likewise. + +2017-07-25 Yao Qi <yao.qi@linaro.org> + + PR tdep/21717 + * arm-linux-nat.c (arm_linux_fetch_inferior_registers): Update + condition for FPSCR. + (arm_linux_store_inferior_registers): Likewise. + +2017-07-22 Tom Tromey <tom@tromey.com> + + * break-catch-syscall.c (struct catch_syscall_inferior_data) + <syscalls_counts>: Now a std::vector. + (get_catch_syscall_inferior_data): Use "new". + (catch_syscall_inferior_data_cleanup): Use "delete". + (insert_catch_syscall, remove_catch_syscall) + (clear_syscall_counts): Update. + +2017-07-22 Tom Tromey <tom@tromey.com> + + * break-catch-syscall.c (syscall_catchpoint) + <syscalls_to_be_caught>: Now a std::vector<int> + (~syscall_catchpoint): Remove. + (insert_catch_syscall, remove_catch_syscall) + (breakpoint_hit_catch_syscall, print_one_catch_syscall) + (print_mention_catch_syscall, print_recreate_catch_syscall): + Update. + (create_syscall_event_catchpoint): Change type of "filter" + parameter. + (catch_syscall_split_args): Return a std::vector. + (catch_syscall_command_1, catching_syscall_number_1): Update. + +2017-07-22 Tom Tromey <tom@tromey.com> + + * break-catch-throw.c (struct exception_catchpoint) + <exception_rx>: Now a std::string. + (~exception_catchpoint): Remove. + (print_one_detail_exception_catchpoint): Update. + (handle_gnu_v3_exceptions): Change type of except_rx. + (extract_exception_regexp): Return a std::string. + (catch_exception_command_1): Update. + +2017-07-22 Tom Tromey <tom@tromey.com> + + * break-catch-sig.c (gdb_signal_type): Remove typedef. + (struct signal_catchpoint) <signals_to_be_caught>: Now a + std::vector. + <catch_all>: Now a bool. + (~signal_catchpoint): Remove. + (signal_catchpoint_insert_location) + (signal_catchpoint_remove_location) + (signal_catchpoint_breakpoint_hit, signal_catchpoint_print_one) + (signal_catchpoint_print_mention) + (signal_catchpoint_print_recreate) + (signal_catchpoint_explains_signal): Update. + (create_signal_catchpoint): Change type of "filter" and + "catch_all". + (catch_signal_split_args): Return a std::vector. Change type of + "catch_all". + (catch_signal_command): Update. + +2017-07-20 Pedro Alves <palves@redhat.com> + + * ada-lang.c (ada_language_defn): Make extern. + (_initialize_ada_language): Remove add_language call. + * c-lang.c (c_language_defn, cplus_language_defn) + (asm_language_defn, minimal_language_defn): Make extern. + (_initialize_c_language): Delete. + * completer.c (compare_cstrings): Delete, moved to utils.h. + * d-lang.c (d_language_defn): Make extern. + (_initialize_d_language): Remove add_language calls. + * defs.h (enum language): Add comment. + * f-lang.c (f_language_defn): Make extern. + (_initialize_f_language): Remove add_language call. + * go-lang.c (go_language_defn): Make extern. + (_initialize_go_language): Remove add_language call. + * language.c: Include <algorithm>. + (languages): Redefine as const array. + (languages_size, languages_allocsize, DEFAULT_ALLOCSIZE): Delete. + (set_language_command): Handle "local". Use for-range loop. + (set_language): Remove loop. + (language_enum): Rewrite. + (language_def, language_str): Remove loops. + (add_language): Delete. + (add_set_language_command): New, based on add_languages. + (skip_language_trampoline): Adjust. + (local_language_defn): Delete. + (language_gdbarch_post_init): Adjust. + (_initialize_language): Remove add_language calls. Call + add_set_language_command. + * language.h (add_language): Delete. + (auto_language_defn) + (unknown_language_defn, minimal_language_defn, ada_language_defn) + (asm_language_defn, c_language_defn, cplus_language_defn) + (d_language_defn, f_language_defn, go_language_defn) + (m2_language_defn, objc_language_defn, opencl_language_defn) + (pascal_language_defn, rust_language_defn): Declare. + * m2-lang.c (m2_language_defn): Make extern. + (_initialize_m2_language): Remove add_language call. + * objc-lang.c (objc_language_defn): Make extern. + (_initialize_objc_language): Remove add_language call. + * opencl-lang.c (opencl_language_defn): Make extern. + (_initialize_opencl_language): Remove add_language call. + * p-lang.c (pascal_language_defn): Make extern. + (_initialize_pascal_language): Delete. + * rust-lang.c (rust_language_defn): Make extern. + (_initialize_rust_language): Delete. + * utils.h (compare_cstrings): New static inline function. + +2017-07-20 Pedro Alves <palves@redhat.com> + + * ada-lang.c (ada_to_fixed_type_1): Adjust. + (get_var_value): Constify parameters. + (get_int_var_value): Change prototype. + (to_fixed_range_type): Adjust. + * ada-lang.h (get_int_var_value): Change prototype. + +2017-07-20 Pedro Alves <palves@redhat.com> + + * dwarf2read.c (dw2_lookup_symbol): Use + SYMBOL_MATCHES_SEARCH_NAME. + * psymtab.c (psym_lookup_symbol): Use SYMBOL_MATCHES_SEARCH_NAME. + +2017-07-20 Pedro Alves <palves@redhat.com> + + * block.c (block_iter_name_step, block_iter_name_first) + (block_iter_name_next): Delete. + (block_lookup_symbol_primary): Adjust to use + dict_iter_match_first/dict_iter_match_next. + * block.h (block_iter_name_first, block_iter_name_next): Delete + declarations. + (ALL_BLOCK_SYMBOLS_WITH_NAME): Adjust to use + dict_iter_match_first/dict_iter_match_next. + +2017-07-20 Pedro Alves <palves@redhat.com> + + * cp-support.c (cp_find_first_component_aux): Add missing case for + end of string. + +2017-07-18 David Blaikie <dblaikie@gmail.com> + + * dwarf2read.c (create_cus_hash_table): Re-add lost initialization + of dwo_cu's dwo_file. + +2017-07-18 Yao Qi <yao.qi@linaro.org> + + * remote.c (store_registers_using_G): Remove one line comment. + +2017-07-18 Yao Qi <yao.qi@linaro.org> + + * regcache.c (regcache_cpy): Simplify it. + (regcache::cpy_no_passthrough): Remove it. + * regcache.h (cpy_no_passthrough): Remove it. + (regcache_dup, regcache_cpy): Update comments. + +2017-07-18 Pedro Alves <palves@redhat.com> + + * remote-sim.c (sim_command_completer): Adjust to work with a + completion_tracker instead of a VEC. + +2017-07-17 Pedro Alves <palves@redhat.com> + + * completer.c (complete_source_filenames): New function. + (complete_address_and_linespec_locations): New function. + (location_completer): Use complete_address_and_linespec_locations. + (completion_tracker::build_completion_result): Honor the tracker's + request to suppress append. + * completer.h (completion_tracker::suppress_append_ws) + (completion_tracker::set_suppress_append_ws): New methods. + (completion_tracker::m_suppress_append_ws): New field. + (complete_source_filenames): New declaration. + * linespec.c (linespec_complete_what): New. + (struct ls_parser) <complete_what, completion_word, + completion_quote_char, completion_quote_end, completion_tracker>: + New fields. + (string_find_incomplete_keyword_at_end): New. + (linespec_lexer_lex_string): Record quote char. If in completion + mode, don't throw. + (linespec_lexer_consume_token): Advance the completion word point. + (linespec_lexer_peek_token): Save/restore completion info. + (save_stream_and_consume_token): New. + (set_completion_after_number): New. + (linespec_parse_basic): Set what to complete next depending on + token. Handle function and label completions specially. + (parse_linespec): Disable objc shortcut in completion mode. Set + what to complete next depending on token type. Skip keyword if in + completion mode. + (complete_linespec_component, linespec_complete): New. + * linespec.h (linespec_complete): Declare. + +2017-07-17 Pedro Alves <palves@redhat.com> + + * linespec.c (linespec_lexer_lex_string, find_toplevel_char): + Handle 'operator<' / 'operator<<'. + +2017-07-17 Pedro Alves <palves@redhat.com> + + * completer.c (collect_explicit_location_matches): Handle + MATCH_LABEL. + (convert_explicit_location_to_linespec): New, factored out from + ... + (convert_explicit_location_to_sals): ... this. + (complete_label): New. + (linespec_complete_label, find_label_symbols_in_block): New. + (find_label_symbols): Add completion_mode parameter and adjust to + call find_label_symbols_in_block. + * linespec.h (linespec_complete_label): Declare. + +2017-07-17 Pedro Alves <palves@redhat.com> + + * ada-lang.c (ada_collect_symbol_completion_matches): Add + complete_symbol_mode parameter. + * cli/cli-cmds.c (complete_command): Get the completion result out + of the handle_brkchars tracker if used a custom word point. + * completer.c: Include "linespec.h". + (enum explicit_location_match_type) <MATCH_LINE>: New enumerator. + (advance_to_expression_complete_word_point): New. + (completion_tracker::completes_to_completion_word): New. + (complete_files_symbols): Pass down + complete_symbol_mode::EXPRESSION. + (explicit_options, probe_options): New. + (collect_explicit_location_matches): Complete on the + explictit_loc->foo instead of word. Use + linespec_complete_function. Handle MATCH_LINE. Handle offering + keyword and options completions. + (backup_text_ptr): Delete. + (skip_keyword): New. + (complete_explicit_location): Remove 'word' parameter. Add + language, quoted_arg_start and quoted_arg_end parameters. + Rewrite, parsing left to right. + (location_completer): Rewrite. + (location_completer_handle_brkchars): New function. + (symbol_completer): Pass down complete_symbol_mode::EXPRESSION. + (enum complete_line_internal_reason): Adjust comments. + (completion_tracker::discard_completions): New. + (completer_handle_brkchars_func_for_completer): Handle + location_completer. + (gdb_custom_word_point_brkchars) + (gdb_org_rl_basic_quote_characters): New. + (gdb_completion_word_break_characters_throw) + (completion_find_completion_word): Handle trackers that use a + custom word point. + (completion_tracker::advance_custom_word_point_by): New. + (completion_tracker::build_completion_result): Don't rely on + readline appending the quote char. + (gdb_rl_attempted_completion_function_throw): Handle trackers that + use a custom word point. + (gdb_rl_attempted_completion_function): Restore + rl_basic_quote_characters. + * completer.h (class completion_tracker): Extend intro comment. + (completion_tracker::set_quote_char) + (completion_tracker::quote_char) + (completion_tracker::set_use_custom_word_point) + (completion_tracker::use_custom_word_point) + (completion_tracker::custom_word_point) + (completion_tracker::set_custom_word_point) + (completion_tracker::advance_custom_word_point_by) + (completion_tracker::completes_to_completion_word) + (completion_tracker::discard_completions): New methods. + (completion_tracker::m_quote_char) + (completion_tracker::m_use_custom_word_point) + (completion_tracker::m_custom_word_point): New fields. + (advance_to_expression_complete_word_point): Declare. + * f-lang.c (f_collect_symbol_completion_matches): Add + complete_symbol_mode parameter. + * language.h (struct language_defn) + <la_collect_symbol_completion_matches>: Add complete_symbol_mode + parameter. + * linespec.c (linespec_keywords): Add NULL terminator. Make extern. + (linespec_complete_function): New function. + (linespec_lexer_lex_keyword): Adjust. + * linespec.h (linespec_keywords, linespec_complete_function): New + declarations. + * location.c (find_end_quote): New function. + (explicit_location_lex_one): Add explicit_completion_info + parameter. Save quoting info. Don't throw if being called for + completion. Don't handle Ada operators here. + (is_cp_operator, skip_op_false_positives, first_of) + (explicit_location_lex_one_function): New function. + (string_to_explicit_location): Replace 'dont_throw' parameter with + an explicit_completion_info pointer parameter. Handle it. Don't + use explicit_location_lex_one to lex function names. Use + explicit_location_lex_one_function instead. + * location.h (struct explicit_completion_info): New. + (string_to_explicit_location): Replace 'dont_throw' parameter with + an explicit_completion_info pointer parameter. + * symtab.c (default_collect_symbol_completion_matches_break_on): + Add complete_symbol_mode parameter. Handle LINESPEC mode. + (default_collect_symbol_completion_matches) + (collect_symbol_completion_matches): Add complete_symbol_mode + parameter. + (collect_symbol_completion_matches_type): Pass down + complete_symbol_mode::EXPRESSION. + (collect_file_symbol_completion_matches): Add complete_symbol_mode + parameter. Handle LINESPEC mode. + * symtab.h (complete_symbol_mode): New. + (default_collect_symbol_completion_matches_break_on) + (default_collect_symbol_completion_matches) + (collect_symbol_completion_matches) + (collect_file_symbol_completion_matches): Add complete_symbol_mode + parameter. + +2017-07-17 Pedro Alves <palves@redhat.com> + + * utils.c (enum class strncmp_iw_mode): New. + (strcmp_iw): Rename to ... + (strncmp_iw_with_mode): ... this. Add string2_len and mode + parameters. Handle them. + (strncmp_iw): New. + (strcmp_iw): Reimplement as wrapper around strncmp_iw_with_mode. + * utils.h (strncmp_iw): Declare. + (strcmp_iw): Move describing comments here. + +2017-07-17 Pedro Alves <palves@redhat.com> + + * c-exp.y (operator_stoken): Use CP_OPERATOR_LEN and + CP_OPERATOR_STR. + * c-typeprint.c (is_type_conversion_operator): Use + CP_OPERATOR_STR. + * cp-support.c (LENGTH_OF_OPERATOR): Delete. + (cp_find_first_component_aux): Use CP_OPERATOR_STR and + CP_OPERATOR_LEN. + * cp-support.h (CP_OPERATOR_STR, CP_OPERATOR_LEN): New. + * gnu-v2-abi.c (gnuv2_is_operator_name): Use CP_OPERATOR_STR. + * gnu-v3-abi.c (gnuv3_is_operator_name): Use CP_OPERATOR_STR. + * linespec.c (linespec_lexer_lex_string): Use CP_OPERATOR_LEN and + CP_OPERATOR_STR. + * location.c: Include "cp-support.h". + (explicit_location_lex_one): Use CP_OPERATOR_LEN and + CP_OPERATOR_STR. + * symtab.c (operator_chars): Use CP_OPERATOR_STR and + CP_OPERATOR_LEN. + +2017-07-17 Pedro Alves <palves@redhat.com> + + * cli/cli-cmds.c (complete_command): Use a completion tracker + along with completion_find_completion_word for handle_brkchars + phase. + * completer.c (RL_QF_SINGLE_QUOTE, RL_QF_DOUBLE_QUOTE) + (RL_QF_BACKSLASH, RL_QF_OTHER_QUOTE): New. + (struct gdb_rl_completion_word_info): New. + (gdb_rl_find_completion_word): New. + (completion_find_completion_word): New. + * completer.h (completion_find_completion_word): Declare. + +2017-07-17 Pedro Alves <palves@redhat.com> + + * ada-lang.c (symbol_completion_match): Adjust comments. + (symbol_completion_add): Replace vector parameter with + completion_tracker parameter. Use it. + (ada_make_symbol_completion_list): Rename to... + (ada_collect_symbol_completion_matches): ... this. Add + completion_tracker parameter and use it. + (ada_language_defn): Adjust. + * break-catch-syscall.c (catch_syscall_completer): Adjust + prototype and work with completion_tracker instead of VEC. + * breakpoint.c (condition_completer): Adjust prototype and work + with completion_tracker instead of VEC. + * c-lang.c (c_language_defn, cplus_language_defn) + (asm_language_defn, minimal_language_defn): Adjust to renames. + * cli/cli-cmds.c (complete_command): Rework using + completion_tracker. Catch exceptions when completing. + * cli/cli-decode.c (integer_unlimited_completer) + (complete_on_cmdlist, complete_on_enum): Adjust prototype and work + with completion_tracker instead of VEC. + * command.h (struct completion_tracker): Forward declare. + (completer_ftype, completer_handle_brkchars_ftype): Change + types. + (complete_on_cmdlist, complete_on_enum): Adjust. + * completer.c: Include <algorithm>. + (struct gdb_completer_state): New. + (current_completion): New global. + (readline_line_completion_function): Delete. + (noop_completer, filename_completer) + (filename_completer_handle_brkchars, complete_files_symbols) + (linespec_location_completer): Adjust to work with a + completion_tracker instead of a VEC. + (string_or_empty): New. + (collect_explicit_location_matches): Adjust to work with a + completion_tracker instead of a VEC. + (explicit_location_completer): Rename to ... + (complete_explicit_location): ... this and adjust to work with a + completion_tracker instead of a VEC. + (location_completer): Adjust to work with a completion_tracker + instead of a VEC. + (add_struct_fields): Adjust to work with a completion_list instead + of VEC. + (expression_completer): Rename to ... + (complete_expression): ... this and adjust to work with a + completion_tracker instead of a VEC. Use complete_files_symbols. + (expression_completer): Reimplement on top of complete_expression. + (symbol_completer): Adjust to work with a completion_tracker + instead of a VEC. + (enum complete_line_internal_reason): Add describing comments. + (complete_line_internal_normal_command): Adjust to work with a + completion_tracker instead of a VEC. + (complete_line_internal): Rename to ... + (complete_line_internal_1): ... this and adjust to work with a + completion_tracker instead of a VEC. Assert TEXT is NULL in the + handle_brkchars phase. + (new_completion_tracker): Delete. + (complete_line_internal): Reimplement as TRY/CATCH wrapper around + complete_line_internal_1. + (free_completion_tracker): Delete. + (INITIAL_COMPLETION_HTAB_SIZE): New. + (completion_tracker::completion_tracker) + (completion_tracker::~completion_tracker): New. + (maybe_add_completion): Delete. + (completion_tracker::maybe_add_completion) + (completion_tracker::add_completion) + (completion_tracker::add_completions): New. + (throw_max_completions_reached_error): Delete. + (complete_line): Adjust to work with a completion_tracker instead + of a VEC. Don't create a completion_tracker_t or check for max + completions here. + (command_completer, command_completer_handle_brkchars) + (signal_completer, reg_or_group_completer_1) + (reg_or_group_completer, default_completer_handle_brkchars): + Adjust to work with a completion_tracker. + (gdb_completion_word_break_characters_throw): New. + (gdb_completion_word_break_characters): Reimplement. + (line_completion_function): Delete. + (completion_tracker::recompute_lowest_common_denominator) + (expand_preserving_ws) + (completion_tracker::build_completion_result) + (completion_result::completion_result) + (completion_result::completion_result) + (completion_result::~completion_result) + (completion_result::completion_result) + (completion_result::release_match_list, compare_cstrings) + (completion_result::sort_match_list) + (completion_result::reset_match_list) + (gdb_rl_attempted_completion_function_throw) + (gdb_rl_attempted_completion_function): New. + * completer.h (completion_list, struct completion_result) + (class completion_tracker): New. + (complete_line): Add completion_tracker parameter. + (readline_line_completion_function): Delete. + (gdb_rl_attempted_completion_function): New. + (noop_completer, filename_completer, expression_completer) + (location_completer, symbol_completer, command_completer) + (signal_completer, reg_or_group_completer): Update prototypes. + (completion_tracker_t, new_completion_tracker) + (make_cleanup_free_completion_tracker): Delete. + (enum maybe_add_completion_enum): Delete. + (maybe_add_completion): Delete. + (throw_max_completions_reached_error): Delete. + * corefile.c (complete_set_gnutarget): Adjust to work with a + completion_tracker instead of a VEC. + * cp-abi.c (cp_abi_completer): Adjust to work with a + completion_tracker instead of a VEC. + * d-lang.c (d_language_defn): Adjust. + * disasm.c (disassembler_options_completer): Adjust to work with a + completion_tracker instead of a VEC. + * f-lang.c (f_make_symbol_completion_list): Rename to ... + (f_collect_symbol_completion_matches): ... this. Adjust to work + with a completion_tracker instead of a VEC. + (f_language_defn): Adjust. + * go-lang.c (go_language_defn): Adjust. + * guile/scm-cmd.c (cmdscm_add_completion, cmdscm_completer): + Adjust to work with a completion_tracker instead of a VEC. + * infrun.c (handle_completer): Likewise. + * interps.c (interpreter_completer): Likewise. + * interps.h (interpreter_completer): Likewise. + * language.c (unknown_language_defn, auto_language_defn) + (local_language_defn): Adjust. + * language.h (language_defn::la_make_symbol_completion_list): + Rename to ... + (language_defn::la_collect_symbol_completion_matches): ... this + and adjust to work with a completion_tracker instead of a VEC. + * m2-lang.c (m2_language_defn): Adjust. + * objc-lang.c (objc_language_defn): Adjust. + * opencl-lang.c (opencl_language_defn): Adjust. + * p-lang.c (pascal_language_defn): Adjust. + * python/py-cmd.c (cmdpy_completer_helper): Handle NULL word. + (cmdpy_completer_handle_brkchars, cmdpy_completer): Adjust to work + with a completion_tracker. + * rust-lang.c (rust_language_defn): Adjust. + * symtab.c (free_completion_list, do_free_completion_list) + (return_val, completion_tracker): Delete. + (completion_list_add_name, completion_list_add_symbol) + (completion_list_add_msymbol, completion_list_objc_symbol) + (completion_list_add_fields, add_symtab_completions): Add + completion_tracker parameter and use it. + (default_make_symbol_completion_list_break_on_1): Rename to... + (default_collect_symbol_completion_matches_break_on): ... this. + Add completion_tracker parameter and use it instead of allocating + a completion tracker here. + (default_make_symbol_completion_list_break_on): Delete old + implementation. + (default_make_symbol_completion_list): Delete. + (default_collect_symbol_completion_matches): New. + (make_symbol_completion_list): Delete. + (collect_symbol_completion_matches): New. + (make_symbol_completion_type): Rename to ... + (collect_symbol_completion_matches_type): ... this. Add + completion_tracker parameter and use it instead of VEC. + (make_file_symbol_completion_list_1): Rename to... + (collect_file_symbol_completion_matches): ... this. Add + completion_tracker parameter and use it instead of VEC. + (make_file_symbol_completion_list): Delete. + (add_filename_to_list): Use completion_list instead of a VEC. + (add_partial_filename_data::list): Now a completion_list. + (make_source_files_completion_list): Work with a completion_list + instead of a VEC. + * symtab.h: Include "completer.h". + (default_make_symbol_completion_list_break_on) + (default_make_symbol_completion_list, make_symbol_completion_list) + (make_symbol_completion_type, make_file_symbol_completion_list) + (make_source_files_completion_list): Delete. + (default_collect_symbol_completion_matches_break_on) + (default_collect_symbol_completion_matches) + (collect_symbol_completion_matches) + (collect_symbol_completion_matches_type) + (collect_file_symbol_completion_matches) + (make_source_files_completion_list): New. + * top.c (init_main): Don't install a rl_completion_entry_function + hook. Install a rl_attempted_completion_function hook instead. + * tui/tui-layout.c (layout_completer): Adjust to work with a + completion_tracker. + * tui/tui-regs.c (tui_reggroup_completer): + * tui/tui-win.c (window_name_completer, focus_completer) + (winheight_completer): Adjust to work with a completion_tracker. + * value.c: Include "completer.h". + (complete_internalvar): Adjust to work with a completion_tracker. + * value.h (complete_internalvar): Likewise. + +2017-07-17 Pedro Alves <palves@redhat.com> + + * cli/cli-decode.c (set_cmd_completer_handle_brkchars): Adjust to + renames. + * cli/cli-decode.h (struct cmd_list_element) <completer>: Move + comments to completer_ftype's declaration. + <completer_handle_brkchars>: Change type to + completer_handle_brkchars_ftype. + * command.h (completer_ftype): Add describing comment and give + names to parameters. + (completer_ftype_void): Rename to ... + (completer_handle_brkchars_ftype) ... this. Add describing comment. + (set_cmd_completer_handle_brkchars): Adjust. + * completer.c (filename_completer_handle_brkchars): New function. + (complete_line_internal_normal_command): New function, factored + out from ... + (complete_line_internal): ... here. + (command_completer_handle_brkchars) + (default_completer_handle_brkchars) + (completer_handle_brkchars_func_for_completer): New functions. + * completer.h (set_gdb_completion_word_break_characters): Delete + declaration. + (completer_handle_brkchars_func_for_completer): New declaration. + * python/py-cmd.c (cmdpy_completer_handle_brkchars): Adjust to use + completer_handle_brkchars_func_for_completer. + +2017-07-17 Pedro Alves <palves@redhat.com> + + * completer.c (symbol_completer): New function, based on + make_symbol_completion_list_fn. + * completer.h (symbol_completer): New declaration. + * guile/scm-cmd.c (cmdscm_completers): Adjust. + * python/py-cmd.c (completers): Adjust. + * symtab.c (make_symbol_completion_list_fn): Delete. + * symtab.h (make_symbol_completion_list_fn): Delete. + * cli/cli-decode.c (add_cmd): Adjust. + +2017-07-17 Pedro Alves <palves@redhat.com> + + * Makefile.in (COMMON_OBS): Add filename-seen-cache.o. + * dwarf2read.c: Include "filename-seen-cache.h". + * dwarf2read.c (dwarf2_per_objfile) <filenames_cache>: New field. + (dw2_map_symbol_filenames): Build and use a filenames_seen_cache. + * filename-seen-cache.c: New file. + * filename-seen-cache.h: New file. + * symtab.c: Include "filename-seen-cache.h". + (struct filename_seen_cache, INITIAL_FILENAME_SEEN_CACHE_SIZE) + (create_filename_seen_cache, clear_filename_seen_cache) + (delete_filename_seen_cache, filename_seen): Delete, parts moved + to filename-seen-cache.h/filename-seen-cache.c. + (output_source_filename, sources_info) + (maybe_add_partial_symtab_filename) + (make_source_files_completion_list): Adjust to use + filename_seen_cache. + +2017-07-17 Pedro Alves <palves@redhat.com> + + * dwarf2read.c (dwarf2_per_objfile): In-class initialize all + fields. + (dwarf2_per_objfile::dwarf2_per_objfile(objfile*, const + dwarf2_debug_sections*)): New. + (dwarf2_per_objfile::dwarf2_per_objfile(const + dwarf2_per_objfile&)): Declare as deleted. + (dwarf2_per_objfile::operator=): Declare as deleted. + (dwarf2_per_objfile::dwarf2_per_objfile) + (dwarf2_per_objfile::~dwarf2_per_objfile) + (dwarf2_per_objfile::free_cached_comp_units): New. + (dwarf2_has_info): dwarf2_per_objfile initialization code moved to + ctor. Call dwarf2_per_objfile's ctor manually. + (dwarf2_locate_sections): Deleted/refactored as ... + (dwarf2_per_objfile::locate_sections): ... this new method. + (free_cached_comp_units): Defer to + dwarf2_per_objfile::free_cached_comp_units. + (dwarf2_free_objfile): Call dwarf2_per_objfile's dtor manually. + +2017-07-14 Tom Tromey <tom@tromey.com> + + PR rust/21764: + * rust-exp.y (convert_ast_to_expression): Add "want_type" + parameter. + <UNOP_SIZEOF>: Split into separate case. + <UNOP_VAR_VALUE>: Handle want_type. Add error case. + +2017-07-14 Tom Tromey <tom@tromey.com> + + PR rust/21763: + * symtab.c (symbol_matches_domain): Add language_rust to special + case. + * rust-exp.y (convert_ast_to_expression) <OP_VAR_VALUE>: Don't + treat LOC_TYPEDEF symbols as variables. + +2017-07-14 Pedro Alves <palves@redhat.com> + + * symtab.c (make_file_symbol_completion_list_1): Iterate over + symtabs matching all symtabs with SRCFILE as file name instead of + only considering the first hit, with lookup_symtab. + +2017-07-14 Simon Marchi <simon.marchi@ericsson.com> + + * ax-gdb.c (gen_aggregate_elt_ref): Remove operand_name and + operator_name parameters. + (gen_expr): Update function call. + +2017-07-14 Simon Marchi <simon.marchi@ericsson.com> + + * dwarf2loc.h (dwarf2_compile_expr_to_ax): Remove gdbarch + parameter. + * symtab.h (struct symbol_computed_ops::tracepoint_var_ref): + Likewise. + * dwarf2loc.c (dwarf2_compile_expr_to_ax): Remove gdbarch + parameter, use agent_expr::gdbarch instead, update function + calls. + (locexpr_tracepoint_var_ref): Likewise. + (loclist_tracepoint_var_ref): Likewise. + * ax-gdb.c (gen_trace_static_fields): Likewise. + (gen_traced_pop): Likewise. + (gen_frame_args_address): Likewise. + (gen_frame_locals_address): Likewise. + (gen_var_ref): Likewise. + (gen_struct_ref_recursive): Likewise. + (gen_static_field): Likewise. + (gen_maybe_namespace_elt): Likewise. + (gen_expr): Likewise. + (gen_trace_for_var): Likewise. + (gen_trace_for_expr): Likewise. + (gen_trace_for_return_address): Likewise. + +2017-07-14 Simon Marchi <simon.marchi@ericsson.com> + + * ax-gdb.c (gen_deref, gen_address_of): Remove unused ax + parameter. + (gen_struct_ref, gen_expr, gen_expr_binop_rest): Update call. + +2017-07-14 Simon Marchi <simon.marchi@ericsson.com> + + * ax-gdb.c (gen_usual_unary): Remove exp parameter, get gdbarch + from ax, update calls. + (gen_usual_arithmetic): Likewise. + (gen_integral_promotions): Likewise. + (gen_bitfield_ref): Likewise. + (gen_primitive_field): Likewise. + (gen_struct_ref_recursive): Likewise. + (gen_struct_ref): Likewise. + (gen_maybe_namespace_elt): Likewise. + (gen_struct_elt_for_reference): Likewise. + (gen_namespace_elt): Likewise. + (gen_aggregate_elt_ref): Likewise. + (gen_expr): Get gdbarch from ax, update calls. + (gen_expr_binop_rest): Likewise. + +2017-07-13 Pedro Alves <palves@redhat.com> + + * amd64-darwin-tdep.c (x86_darwin_init_abi_64): Pass tdesc_amd64 + as default tdesc. + * amd64-dicos-tdep.c (amd64_dicos_init_abi): + * amd64-fbsd-tdep.c (amd64fbsd_init_abi): + * amd64-linux-tdep.c (amd64_linux_init_abi): Pass + tdesc_amd64_linux as default tdesc. Get final tdesc from the + tdep. + (amd64_x32_linux_init_abi): Pass tdesc_x32_linux as default tdesc. + Get final tdesc from the tdep. + * amd64-nbsd-tdep.c (amd64nbsd_init_abi): Pass tdesc_amd64 as + default tdesc. + * amd64-obsd-tdep.c (amd64obsd_init_abi): Likewise. + * amd64-sol2-tdep.c (amd64_sol2_init_abi): Likewise. + * amd64-tdep.c (amd64_init_abi): Add 'default_tdesc' parameter. + Use it as default tdesc. + (amd64_x32_init_abi): Add 'default_tdesc' parameter, and pass it + down to amd_init_abi. No longer handle fallback tdesc here. + * amd64-tdep.h (tdesc_x32): Declare. + (amd64_init_abi, amd64_x32_init_abi): Add 'default_tdesc' + parameter. + * amd64-windows-tdep.c (amd64_windows_init_abi): Pass tdesc_amd64 + as default tdesc. + +2017-07-13 Andreas Arnez <arnez@linux.vnet.ibm.com> + + * s390-linux-tdep.c (s390_process_record): Add support for + instructions new in arch12. + +2017-07-11 John Baldwin <jhb@FreeBSD.org> + + * amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers): Use + PT_GETFSBASE and PT_GETGSBASE. + (amd64bsd_store_inferior_registers): Use PT_SETFSBASE and + PT_SETGSBASE. + +2017-07-11 John Baldwin <jhb@FreeBSD.org> + + * features/Makefile (amd64.dat, amd64-avx.dat, amd64-mpx.dat) + (amd64-avx-mpx.dat, amd64-avx-avx512.dat) + (amd64-avx-mpx-avx512-pku.dat): Add i386/64bit-segments.xml in + those rules. + * features/i386/amd64-avx-avx512.xml: Add 64bit-segments.xml. + * features/i386/amd64-avx-mpx-avx512-pku.xml: Add 64bit-segments.xml. + * features/i386/amd64-avx-mpx.xml: Add 64bit-segments.xml. + * features/i386/amd64-avx.xml: Add 64bit-segments.xml. + * features/i386/amd64-mpx.xml: Add 64bit-segments.xml. + * features/i386/amd64.xml: Add 64bit-segments.xml. + * features/i386/amd64-avx-avx512.c: Regenerated. + * features/i386/amd64-avx-mpx-avx512-pku.c: Regenerated. + * features/i386/amd64-avx-mpx.c: Regenerated. + * features/i386/amd64-avx.c: Regenerated. + * features/i386/amd64-mpx.c: Regenerated. + * features/i386/amd64.c: Regenerated. + * regformats/i386/amd64-avx-avx512.dat: Regenerated. + * regformats/i386/amd64-avx-mpx-avx512-pku.dat: Regenerated. + * regformats/i386/amd64-avx-mpx.dat: Regenerated. + * regformats/i386/amd64-avx.dat: Regenerated. + * regformats/i386/amd64-mpx.dat: Regenerated. + * regformats/i386/amd64.dat: Regenerated. + +2017-07-10 Yao Qi <yao.qi@linaro.org> + + * features/i386/amd64-avx-avx512-linux.c: Re-generated. + * features/i386/amd64-avx-mpx-avx512-pku-linux.c: Re-generated. + +2017-07-10 Anton Kolesov <Anton.Kolesov@synopsys.com> + + * gnulib/update-gnulib.sh (IMPORTED_GNULIB_MODULES): Add setenv and + unsetenv. + * gnulib/aclocal.m4: Regenerate. + * gnulib/config.in: Regenerate. + * gnulib/configure: Regenerate. + * gnulib/import/Makefile.am: Regenerate. + * gnulib/import/Makefile.in: Regenerate. + * gnulib/import/m4/gnulib-cache.m4: Regenerate. + * gnulib/import/m4/gnulib-comp.m4: Regenerate. + * gnulib/import/m4/environ.m4: New file. + * gnulib/import/m4/setenv.m4: New file. + * gnulib/import/setenv.c: New file. + * gnulib/import/unsetenv.c: New file. + +2017-07-09 Simon Marchi <simon.marchi@ericsson.com> + + * compile/compile-loc2c.c (do_compile_dwarf_expr_to_c): Read + address when op is DW_OP_addr. + +2017-07-09 Tom Tromey <tom@tromey.com> + + * dwarf2loc.c (dwarf2_evaluate_loc_desc_full): Reverse size + check and apply to outer type. + +2017-07-07 John Baldwin <jhb@FreeBSD.org> + + * fbsd-tdep.c (LWPINFO_OFFSET, LWPINFO_PL_FLAGS) + (LWPINFO64_PL_SIGINFO, LWPINFO32_PL_SIGINFO, PL_FLAG_SI) + (SIZE64_SIGINFO_T, SIZE32_SIGINFO_T, fbsd_core_xfer_siginfo): New. + (fbsd_init_abi): Install gdbarch "core_xfer_siginfo" method. + +2017-07-07 John Baldwin <jhb@FreeBSD.org> + + * fbsd-tdep.c (fbsd_core_thread_name): Use thread_section_name. + +2017-07-07 John Baldwin <jhb@FreeBSD.org> + + * corelow.c (get_core_siginfo): Remove. + (core_xfer_partial): Use the gdbarch "core_xfer_siginfo" method + instead of get_core_siginfo. + * gdbarch.sh (core_xfer_siginfo): New gdbarch callback. + * gdbarch.h: Re-generate. + * gdbarch.c: Re-generate. + * linux-tdep.c (linux_core_xfer_siginfo): New. + (linux_init_abi): Install gdbarch "core_xfer_siginfo" method. + +2017-07-07 John Baldwin <jhb@FreeBSD.org> + + * corelow.c (thread_section_name): Move to ... + * gdbcore.h (thread_section_name): ... here. + +2017-07-07 John Baldwin <jhb@FreeBSD.org> + + * fbsd-nat.c [PT_LWPINFO && __LP64__] (union sigval32) + (struct siginfo32): New. + [PT_LWPINFO] (fbsd_siginfo_size, fbsd_convert_siginfo): New. + (fbsd_xfer_partial) [PT_LWPINFO]: Handle TARGET_OBJECT_SIGNAL_INFO + via ptrace(PT_LWPINFO). + +2017-07-07 John Baldwin <jhb@FreeBSD.org> + + * fbsd-tdep.c (fbsd_gdbarch_data_handle, struct fbsd_gdbarch_data) + (init_fbsd_gdbarch_data, get_fbsd_gdbarch_data) + (fbsd_get_siginfo_type): New. + (fbsd_init_abi): Install gdbarch "get_siginfo_type" method. + (_initialize_fbsd_tdep): New. + +2017-07-06 David Blaikie <dblaikie@gmail.com> + + * dwarf2read.c (struct dwo_file): Use a htab of dwo_unit* (rather than + a singular dwo_unit*) to support multiple CUs in the same way that + multiple TUs are supported. + (create_cus_hash_table): Replace create_dwo_cu with a function for + parsing multiple CUs from a DWO file. + (open_and_init_dwo_file): Use create_cus_hash_table rather than + create_dwo_cu. + (lookup_dwo_cutu): Lookup CU in the hash table in the dwo_file with + htab_find, rather than comparing the signature to a singleton CU in + the dwo_file. + +2017-07-06 Pedro Alves <palves@redhat.com> + + * python/py-unwind.c (pyuw_dealloc_cache): Fix for loop condition. + +2017-07-04 Pedro Alves <palves@redhat.com> + + * gdbtypes.c (recursive_dump_type): Don't reference TYPE_STATIC. + * gdbtypes.h (TYPE_STATIC): Delete. + (struct fn_field) <is_public, is_abstract, is_static, is_final, + is_synchronized, is_native>: Delete. + <dummy>: Bump. + (TYPE_FN_FIELD_PUBLIC, TYPE_FN_FIELD_STATIC, TYPE_FN_FIELD_FINAL) + (TYPE_FN_FIELD_SYNCHRONIZED, TYPE_FN_FIELD_NATIVE) + (TYPE_FN_FIELD_ABSTRACT): Delete. + +2017-07-03 Simon Marchi <simon.marchi@ericsson.com> + + * buffer.h (buffer_finish): Fix spelling mistakes. + +2017-07-01 Eli Zaretskii <eliz@gnu.org> + + * .dir-locals.el: Automatically switch to C-style comments in + versions of Emacs that support the feature. + +2017-06-30 Sergio Durigan Junior <sergiodj@redhat.com> + Pedro Alves <palves@redhat.com> + + PR cli/21688 + * cli/cli-script.c (command_name_equals_not_inline): Remove function. + (process_next_line): New variable 'inline_cmd'. + Adjust 'if' clauses for "python", "compile" and "guile" to use + 'command_name_equals' and check for '!inline_cmd'. + +2017-06-30 Sergio Durigan Junior <sergiodj@redhat.com> + + PR cli/21688 + * cli/cli-script.c (command_name_equals_not_inline): New function. + (process_next_line): Adjust 'if' clauses for "python", "compile" + and "guile" to use command_name_equals_not_inline. + +2017-06-29 Pedro Alves <palves@redhat.com> + + * completer.c (expression_completer): Call + linespec_location_completer instead of location_completer. + +2017-06-29 Pedro Alves <palves@redhat.com> + + * completer.c (expression_completer): Remove code that recomputes + 'text' from 'word'. + +2017-06-29 Yao Qi <yao.qi@linaro.org> + + * regformats/regdat.sh: Generate code with + "ifndef IN_PROCESS_AGENT". + +2017-06-28 Pedro Alves <palves@redhat.com> + + * command.h: Include "common/scoped_restore.h". + +2017-06-28 Yao Qi <yao.qi@linaro.org> + + * mi/mi-cmd-break.c (mi_argv_to_format): Use obstack_grow_str + instead of obstack_grow. + +2017-06-28 Doug Gilmore <Doug.Gilmore@imgtec.com> + + PR gdb/21337 + * symfile.c (reread_symbols): Call objfiles_changed just before + read_symbols. + +2017-06-27 Pedro Alves <palves@redhat.com> + + * symtab.c (COMPLETION_LIST_ADD_SYMBOL) + (MCOMPLETION_LIST_ADD_SYMBOL): Delete macros, replace with ... + (completion_list_add_symbol, completion_list_add_msymbol): + ... these new functions. + (add_symtab_completions) + (default_make_symbol_completion_list_break_on_1): Adjust. + +2017-06-27 Pedro Alves <palves@redhat.com> + + * objfiles.c (get_objfile_bfd_data): Call bfd_alloc instead of + bfd_zalloc. Call objfile_per_bfd_storage's ctor. + (free_objfile_per_bfd_storage): Call objfile_per_bfd_storage's + dtor. + * objfiles.h (objfile_per_bfd_storage): Add ctor. Make + 'storage_obstack' field an auto_obstack. In-class initialize all + non-bitfield fields. Make minsyms_read bool. + * symfile.c (read_symbols): Adjust. + +2017-06-27 Alan Hayward <alan.hayward@arm.com> + + * remote-sim.c (gdbsim_fetch_register): Use byte_vector. + (gdbsim_store_register): Likewise. + +2017-06-27 Pedro Alves <palves@redhat.com> + + * c-exp.y (name_obstack): Now an auto_obstack. + (yylex): Use auto_obstack::clear. + (c_parse): Use auto_obstack::clear instead of reinitializing and + freeing the obstack. + * c-lang.c (evaluate_subexp_c): Use auto_obstack. + * d-exp.y (name_obstack): Now an auto_obstack. + (yylex): Use auto_obstack::clear. + (d_parse): Use auto_obstack::clear instead of reinitializing and + freeing the obstack. + * dwarf2loc.c (fetch_const_value_from_synthetic_pointer): Use + auto_obstack. + * dwarf2read.c (create_addrmap_from_index) + (dwarf2_build_psymtabs_hard) + (update_enumeration_type_from_children): Likewise. + * gdb_obstack.h (auto_obstack): New type. + * go-exp.y (name_obstack): Now an auto_obstack. + (build_packaged_name): Use auto_obstack::clear. + (go_parse): Use auto_obstack::clear instead of reinitializing and + freeing the obstack. + * linux-tdep.c (linux_make_mappings_corefile_notes): Use + auto_obstack. + * printcmd.c (printf_wide_c_string, ui_printf): Use auto_obstack. + * rust-exp.y (work_obstack): Now an auto_obstack. + (rust_parse, rust_lex_tests): Use auto_obstack::clear instead of + reinitializing and freeing the obstack. + * utils.c (do_obstack_free, make_cleanup_obstack_free): Delete. + (host_char_to_target): Use auto_obstack. + * utils.h (make_cleanup_obstack_free): Delete declaration. + * valprint.c (generic_emit_char, generic_printstr): Use + auto_obstack. + +2017-06-27 Simon Marchi <simon.marchi@ericsson.com> + + * darwin-nat.c (darwin_check_new_threads): Don't handle dummy + thread. + (darwin_init_thread_list): Don't update dummy thread. + (darwin_create_inferior, darwin_attach): Don't add a dummy thread. + 2017-06-26 Simon Marchi <simon.marchi@ericsson.com> * record-full.c (netorder16): Remove. diff --git a/gdb/MAINTAINERS b/gdb/MAINTAINERS index c0e3cee..7aa3666 100644 --- a/gdb/MAINTAINERS +++ b/gdb/MAINTAINERS @@ -544,6 +544,7 @@ Matt Hiller hiller@redhat.com Kazu Hirata kazu@cs.umass.edu James Hogan james.hogan@imgtec.com Jeff Holcomb jeffh@redhat.com +Stafford Horne shorne@gmail.com Don Howard dhoward@redhat.com Nick Hudson nick.hudson@dsl.pipex.com Martin Hunt hunt@redhat.com @@ -555,6 +556,7 @@ Daniel Jacobowitz drow@false.org Andreas Jaeger aj@suse.de Janis Johnson janisjo@codesourcery.com Jeff Johnston jjohnstn@redhat.com +Ruslan Kabatsayev b7.10110111@gmail.com Geoff Keating geoffk@redhat.com Mark Kettenis kettenis@gnu.org Marc Khouzam marc.khouzam@ericsson.com @@ -626,6 +628,7 @@ Aleksandar Ristovski aristovski@qnx.com Tom Rix trix@redhat.com Nick Roberts nickrob@snap.net.nz Pierre-Marie de Rodat derodat@adacore.com +Xavier Roirand roirand@adacore.com Bob Rossi bob_rossi@cox.net Theodore A. Roth troth@openavr.org Ian Roxborough irox@redhat.com diff --git a/gdb/Makefile.in b/gdb/Makefile.in index a9a4b4e..1fda8cd 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1722,6 +1722,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \ f-typeprint.o \ f-valprint.o \ fileio.o \ + filename-seen-cache.o \ filestuff.o \ filesystem.o \ findcmd.o \ @@ -21,6 +21,9 @@ set|show compile-gcc QStartupWithShell Indicates whether the inferior must be started with a shell or not. +* The "maintenance print c-tdesc" command now takes an optional + argument which is the file name of XML target description. + * New commands set debug separate-debug-file diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c index d2ca70a..847454f 100644 --- a/gdb/aarch64-linux-tdep.c +++ b/gdb/aarch64-linux-tdep.c @@ -45,6 +45,8 @@ #include "record-full.h" #include "linux-record.h" +#include "auxv.h" +#include "elf/common.h" /* Signal frame handling. @@ -231,6 +233,20 @@ aarch64_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, NULL, cb_data); } +/* Implement the "core_read_description" gdbarch method. */ + +static const struct target_desc * +aarch64_linux_core_read_description (struct gdbarch *gdbarch, + struct target_ops *target, bfd *abfd) +{ + CORE_ADDR aarch64_hwcap = 0; + + if (target_auxv_search (target, AT_HWCAP, &aarch64_hwcap) != 1) + return NULL; + + return tdesc_aarch64; +} + /* Implementation of `gdbarch_stap_is_single_operand', as defined in gdbarch.h. */ @@ -1018,6 +1034,8 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_iterate_over_regset_sections (gdbarch, aarch64_linux_iterate_over_regset_sections); + set_gdbarch_core_read_description + (gdbarch, aarch64_linux_core_read_description); /* SystemTap related. */ set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes); diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 75bb00f..7816281 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -2997,7 +2997,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Hook in the ABI-specific overrides, if they have been registered. */ info.target_desc = tdesc; - info.tdep_info = (void *) tdesc_data; + info.tdesc_data = tdesc_data; gdbarch_init_osabi (info, gdbarch); dwarf2_frame_set_init_reg (gdbarch, aarch64_dwarf2_frame_init_reg); diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 7c60624..9dd3b31 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -194,8 +194,6 @@ static void move_bits (gdb_byte *, int, const gdb_byte *, int, int, int); static struct value *coerce_unspec_val_to_type (struct value *, struct type *); -static struct value *get_var_value (char *, char *); - static int lesseq_defined_than (struct symbol *, struct symbol *); static int equiv_types (struct type *, struct type *); @@ -6440,10 +6438,10 @@ symbol_completion_match (const char *sym_name, return sym_name; } -/* A companion function to ada_make_symbol_completion_list(). +/* A companion function to ada_collect_symbol_completion_matches(). Check if SYM_NAME represents a symbol which name would be suitable - to complete TEXT (TEXT_LEN is the length of TEXT), in which case - it is appended at the end of the given string vector SV. + to complete TEXT (TEXT_LEN is the length of TEXT), in which case it + is added as a completion match to TRACKER. ORIG_TEXT is the string original string from the user command that needs to be completed. WORD is the entire command on which @@ -6456,8 +6454,8 @@ symbol_completion_match (const char *sym_name, encoded). */ static void -symbol_completion_add (VEC(char_ptr) **sv, - const char *sym_name, +symbol_completion_add (completion_tracker &tracker, + const char *sym_name, const char *text, int text_len, const char *orig_text, const char *word, int wild_match_p, int encoded_p) @@ -6492,21 +6490,22 @@ symbol_completion_add (VEC(char_ptr) **sv, strcat (completion, match); } - VEC_safe_push (char_ptr, *sv, completion); + tracker.add_completion (gdb::unique_xmalloc_ptr<char> (completion)); } -/* Return a list of possible symbol names completing TEXT0. WORD is - the entire command on which completion is made. */ +/* Add the list of possible symbol names completing TEXT0 to TRACKER. + WORD is the entire command on which completion is made. */ -static VEC (char_ptr) * -ada_make_symbol_completion_list (const char *text0, const char *word, - enum type_code code) +static void +ada_collect_symbol_completion_matches (completion_tracker &tracker, + complete_symbol_mode mode, + const char *text0, const char *word, + enum type_code code) { char *text; int text_len; int wild_match_p; int encoded_p; - VEC(char_ptr) *completions = VEC_alloc (char_ptr, 128); struct symbol *sym; struct compunit_symtab *s; struct minimal_symbol *msymbol; @@ -6562,7 +6561,7 @@ ada_make_symbol_completion_list (const char *text0, const char *word, ALL_MSYMBOLS (objfile, msymbol) { QUIT; - symbol_completion_add (&completions, MSYMBOL_LINKAGE_NAME (msymbol), + symbol_completion_add (tracker, MSYMBOL_LINKAGE_NAME (msymbol), text, text_len, text0, word, wild_match_p, encoded_p); } @@ -6577,7 +6576,7 @@ ada_make_symbol_completion_list (const char *text0, const char *word, ALL_BLOCK_SYMBOLS (b, iter, sym) { - symbol_completion_add (&completions, SYMBOL_LINKAGE_NAME (sym), + symbol_completion_add (tracker, SYMBOL_LINKAGE_NAME (sym), text, text_len, text0, word, wild_match_p, encoded_p); } @@ -6592,7 +6591,7 @@ ada_make_symbol_completion_list (const char *text0, const char *word, b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (s), GLOBAL_BLOCK); ALL_BLOCK_SYMBOLS (b, iter, sym) { - symbol_completion_add (&completions, SYMBOL_LINKAGE_NAME (sym), + symbol_completion_add (tracker, SYMBOL_LINKAGE_NAME (sym), text, text_len, text0, word, wild_match_p, encoded_p); } @@ -6607,14 +6606,13 @@ ada_make_symbol_completion_list (const char *text0, const char *word, continue; ALL_BLOCK_SYMBOLS (b, iter, sym) { - symbol_completion_add (&completions, SYMBOL_LINKAGE_NAME (sym), + symbol_completion_add (tracker, SYMBOL_LINKAGE_NAME (sym), text, text_len, text0, word, wild_match_p, encoded_p); } } do_cleanups (old_chain); - return completions; } /* Field Access */ @@ -8989,12 +8987,11 @@ ada_to_fixed_type_1 (struct type *type, const gdb_byte *valaddr, const char *name = ada_type_name (fixed_record_type); char *xvz_name = (char *) alloca (strlen (name) + 7 /* "___XVZ\0" */); - int xvz_found = 0; LONGEST size; xsnprintf (xvz_name, strlen (name) + 7, "%s___XVZ", name); - size = get_int_var_value (xvz_name, &xvz_found); - if (xvz_found && TYPE_LENGTH (fixed_record_type) != size) + if (get_int_var_value (xvz_name, size) + && TYPE_LENGTH (fixed_record_type) != size) { fixed_record_type = copy_type (fixed_record_type); TYPE_LENGTH (fixed_record_type) = size; @@ -11614,7 +11611,7 @@ scan_discrim_bound (const char *str, int k, struct value *dval, LONGEST * px, otherwise causes an error with message ERR_MSG. */ static struct value * -get_var_value (char *name, char *err_msg) +get_var_value (const char *name, const char *err_msg) { struct block_symbol *syms; int nsyms; @@ -11633,27 +11630,20 @@ get_var_value (char *name, char *err_msg) return value_of_variable (syms[0].symbol, syms[0].block); } -/* Value of integer variable named NAME in the current environment. If - no such variable found, returns 0, and sets *FLAG to 0. If - successful, sets *FLAG to 1. */ +/* Value of integer variable named NAME in the current environment. + If no such variable is found, returns false. Otherwise, sets VALUE + to the variable's value and returns true. */ -LONGEST -get_int_var_value (char *name, int *flag) +bool +get_int_var_value (const char *name, LONGEST &value) { struct value *var_val = get_var_value (name, 0); if (var_val == 0) - { - if (flag != NULL) - *flag = 0; - return 0; - } - else - { - if (flag != NULL) - *flag = 1; - return value_as_long (var_val); - } + return false; + + value = value_as_long (var_val); + return true; } @@ -11725,11 +11715,8 @@ to_fixed_range_type (struct type *raw_type, struct value *dval) } else { - int ok; - strcpy (name_buf + prefix_len, "___L"); - L = get_int_var_value (name_buf, &ok); - if (!ok) + if (!get_int_var_value (name_buf, L)) { lim_warning (_("Unknown lower bound, using 1.")); L = 1; @@ -11744,11 +11731,8 @@ to_fixed_range_type (struct type *raw_type, struct value *dval) } else { - int ok; - strcpy (name_buf + prefix_len, "___U"); - U = get_int_var_value (name_buf, &ok); - if (!ok) + if (!get_int_var_value (name_buf, U)) { lim_warning (_("Unknown upper bound, using %ld."), (long) L); U = L; @@ -13976,7 +13960,7 @@ static const char *ada_extensions[] = ".adb", ".ads", ".a", ".ada", ".dg", NULL }; -const struct language_defn ada_language_defn = { +extern const struct language_defn ada_language_defn = { "ada", /* Language name */ "Ada", language_ada, @@ -14010,7 +13994,7 @@ const struct language_defn ada_language_defn = { 0, /* c-style arrays */ 1, /* String lower bound */ ada_get_gdb_completer_word_break_characters, - ada_make_symbol_completion_list, + ada_collect_symbol_completion_matches, ada_language_arch_info, ada_print_array_index, default_pass_by_reference, @@ -14107,8 +14091,6 @@ ada_free_objfile_observer (struct objfile *objfile) void _initialize_ada_language (void) { - add_language (&ada_language_defn); - initialize_ada_catchpoint_ops (); add_prefix_cmd ("ada", no_class, set_ada_command, diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h index 5f97a6c..f5b3bca 100644 --- a/gdb/ada-lang.h +++ b/gdb/ada-lang.h @@ -335,7 +335,7 @@ extern const char *ada_type_name (struct type *); extern struct type *ada_find_parallel_type (struct type *, const char *suffix); -extern LONGEST get_int_var_value (char *, int *); +extern bool get_int_var_value (const char *, LONGEST &value); extern struct symbol *ada_find_renaming_symbol (struct symbol *name_sym, const struct block *block); diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c index ae43da5..cf43f0e 100644 --- a/gdb/ada-tasks.c +++ b/gdb/ada-tasks.c @@ -1008,7 +1008,6 @@ print_ada_task_info (struct ui_out *uiout, struct ada_tasks_inferior_data *data; int taskno, nb_tasks; int taskno_arg = 0; - struct cleanup *old_chain; int nb_columns; if (ada_build_task_list () == 0) @@ -1047,8 +1046,7 @@ print_ada_task_info (struct ui_out *uiout, nb_tasks = VEC_length (ada_task_info_s, data->task_list); nb_columns = uiout->is_mi_like_p () ? 8 : 7; - old_chain = make_cleanup_ui_out_table_begin_end (uiout, nb_columns, - nb_tasks, "tasks"); + ui_out_emit_table table_emitter (uiout, nb_columns, nb_tasks, "tasks"); uiout->table_header (1, ui_left, "current", ""); uiout->table_header (3, ui_right, "id", "ID"); uiout->table_header (9, ui_right, "task-id", "TID"); @@ -1143,8 +1141,6 @@ print_ada_task_info (struct ui_out *uiout, uiout->text ("\n"); } - - do_cleanups (old_chain); } /* Print a detailed description of the Ada task whose ID is TASKNO_STR diff --git a/gdb/ada-typeprint.c b/gdb/ada-typeprint.c index 3c33bdc..8392513 100644 --- a/gdb/ada-typeprint.c +++ b/gdb/ada-typeprint.c @@ -256,14 +256,12 @@ print_dynamic_range_bound (struct type *type, const char *name, int name_len, static char *name_buf = NULL; static size_t name_buf_len = 0; LONGEST B; - int OK; GROW_VECT (name_buf, name_buf_len, name_len + strlen (suffix) + 1); strncpy (name_buf, name, name_len); strcpy (name_buf + name_len, suffix); - B = get_int_var_value (name_buf, &OK); - if (OK) + if (get_int_var_value (name_buf, B)) ada_print_scalar (type, B, stream); else fprintf_filtered (stream, "?"); diff --git a/gdb/amd64-bsd-nat.c b/gdb/amd64-bsd-nat.c index ca61a35..41dee84 100644 --- a/gdb/amd64-bsd-nat.c +++ b/gdb/amd64-bsd-nat.c @@ -57,6 +57,33 @@ amd64bsd_fetch_inferior_registers (struct target_ops *ops, return; } +#ifdef PT_GETFSBASE + if (regnum == -1 || regnum == AMD64_FSBASE_REGNUM) + { + register_t base; + + if (ptrace (PT_GETFSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) + perror_with_name (_("Couldn't get segment register fs_base")); + + regcache_raw_supply (regcache, AMD64_FSBASE_REGNUM, &base); + if (regnum != -1) + return; + } +#endif +#ifdef PT_GETGSBASE + if (regnum == -1 || regnum == AMD64_GSBASE_REGNUM) + { + register_t base; + + if (ptrace (PT_GETGSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) + perror_with_name (_("Couldn't get segment register gs_base")); + + regcache_raw_supply (regcache, AMD64_GSBASE_REGNUM, &base); + if (regnum != -1) + return; + } +#endif + if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum)) { struct fpreg fpregs; @@ -108,6 +135,33 @@ amd64bsd_store_inferior_registers (struct target_ops *ops, return; } +#ifdef PT_SETFSBASE + if (regnum == -1 || regnum == AMD64_FSBASE_REGNUM) + { + register_t base; + + regcache_raw_collect (regcache, AMD64_FSBASE_REGNUM, &base); + + if (ptrace (PT_SETFSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) + perror_with_name (_("Couldn't write segment register fs_base")); + if (regnum != -1) + return; + } +#endif +#ifdef PT_SETGSBASE + if (regnum == -1 || regnum == AMD64_GSBASE_REGNUM) + { + register_t base; + + regcache_raw_collect (regcache, AMD64_GSBASE_REGNUM, &base); + + if (ptrace (PT_SETGSBASE, pid, (PTRACE_TYPE_ARG3) &base, 0) == -1) + perror_with_name (_("Couldn't write segment register gs_base")); + if (regnum != -1) + return; + } +#endif + if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum)) { struct fpreg fpregs; diff --git a/gdb/amd64-darwin-tdep.c b/gdb/amd64-darwin-tdep.c index db400cd..be26d9e 100644 --- a/gdb/amd64-darwin-tdep.c +++ b/gdb/amd64-darwin-tdep.c @@ -99,7 +99,7 @@ x86_darwin_init_abi_64 (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - amd64_init_abi (info, gdbarch); + amd64_init_abi (info, gdbarch, tdesc_amd64); tdep->struct_return = reg_struct_return; diff --git a/gdb/amd64-dicos-tdep.c b/gdb/amd64-dicos-tdep.c index ee40891..7bdb167 100644 --- a/gdb/amd64-dicos-tdep.c +++ b/gdb/amd64-dicos-tdep.c @@ -25,7 +25,7 @@ static void amd64_dicos_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { - amd64_init_abi (info, gdbarch); + amd64_init_abi (info, gdbarch, tdesc_amd64); dicos_init_abi (gdbarch); } diff --git a/gdb/amd64-fbsd-tdep.c b/gdb/amd64-fbsd-tdep.c index 48bb209..ad4d787 100644 --- a/gdb/amd64-fbsd-tdep.c +++ b/gdb/amd64-fbsd-tdep.c @@ -217,7 +217,7 @@ amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) tdep->gregset_num_regs = ARRAY_SIZE (amd64fbsd_r_reg_offset); tdep->sizeof_gregset = 22 * 8; - amd64_init_abi (info, gdbarch); + amd64_init_abi (info, gdbarch, tdesc_amd64); tdep->sigtramp_p = amd64fbsd_sigtramp_p; tdep->sigtramp_start = amd64fbsd_sigtramp_start_addr; diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c index 4ef0f78..31d2b16 100644 --- a/gdb/amd64-linux-tdep.c +++ b/gdb/amd64-linux-tdep.c @@ -1863,9 +1863,7 @@ static void amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - const struct target_desc *tdesc = info.target_desc; - struct tdesc_arch_data *tdesc_data - = (struct tdesc_arch_data *) info.tdep_info; + struct tdesc_arch_data *tdesc_data = info.tdesc_data; const struct tdesc_feature *feature; int valid_p; @@ -1875,15 +1873,13 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) tdep->gregset_num_regs = ARRAY_SIZE (amd64_linux_gregset_reg_offset); tdep->sizeof_gregset = 27 * 8; - amd64_init_abi (info, gdbarch); + amd64_init_abi (info, gdbarch, tdesc_amd64_linux); + + const target_desc *tdesc = tdep->tdesc; /* Reserve a number for orig_rax. */ set_gdbarch_num_regs (gdbarch, AMD64_LINUX_NUM_REGS); - if (! tdesc_has_registers (tdesc)) - tdesc = tdesc_amd64_linux; - tdep->tdesc = tdesc; - feature = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.linux"); if (feature == NULL) return; @@ -2080,9 +2076,7 @@ static void amd64_x32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - const struct target_desc *tdesc = info.target_desc; - struct tdesc_arch_data *tdesc_data - = (struct tdesc_arch_data *) info.tdep_info; + struct tdesc_arch_data *tdesc_data = info.tdesc_data; const struct tdesc_feature *feature; int valid_p; @@ -2092,14 +2086,12 @@ amd64_x32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) tdep->gregset_num_regs = ARRAY_SIZE (amd64_linux_gregset_reg_offset); tdep->sizeof_gregset = 27 * 8; - amd64_x32_init_abi (info, gdbarch); + amd64_x32_init_abi (info, gdbarch, tdesc_x32_linux); /* Reserve a number for orig_rax. */ set_gdbarch_num_regs (gdbarch, AMD64_LINUX_NUM_REGS); - if (! tdesc_has_registers (tdesc)) - tdesc = tdesc_x32_linux; - tdep->tdesc = tdesc; + const target_desc *tdesc = tdep->tdesc; feature = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.linux"); if (feature == NULL) diff --git a/gdb/amd64-nbsd-tdep.c b/gdb/amd64-nbsd-tdep.c index db6f19f..02bf427 100644 --- a/gdb/amd64-nbsd-tdep.c +++ b/gdb/amd64-nbsd-tdep.c @@ -103,7 +103,7 @@ amd64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) tdep->gregset_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset); tdep->sizeof_gregset = 26 * 8; - amd64_init_abi (info, gdbarch); + amd64_init_abi (info, gdbarch, tdesc_amd64); tdep->jb_pc_offset = 7 * 8; diff --git a/gdb/amd64-obsd-tdep.c b/gdb/amd64-obsd-tdep.c index 72895b6..ad90c20 100644 --- a/gdb/amd64-obsd-tdep.c +++ b/gdb/amd64-obsd-tdep.c @@ -419,7 +419,7 @@ amd64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - amd64_init_abi (info, gdbarch); + amd64_init_abi (info, gdbarch, tdesc_amd64); obsd_init_abi (info, gdbarch); /* Initialize general-purpose register set details. */ diff --git a/gdb/amd64-sol2-tdep.c b/gdb/amd64-sol2-tdep.c index 51fe9db..ca474db 100644 --- a/gdb/amd64-sol2-tdep.c +++ b/gdb/amd64-sol2-tdep.c @@ -99,7 +99,7 @@ amd64_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) tdep->gregset_num_regs = ARRAY_SIZE (amd64_sol2_gregset_reg_offset); tdep->sizeof_gregset = 28 * 8; - amd64_init_abi (info, gdbarch); + amd64_init_abi (info, gdbarch, tdesc_amd64); tdep->sigtramp_p = amd64_sol2_sigtramp_p; tdep->sigcontext_addr = amd64_sol2_mcontext_addr; diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index 9ff7dfc..89a060d 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -49,10 +49,6 @@ #include "features/i386/amd64-avx-avx512.c" #include "features/i386/amd64-avx-mpx-avx512-pku.c" -#include "features/i386/x32.c" -#include "features/i386/x32-avx.c" -#include "features/i386/x32-avx-avx512.c" - #include "ax.h" #include "ax-gdb.h" @@ -3005,7 +3001,8 @@ static const int amd64_record_regmap[] = }; void -amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch, + const target_desc *default_tdesc) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); const struct target_desc *tdesc = info.target_desc; @@ -3022,7 +3019,7 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) tdep->fpregset = &amd64_fpregset; if (! tdesc_has_registers (tdesc)) - tdesc = tdesc_amd64; + tdesc = default_tdesc; tdep->tdesc = tdesc; tdep->num_core_regs = AMD64_NUM_GREGS + I387_NUM_REGS; @@ -3196,16 +3193,12 @@ amd64_x32_pseudo_register_type (struct gdbarch *gdbarch, int regnum) } void -amd64_x32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +amd64_x32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch, + const target_desc *default_tdesc) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - const struct target_desc *tdesc = info.target_desc; - - amd64_init_abi (info, gdbarch); - if (! tdesc_has_registers (tdesc)) - tdesc = tdesc_x32; - tdep->tdesc = tdesc; + amd64_init_abi (info, gdbarch, default_tdesc); tdep->num_dword_regs = 17; set_tdesc_pseudo_register_type (gdbarch, amd64_x32_pseudo_register_type); @@ -3248,10 +3241,6 @@ _initialize_amd64_tdep (void) initialize_tdesc_amd64_avx_mpx (); initialize_tdesc_amd64_avx_avx512 (); initialize_tdesc_amd64_avx_mpx_avx512_pku (); - - initialize_tdesc_x32 (); - initialize_tdesc_x32_avx (); - initialize_tdesc_x32_avx_avx512 (); } diff --git a/gdb/amd64-tdep.h b/gdb/amd64-tdep.h index 87f0ba3..23fa5b8 100644 --- a/gdb/amd64-tdep.h +++ b/gdb/amd64-tdep.h @@ -97,9 +97,17 @@ extern void amd64_displaced_step_fixup (struct gdbarch *gdbarch, CORE_ADDR from, CORE_ADDR to, struct regcache *regs); -extern void amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch); +/* Initialize the ABI for amd64. Uses DEFAULT_TDESC as fallback + tdesc, if INFO does not specify one. */ +extern void amd64_init_abi (struct gdbarch_info info, + struct gdbarch *gdbarch, + const target_desc *default_tdesc); + +/* Initialize the ABI for x32. Uses DEFAULT_TDESC as fallback tdesc, + if INFO does not specify one. */ extern void amd64_x32_init_abi (struct gdbarch_info info, - struct gdbarch *gdbarch); + struct gdbarch *gdbarch, + const target_desc *default_tdesc); extern const struct target_desc *amd64_target_description (uint64_t xcr0); /* Fill register REGNUM in REGCACHE with the appropriate diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c index f1acdb9..9158282 100644 --- a/gdb/amd64-windows-tdep.c +++ b/gdb/amd64-windows-tdep.c @@ -1224,7 +1224,7 @@ amd64_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) */ frame_unwind_append_unwinder (gdbarch, &amd64_windows_frame_unwind); - amd64_init_abi (info, gdbarch); + amd64_init_abi (info, gdbarch, tdesc_amd64); windows_init_abi (info, gdbarch); diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 2ae3413..4e0fdf4 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -971,13 +971,6 @@ default_print_insn (bfd_vma memaddr, disassemble_info *info) { disassembler_ftype disassemble_fn; - if (exec_bfd != NULL) - { - gdb_assert (info->arch == bfd_get_arch (exec_bfd)); - gdb_assert (info->endian == (bfd_big_endian (exec_bfd) - ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE)); - gdb_assert (info->mach == bfd_get_mach (exec_bfd)); - } disassemble_fn = disassembler (info->arch, info->endian == BFD_ENDIAN_BIG, info->mach, exec_bfd); @@ -985,6 +978,24 @@ default_print_insn (bfd_vma memaddr, disassemble_info *info) return (*disassemble_fn) (memaddr, info); } +/* See arch-utils.h. */ + +CORE_ADDR +gdbarch_skip_prologue_noexcept (gdbarch *gdbarch, CORE_ADDR pc) noexcept +{ + CORE_ADDR new_pc = pc; + + TRY + { + new_pc = gdbarch_skip_prologue (gdbarch, pc); + } + CATCH (ex, RETURN_MASK_ALL) + {} + END_CATCH + + return new_pc; +} + /* -Wmissing-prototypes */ extern initialize_file_ftype _initialize_gdbarch_utils; diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h index 2aa9159..fa2908605 100644 --- a/gdb/arch-utils.h +++ b/gdb/arch-utils.h @@ -268,4 +268,10 @@ extern void default_guess_tracepoint_registers (struct gdbarch *gdbarch, extern int default_print_insn (bfd_vma memaddr, disassemble_info *info); +/* Wrapper to gdbarch_skip_prologue, but doesn't throw exception. Catch + exception thrown from gdbarch_skip_prologue, and return PC. */ + +extern CORE_ADDR gdbarch_skip_prologue_noexcept (gdbarch *gdbarch, + CORE_ADDR pc) noexcept; + #endif diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c index ad3085a..4039d1e 100644 --- a/gdb/arm-linux-nat.c +++ b/gdb/arm-linux-nat.c @@ -402,7 +402,8 @@ arm_linux_fetch_inferior_registers (struct target_ops *ops, fetch_wmmx_regs (regcache); else if (tdep->vfp_register_count > 0 && regno >= ARM_D0_REGNUM - && regno <= ARM_D0_REGNUM + tdep->vfp_register_count) + && (regno < ARM_D0_REGNUM + tdep->vfp_register_count + || regno == ARM_FPSCR_REGNUM)) fetch_vfp_regs (regcache); } } @@ -439,7 +440,8 @@ arm_linux_store_inferior_registers (struct target_ops *ops, store_wmmx_regs (regcache); else if (tdep->vfp_register_count > 0 && regno >= ARM_D0_REGNUM - && regno <= ARM_D0_REGNUM + tdep->vfp_register_count) + && (regno < ARM_D0_REGNUM + tdep->vfp_register_count + || regno == ARM_FPSCR_REGNUM)) store_vfp_regs (regcache); } } diff --git a/gdb/auto-load.c b/gdb/auto-load.c index 37bf942..9f1f13f 100644 --- a/gdb/auto-load.c +++ b/gdb/auto-load.c @@ -786,7 +786,6 @@ auto_load_objfile_script_1 (struct objfile *objfile, const char *realname, { char *filename, *debugfile; int len, retval; - FILE *input; struct cleanup *cleanups; const char *suffix = ext_lang_auto_load_suffix (language); @@ -797,7 +796,7 @@ auto_load_objfile_script_1 (struct objfile *objfile, const char *realname, cleanups = make_cleanup (xfree, filename); - input = gdb_fopen_cloexec (filename, "r"); + gdb_file_up input = gdb_fopen_cloexec (filename, "r"); debugfile = filename; if (debug_auto_load) fprintf_unfiltered (gdb_stdlog, _("auto-load: Attempted file \"%s\" %s.\n"), @@ -845,8 +844,6 @@ auto_load_objfile_script_1 (struct objfile *objfile, const char *realname, int is_safe; struct auto_load_pspace_info *pspace_info; - make_cleanup_fclose (input); - is_safe = file_is_auto_load_safe (debugfile, _("auto-load: Loading %s script \"%s\"" @@ -875,7 +872,7 @@ auto_load_objfile_script_1 (struct objfile *objfile, const char *realname, compiled in. And the extension language is required to implement this function. */ gdb_assert (sourcer != NULL); - sourcer (language, objfile, input, debugfile); + sourcer (language, objfile, input.get (), debugfile); } retval = 1; @@ -931,10 +928,7 @@ source_script_file (struct auto_load_pspace_info *pspace_info, const char *section_name, unsigned int offset, const char *file) { - FILE *stream; - char *full_path; - int opened, in_hash_table; - struct cleanup *cleanups; + int in_hash_table; objfile_script_sourcer_func *sourcer; /* Skip this script if support is not compiled in. */ @@ -956,27 +950,22 @@ source_script_file (struct auto_load_pspace_info *pspace_info, return; } - opened = find_and_open_script (file, 1 /*search_path*/, - &stream, &full_path); + gdb::optional<open_script> opened = find_and_open_script (file, + 1 /*search_path*/); - cleanups = make_cleanup (null_cleanup, NULL); if (opened) { - make_cleanup_fclose (stream); - make_cleanup (xfree, full_path); - - if (!file_is_auto_load_safe (full_path, + if (!file_is_auto_load_safe (opened->full_path.get (), _("auto-load: Loading %s script " "\"%s\" from section \"%s\" of " "objfile \"%s\".\n"), - ext_lang_name (language), full_path, + ext_lang_name (language), + opened->full_path.get (), section_name, objfile_name (objfile))) - opened = 0; + opened.reset (); } else { - full_path = NULL; - /* If one script isn't found it's not uncommon for more to not be found either. We don't want to print a message for each script, too much noise. Instead, we print the warning once and tell the @@ -989,14 +978,16 @@ source_script_file (struct auto_load_pspace_info *pspace_info, section_name, offset); } - in_hash_table = maybe_add_script_file (pspace_info, opened, file, full_path, + in_hash_table = maybe_add_script_file (pspace_info, bool (opened), file, + (opened + ? opened->full_path.get () + : NULL), language); /* If this file is not currently loaded, load it. */ if (opened && !in_hash_table) - sourcer (language, objfile, stream, full_path); - - do_cleanups (cleanups); + sourcer (language, objfile, opened->stream.get (), + opened->full_path.get ()); } /* Subroutine of source_section_scripts to simplify it. @@ -1382,18 +1373,18 @@ auto_load_info_scripts (char *pattern, int from_tty, if (nr_scripts > 0 && pattern == auto_load_info_scripts_pattern_nl) uiout->text ("\n"); - /* Note: This creates a cleanup to output the table end marker. */ - make_cleanup_ui_out_table_begin_end (uiout, 2, nr_scripts, - "AutoLoadedScriptsTable"); + { + ui_out_emit_table table_emitter (uiout, 2, nr_scripts, + "AutoLoadedScriptsTable"); - uiout->table_header (7, ui_left, "loaded", "Loaded"); - uiout->table_header (70, ui_left, "script", "Script"); - uiout->table_body (); + uiout->table_header (7, ui_left, "loaded", "Loaded"); + uiout->table_header (70, ui_left, "script", "Script"); + uiout->table_body (); - print_scripts (script_files); - print_scripts (script_texts); + print_scripts (script_files); + print_scripts (script_texts); + } - /* Finish up the table before checking for no matching scripts. */ do_cleanups (script_chain); if (nr_scripts == 0) diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c index fae2e2d..91bc4b8 100644 --- a/gdb/ax-gdb.c +++ b/gdb/ax-gdb.c @@ -77,8 +77,7 @@ static struct value *const_var_ref (struct symbol *var); static struct value *const_expr (union exp_element **pc); static struct value *maybe_const_expr (union exp_element **pc); -static void gen_traced_pop (struct gdbarch *, struct agent_expr *, - struct axs_value *); +static void gen_traced_pop (struct agent_expr *, struct axs_value *); static void gen_sign_extend (struct agent_expr *, struct type *); static void gen_extend (struct agent_expr *, struct type *); @@ -86,31 +85,28 @@ static void gen_fetch (struct agent_expr *, struct type *); static void gen_left_shift (struct agent_expr *, int); -static void gen_frame_args_address (struct gdbarch *, struct agent_expr *); -static void gen_frame_locals_address (struct gdbarch *, struct agent_expr *); +static void gen_frame_args_address (struct agent_expr *); +static void gen_frame_locals_address (struct agent_expr *); static void gen_offset (struct agent_expr *ax, int offset); static void gen_sym_offset (struct agent_expr *, struct symbol *); -static void gen_var_ref (struct gdbarch *, struct agent_expr *ax, - struct axs_value *value, struct symbol *var); +static void gen_var_ref (struct agent_expr *ax, struct axs_value *value, + struct symbol *var); static void gen_int_literal (struct agent_expr *ax, struct axs_value *value, LONGEST k, struct type *type); -static void gen_usual_unary (struct expression *exp, struct agent_expr *ax, - struct axs_value *value); +static void gen_usual_unary (struct agent_expr *ax, struct axs_value *value); static int type_wider_than (struct type *type1, struct type *type2); static struct type *max_type (struct type *type1, struct type *type2); static void gen_conversion (struct agent_expr *ax, struct type *from, struct type *to); static int is_nontrivial_conversion (struct type *from, struct type *to); -static void gen_usual_arithmetic (struct expression *exp, - struct agent_expr *ax, +static void gen_usual_arithmetic (struct agent_expr *ax, struct axs_value *value1, struct axs_value *value2); -static void gen_integral_promotions (struct expression *exp, - struct agent_expr *ax, +static void gen_integral_promotions (struct agent_expr *ax, struct axs_value *value); static void gen_cast (struct agent_expr *ax, struct axs_value *value, struct type *type); @@ -133,27 +129,23 @@ static void gen_binop (struct agent_expr *ax, static void gen_logical_not (struct agent_expr *ax, struct axs_value *value, struct type *result_type); static void gen_complement (struct agent_expr *ax, struct axs_value *value); -static void gen_deref (struct agent_expr *, struct axs_value *); -static void gen_address_of (struct agent_expr *, struct axs_value *); -static void gen_bitfield_ref (struct expression *exp, struct agent_expr *ax, - struct axs_value *value, +static void gen_deref (struct axs_value *); +static void gen_address_of (struct axs_value *); +static void gen_bitfield_ref (struct agent_expr *ax, struct axs_value *value, struct type *type, int start, int end); -static void gen_primitive_field (struct expression *exp, - struct agent_expr *ax, +static void gen_primitive_field (struct agent_expr *ax, struct axs_value *value, int offset, int fieldno, struct type *type); -static int gen_struct_ref_recursive (struct expression *exp, - struct agent_expr *ax, +static int gen_struct_ref_recursive (struct agent_expr *ax, struct axs_value *value, const char *field, int offset, struct type *type); -static void gen_struct_ref (struct expression *exp, struct agent_expr *ax, +static void gen_struct_ref (struct agent_expr *ax, struct axs_value *value, const char *field, const char *operator_name, const char *operand_name); -static void gen_static_field (struct gdbarch *gdbarch, - struct agent_expr *ax, struct axs_value *value, +static void gen_static_field (struct agent_expr *ax, struct axs_value *value, struct type *type, int fieldno); static void gen_repeat (struct expression *exp, union exp_element **pc, struct agent_expr *ax, struct axs_value *value); @@ -318,8 +310,7 @@ maybe_const_expr (union exp_element **pc) classes, and generate tracing bytecodes for each. */ static void -gen_trace_static_fields (struct gdbarch *gdbarch, - struct agent_expr *ax, +gen_trace_static_fields (struct agent_expr *ax, struct type *type) { int i, nbases = TYPE_N_BASECLASSES (type); @@ -331,7 +322,7 @@ gen_trace_static_fields (struct gdbarch *gdbarch, { if (field_is_static (&TYPE_FIELD (type, i))) { - gen_static_field (gdbarch, ax, &value, type, i); + gen_static_field (ax, &value, type, i); if (value.optimized_out) continue; switch (value.kind) @@ -361,7 +352,7 @@ gen_trace_static_fields (struct gdbarch *gdbarch, { struct type *basetype = check_typedef (TYPE_BASECLASS (type, i)); - gen_trace_static_fields (gdbarch, ax, basetype); + gen_trace_static_fields (ax, basetype); } } @@ -369,8 +360,7 @@ gen_trace_static_fields (struct gdbarch *gdbarch, the value. Useful on the left side of a comma, and at the end of an expression being used for tracing. */ static void -gen_traced_pop (struct gdbarch *gdbarch, - struct agent_expr *ax, struct axs_value *value) +gen_traced_pop (struct agent_expr *ax, struct axs_value *value) { int string_trace = 0; if (ax->trace_string @@ -443,7 +433,7 @@ gen_traced_pop (struct gdbarch *gdbarch, if (ax->tracing && (TYPE_CODE (value->type) == TYPE_CODE_STRUCT || TYPE_CODE (value->type) == TYPE_CODE_UNION)) - gen_trace_static_fields (gdbarch, ax, value->type); + gen_trace_static_fields (ax, value->type); } @@ -562,12 +552,12 @@ gen_left_shift (struct agent_expr *ax, int distance) /* Generate code to push the base address of the argument portion of the top stack frame. */ static void -gen_frame_args_address (struct gdbarch *gdbarch, struct agent_expr *ax) +gen_frame_args_address (struct agent_expr *ax) { int frame_reg; LONGEST frame_offset; - gdbarch_virtual_frame_pointer (gdbarch, + gdbarch_virtual_frame_pointer (ax->gdbarch, ax->scope, &frame_reg, &frame_offset); ax_reg (ax, frame_reg); gen_offset (ax, frame_offset); @@ -577,12 +567,12 @@ gen_frame_args_address (struct gdbarch *gdbarch, struct agent_expr *ax) /* Generate code to push the base address of the locals portion of the top stack frame. */ static void -gen_frame_locals_address (struct gdbarch *gdbarch, struct agent_expr *ax) +gen_frame_locals_address (struct agent_expr *ax) { int frame_reg; LONGEST frame_offset; - gdbarch_virtual_frame_pointer (gdbarch, + gdbarch_virtual_frame_pointer (ax->gdbarch, ax->scope, &frame_reg, &frame_offset); ax_reg (ax, frame_reg); gen_offset (ax, frame_offset); @@ -627,8 +617,7 @@ gen_sym_offset (struct agent_expr *ax, struct symbol *var) symbol VAR. Set VALUE to describe the result. */ static void -gen_var_ref (struct gdbarch *gdbarch, struct agent_expr *ax, - struct axs_value *value, struct symbol *var) +gen_var_ref (struct agent_expr *ax, struct axs_value *value, struct symbol *var) { /* Dereference any typedefs. */ value->type = check_typedef (SYMBOL_TYPE (var)); @@ -636,7 +625,7 @@ gen_var_ref (struct gdbarch *gdbarch, struct agent_expr *ax, if (SYMBOL_COMPUTED_OPS (var) != NULL) { - SYMBOL_COMPUTED_OPS (var)->tracepoint_var_ref (var, gdbarch, ax, value); + SYMBOL_COMPUTED_OPS (var)->tracepoint_var_ref (var, ax, value); return; } @@ -666,22 +655,22 @@ gen_var_ref (struct gdbarch *gdbarch, struct agent_expr *ax, break; case LOC_ARG: /* var lives in argument area of frame */ - gen_frame_args_address (gdbarch, ax); + gen_frame_args_address (ax); gen_sym_offset (ax, var); value->kind = axs_lvalue_memory; break; case LOC_REF_ARG: /* As above, but the frame slot really holds the address of the variable. */ - gen_frame_args_address (gdbarch, ax); + gen_frame_args_address (ax); gen_sym_offset (ax, var); /* Don't assume any particular pointer size. */ - gen_fetch (ax, builtin_type (gdbarch)->builtin_data_ptr); + gen_fetch (ax, builtin_type (ax->gdbarch)->builtin_data_ptr); value->kind = axs_lvalue_memory; break; case LOC_LOCAL: /* var lives in locals area of frame */ - gen_frame_locals_address (gdbarch, ax); + gen_frame_locals_address (ax); gen_sym_offset (ax, var); value->kind = axs_lvalue_memory; break; @@ -701,7 +690,8 @@ gen_var_ref (struct gdbarch *gdbarch, struct agent_expr *ax, this as an lvalue or rvalue, the caller will generate the right code. */ value->kind = axs_lvalue_register; - value->u.reg = SYMBOL_REGISTER_OPS (var)->register_number (var, gdbarch); + value->u.reg + = SYMBOL_REGISTER_OPS (var)->register_number (var, ax->gdbarch); break; /* A lot like LOC_REF_ARG, but the pointer lives directly in a @@ -709,7 +699,8 @@ gen_var_ref (struct gdbarch *gdbarch, struct agent_expr *ax, because it's just like any other case where the thing has a real address. */ case LOC_REGPARM_ADDR: - ax_reg (ax, SYMBOL_REGISTER_OPS (var)->register_number (var, gdbarch)); + ax_reg (ax, + SYMBOL_REGISTER_OPS (var)->register_number (var, ax->gdbarch)); value->kind = axs_lvalue_memory; break; @@ -818,8 +809,7 @@ require_rvalue (struct agent_expr *ax, struct axs_value *value) lvalue through unchanged, and let `+' raise an error. */ static void -gen_usual_unary (struct expression *exp, struct agent_expr *ax, - struct axs_value *value) +gen_usual_unary (struct agent_expr *ax, struct axs_value *value) { /* We don't have to generate any code for the usual integral conversions, since values are always represented as full-width on @@ -934,8 +924,8 @@ is_nontrivial_conversion (struct type *from, struct type *to) and promotes each argument to that type. *VALUE1 and *VALUE2 describe the values as they are passed in, and as they are left. */ static void -gen_usual_arithmetic (struct expression *exp, struct agent_expr *ax, - struct axs_value *value1, struct axs_value *value2) +gen_usual_arithmetic (struct agent_expr *ax, struct axs_value *value1, + struct axs_value *value2) { /* Do the usual binary conversions. */ if (TYPE_CODE (value1->type) == TYPE_CODE_INT @@ -946,7 +936,7 @@ gen_usual_arithmetic (struct expression *exp, struct agent_expr *ax, unsigned type is considered "wider" than an n-bit signed type. Promote to the "wider" of the two types, and always promote at least to int. */ - struct type *target = max_type (builtin_type (exp->gdbarch)->builtin_int, + struct type *target = max_type (builtin_type (ax->gdbarch)->builtin_int, max_type (value1->type, value2->type)); /* Deal with value2, on the top of the stack. */ @@ -971,10 +961,9 @@ gen_usual_arithmetic (struct expression *exp, struct agent_expr *ax, the value on the top of the stack, as described by VALUE. Assume the value has integral type. */ static void -gen_integral_promotions (struct expression *exp, struct agent_expr *ax, - struct axs_value *value) +gen_integral_promotions (struct agent_expr *ax, struct axs_value *value) { - const struct builtin_type *builtin = builtin_type (exp->gdbarch); + const struct builtin_type *builtin = builtin_type (ax->gdbarch); if (!type_wider_than (value->type, builtin->builtin_int)) { @@ -1196,7 +1185,7 @@ gen_complement (struct agent_expr *ax, struct axs_value *value) /* Dereference the value on the top of the stack. */ static void -gen_deref (struct agent_expr *ax, struct axs_value *value) +gen_deref (struct axs_value *value) { /* The caller should check the type, because several operators use this, and we don't know what error message to generate. */ @@ -1219,7 +1208,7 @@ gen_deref (struct agent_expr *ax, struct axs_value *value) /* Produce the address of the lvalue on the top of the stack. */ static void -gen_address_of (struct agent_expr *ax, struct axs_value *value) +gen_address_of (struct axs_value *value) { /* Special case for taking the address of a function. The ANSI standard describes this as a special case, too, so this @@ -1249,9 +1238,8 @@ gen_address_of (struct agent_expr *ax, struct axs_value *value) starting and one-past-ending *bit* numbers of the field within the structure. */ static void -gen_bitfield_ref (struct expression *exp, struct agent_expr *ax, - struct axs_value *value, struct type *type, - int start, int end) +gen_bitfield_ref (struct agent_expr *ax, struct axs_value *value, + struct type *type, int start, int end) { /* Note that ops[i] fetches 8 << i bits. */ static enum agent_op ops[] @@ -1376,7 +1364,7 @@ gen_bitfield_ref (struct expression *exp, struct agent_expr *ax, the sign/zero extension will wipe them out. - If we're in the interior of the word, then there is no garbage on either end, because the ref operators zero-extend. */ - if (gdbarch_byte_order (exp->gdbarch) == BFD_ENDIAN_BIG) + if (gdbarch_byte_order (ax->gdbarch) == BFD_ENDIAN_BIG) gen_left_shift (ax, end - (offset + op_size)); else gen_left_shift (ax, offset - start); @@ -1409,13 +1397,12 @@ gen_bitfield_ref (struct expression *exp, struct agent_expr *ax, generally follow value_primitive_field. */ static void -gen_primitive_field (struct expression *exp, - struct agent_expr *ax, struct axs_value *value, +gen_primitive_field (struct agent_expr *ax, struct axs_value *value, int offset, int fieldno, struct type *type) { /* Is this a bitfield? */ if (TYPE_FIELD_PACKED (type, fieldno)) - gen_bitfield_ref (exp, ax, value, TYPE_FIELD_TYPE (type, fieldno), + gen_bitfield_ref (ax, value, TYPE_FIELD_TYPE (type, fieldno), (offset * TARGET_CHAR_BIT + TYPE_FIELD_BITPOS (type, fieldno)), (offset * TARGET_CHAR_BIT @@ -1434,8 +1421,7 @@ gen_primitive_field (struct expression *exp, base classes. Return 1 if found, 0 if not. */ static int -gen_struct_ref_recursive (struct expression *exp, struct agent_expr *ax, - struct axs_value *value, +gen_struct_ref_recursive (struct agent_expr *ax, struct axs_value *value, const char *field, int offset, struct type *type) { int i, rslt; @@ -1457,7 +1443,7 @@ gen_struct_ref_recursive (struct expression *exp, struct agent_expr *ax, being handled as a global. */ if (field_is_static (&TYPE_FIELD (type, i))) { - gen_static_field (exp->gdbarch, ax, value, type, i); + gen_static_field (ax, value, type, i); if (value->optimized_out) error (_("static field `%s' has been " "optimized out, cannot use"), @@ -1465,7 +1451,7 @@ gen_struct_ref_recursive (struct expression *exp, struct agent_expr *ax, return 1; } - gen_primitive_field (exp, ax, value, offset, i, type); + gen_primitive_field (ax, value, offset, i, type); return 1; } #if 0 /* is this right? */ @@ -1481,7 +1467,7 @@ gen_struct_ref_recursive (struct expression *exp, struct agent_expr *ax, { struct type *basetype = check_typedef (TYPE_BASECLASS (type, i)); - rslt = gen_struct_ref_recursive (exp, ax, value, field, + rslt = gen_struct_ref_recursive (ax, value, field, offset + TYPE_BASECLASS_BITPOS (type, i) / TARGET_CHAR_BIT, basetype); @@ -1499,9 +1485,9 @@ gen_struct_ref_recursive (struct expression *exp, struct agent_expr *ax, the operator being compiled, and OPERAND_NAME is the kind of thing it operates on; we use them in error messages. */ static void -gen_struct_ref (struct expression *exp, struct agent_expr *ax, - struct axs_value *value, const char *field, - const char *operator_name, const char *operand_name) +gen_struct_ref (struct agent_expr *ax, struct axs_value *value, + const char *field, const char *operator_name, + const char *operand_name) { struct type *type; int found; @@ -1512,7 +1498,7 @@ gen_struct_ref (struct expression *exp, struct agent_expr *ax, while (pointer_type (value->type)) { require_rvalue (ax, value); - gen_deref (ax, value); + gen_deref (value); } type = check_typedef (value->type); @@ -1528,7 +1514,7 @@ gen_struct_ref (struct expression *exp, struct agent_expr *ax, error (_("Structure does not live in memory.")); /* Search through fields and base classes recursively. */ - found = gen_struct_ref_recursive (exp, ax, value, field, 0, type); + found = gen_struct_ref_recursive (ax, value, field, 0, type); if (!found) error (_("Couldn't find member named `%s' in struct/union/class `%s'"), @@ -1536,17 +1522,14 @@ gen_struct_ref (struct expression *exp, struct agent_expr *ax, } static int -gen_namespace_elt (struct expression *exp, - struct agent_expr *ax, struct axs_value *value, +gen_namespace_elt (struct agent_expr *ax, struct axs_value *value, const struct type *curtype, char *name); static int -gen_maybe_namespace_elt (struct expression *exp, - struct agent_expr *ax, struct axs_value *value, +gen_maybe_namespace_elt (struct agent_expr *ax, struct axs_value *value, const struct type *curtype, char *name); static void -gen_static_field (struct gdbarch *gdbarch, - struct agent_expr *ax, struct axs_value *value, +gen_static_field (struct agent_expr *ax, struct axs_value *value, struct type *type, int fieldno) { if (TYPE_FIELD_LOC_KIND (type, fieldno) == FIELD_LOC_KIND_PHYSADDR) @@ -1563,7 +1546,7 @@ gen_static_field (struct gdbarch *gdbarch, if (sym) { - gen_var_ref (gdbarch, ax, value, sym); + gen_var_ref (ax, value, sym); /* Don't error if the value was optimized out, we may be scanning all static fields and just want to pass over this @@ -1579,8 +1562,7 @@ gen_static_field (struct gdbarch *gdbarch, } static int -gen_struct_elt_for_reference (struct expression *exp, - struct agent_expr *ax, struct axs_value *value, +gen_struct_elt_for_reference (struct agent_expr *ax, struct axs_value *value, struct type *type, char *fieldname) { struct type *t = type; @@ -1599,7 +1581,7 @@ gen_struct_elt_for_reference (struct expression *exp, { if (field_is_static (&TYPE_FIELD (t, i))) { - gen_static_field (exp->gdbarch, ax, value, t, i); + gen_static_field (ax, value, t, i); if (value->optimized_out) error (_("static field `%s' has been " "optimized out, cannot use"), @@ -1618,18 +1600,17 @@ gen_struct_elt_for_reference (struct expression *exp, /* FIXME add other scoped-reference cases here */ /* Do a last-ditch lookup. */ - return gen_maybe_namespace_elt (exp, ax, value, type, fieldname); + return gen_maybe_namespace_elt (ax, value, type, fieldname); } /* C++: Return the member NAME of the namespace given by the type CURTYPE. */ static int -gen_namespace_elt (struct expression *exp, - struct agent_expr *ax, struct axs_value *value, +gen_namespace_elt (struct agent_expr *ax, struct axs_value *value, const struct type *curtype, char *name) { - int found = gen_maybe_namespace_elt (exp, ax, value, curtype, name); + int found = gen_maybe_namespace_elt (ax, value, curtype, name); if (!found) error (_("No symbol \"%s\" in namespace \"%s\"."), @@ -1645,8 +1626,7 @@ gen_namespace_elt (struct expression *exp, to, say, some base class of CURTYPE). */ static int -gen_maybe_namespace_elt (struct expression *exp, - struct agent_expr *ax, struct axs_value *value, +gen_maybe_namespace_elt (struct agent_expr *ax, struct axs_value *value, const struct type *curtype, char *name) { const char *namespace_name = TYPE_TAG_NAME (curtype); @@ -1659,7 +1639,7 @@ gen_maybe_namespace_elt (struct expression *exp, if (sym.symbol == NULL) return 0; - gen_var_ref (exp->gdbarch, ax, value, sym.symbol); + gen_var_ref (ax, value, sym.symbol); if (value->optimized_out) error (_("`%s' has been optimized out, cannot use"), @@ -1670,20 +1650,17 @@ gen_maybe_namespace_elt (struct expression *exp, static int -gen_aggregate_elt_ref (struct expression *exp, - struct agent_expr *ax, struct axs_value *value, - struct type *type, char *field, - const char *operator_name, - const char *operand_name) +gen_aggregate_elt_ref (struct agent_expr *ax, struct axs_value *value, + struct type *type, char *field) { switch (TYPE_CODE (type)) { case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: - return gen_struct_elt_for_reference (exp, ax, value, type, field); + return gen_struct_elt_for_reference (ax, value, type, field); break; case TYPE_CODE_NAMESPACE: - return gen_namespace_elt (exp, ax, value, type, field); + return gen_namespace_elt (ax, value, type, field); break; default: internal_error (__FILE__, __LINE__, @@ -1784,7 +1761,7 @@ gen_expr (struct expression *exp, union exp_element **pc, struct axs_value value1, value2, value3; enum exp_opcode op = (*pc)[0].opcode, op2; int if1, go1, if2, go2, end; - struct type *int_type = builtin_type (exp->gdbarch)->builtin_int; + struct type *int_type = builtin_type (ax->gdbarch)->builtin_int; /* If we're looking at a constant expression, just push its value. */ { @@ -1822,7 +1799,7 @@ gen_expr (struct expression *exp, union exp_element **pc, case BINOP_GEQ: (*pc)++; gen_expr (exp, pc, ax, &value1); - gen_usual_unary (exp, ax, &value1); + gen_usual_unary (ax, &value1); gen_expr_binop_rest (exp, op, pc, ax, value, &value1, &value2); break; @@ -1830,12 +1807,12 @@ gen_expr (struct expression *exp, union exp_element **pc, (*pc)++; /* Generate the obvious sequence of tests and jumps. */ gen_expr (exp, pc, ax, &value1); - gen_usual_unary (exp, ax, &value1); + gen_usual_unary (ax, &value1); if1 = ax_goto (ax, aop_if_goto); go1 = ax_goto (ax, aop_goto); ax_label (ax, if1, ax->len); gen_expr (exp, pc, ax, &value2); - gen_usual_unary (exp, ax, &value2); + gen_usual_unary (ax, &value2); if2 = ax_goto (ax, aop_if_goto); go2 = ax_goto (ax, aop_goto); ax_label (ax, if2, ax->len); @@ -1853,10 +1830,10 @@ gen_expr (struct expression *exp, union exp_element **pc, (*pc)++; /* Generate the obvious sequence of tests and jumps. */ gen_expr (exp, pc, ax, &value1); - gen_usual_unary (exp, ax, &value1); + gen_usual_unary (ax, &value1); if1 = ax_goto (ax, aop_if_goto); gen_expr (exp, pc, ax, &value2); - gen_usual_unary (exp, ax, &value2); + gen_usual_unary (ax, &value2); if2 = ax_goto (ax, aop_if_goto); ax_const_l (ax, 0); end = ax_goto (ax, aop_goto); @@ -1871,7 +1848,7 @@ gen_expr (struct expression *exp, union exp_element **pc, case TERNOP_COND: (*pc)++; gen_expr (exp, pc, ax, &value1); - gen_usual_unary (exp, ax, &value1); + gen_usual_unary (ax, &value1); /* For (A ? B : C), it's easiest to generate subexpression bytecodes in order, but if_goto jumps on true, so we invert the sense of A. Then we can do B by dropping through, and @@ -1879,11 +1856,11 @@ gen_expr (struct expression *exp, union exp_element **pc, gen_logical_not (ax, &value1, int_type); if1 = ax_goto (ax, aop_if_goto); gen_expr (exp, pc, ax, &value2); - gen_usual_unary (exp, ax, &value2); + gen_usual_unary (ax, &value2); end = ax_goto (ax, aop_goto); ax_label (ax, if1, ax->len); gen_expr (exp, pc, ax, &value3); - gen_usual_unary (exp, ax, &value3); + gen_usual_unary (ax, &value3); ax_label (ax, end, ax->len); /* This is arbitary - what if B and C are incompatible types? */ value->type = value2.type; @@ -1934,7 +1911,7 @@ gen_expr (struct expression *exp, union exp_element **pc, ax_tsv (ax, aop_tracev, tsv->number); /* Trace state variables are always 64-bit integers. */ value1.kind = axs_rvalue; - value1.type = builtin_type (exp->gdbarch)->builtin_long_long; + value1.type = builtin_type (ax->gdbarch)->builtin_long_long; /* Now do right half of expression. */ gen_expr_binop_rest (exp, op2, pc, ax, value, &value1, &value2); /* We have a result of the binary op, set the tsv. */ @@ -1962,7 +1939,7 @@ gen_expr (struct expression *exp, union exp_element **pc, /* Don't just dispose of the left operand. We might be tracing, in which case we want to emit code to trace it if it's an lvalue. */ - gen_traced_pop (exp->gdbarch, ax, &value1); + gen_traced_pop (ax, &value1); gen_expr (exp, pc, ax, value); /* It's the consumer's responsibility to trace the right operand. */ break; @@ -1978,7 +1955,7 @@ gen_expr (struct expression *exp, union exp_element **pc, break; case OP_VAR_VALUE: - gen_var_ref (exp->gdbarch, ax, value, (*pc)[2].symbol); + gen_var_ref (ax, value, (*pc)[2].symbol); if (value->optimized_out) error (_("`%s' has been optimized out, cannot use"), @@ -1993,19 +1970,19 @@ gen_expr (struct expression *exp, union exp_element **pc, int reg; (*pc) += 4 + BYTES_TO_EXP_ELEM ((*pc)[1].longconst + 1); - reg = user_reg_map_name_to_regnum (exp->gdbarch, name, strlen (name)); + reg = user_reg_map_name_to_regnum (ax->gdbarch, name, strlen (name)); if (reg == -1) internal_error (__FILE__, __LINE__, _("Register $%s not available"), name); /* No support for tracing user registers yet. */ - if (reg >= gdbarch_num_regs (exp->gdbarch) - + gdbarch_num_pseudo_regs (exp->gdbarch)) + if (reg >= gdbarch_num_regs (ax->gdbarch) + + gdbarch_num_pseudo_regs (ax->gdbarch)) error (_("'%s' is a user-register; " "GDB cannot yet trace user-register contents."), name); value->kind = axs_lvalue_register; value->u.reg = reg; - value->type = register_type (exp->gdbarch, reg); + value->type = register_type (ax->gdbarch, reg); } break; @@ -2024,7 +2001,7 @@ gen_expr (struct expression *exp, union exp_element **pc, ax_tsv (ax, aop_tracev, tsv->number); /* Trace state variables are always 64-bit integers. */ value->kind = axs_rvalue; - value->type = builtin_type (exp->gdbarch)->builtin_long_long; + value->type = builtin_type (ax->gdbarch)->builtin_long_long; } else if (! compile_internalvar_to_ax (var, ax, value)) error (_("$%s is not a trace state variable; GDB agent " @@ -2113,49 +2090,49 @@ gen_expr (struct expression *exp, union exp_element **pc, (*pc)++; /* + FOO is equivalent to 0 + FOO, which can be optimized. */ gen_expr (exp, pc, ax, value); - gen_usual_unary (exp, ax, value); + gen_usual_unary (ax, value); break; case UNOP_NEG: (*pc)++; /* -FOO is equivalent to 0 - FOO. */ gen_int_literal (ax, &value1, 0, - builtin_type (exp->gdbarch)->builtin_int); - gen_usual_unary (exp, ax, &value1); /* shouldn't do much */ + builtin_type (ax->gdbarch)->builtin_int); + gen_usual_unary (ax, &value1); /* shouldn't do much */ gen_expr (exp, pc, ax, &value2); - gen_usual_unary (exp, ax, &value2); - gen_usual_arithmetic (exp, ax, &value1, &value2); + gen_usual_unary (ax, &value2); + gen_usual_arithmetic (ax, &value1, &value2); gen_binop (ax, value, &value1, &value2, aop_sub, aop_sub, 1, "negation"); break; case UNOP_LOGICAL_NOT: (*pc)++; gen_expr (exp, pc, ax, value); - gen_usual_unary (exp, ax, value); + gen_usual_unary (ax, value); gen_logical_not (ax, value, int_type); break; case UNOP_COMPLEMENT: (*pc)++; gen_expr (exp, pc, ax, value); - gen_usual_unary (exp, ax, value); - gen_integral_promotions (exp, ax, value); + gen_usual_unary (ax, value); + gen_integral_promotions (ax, value); gen_complement (ax, value); break; case UNOP_IND: (*pc)++; gen_expr (exp, pc, ax, value); - gen_usual_unary (exp, ax, value); + gen_usual_unary (ax, value); if (!pointer_type (value->type)) error (_("Argument of unary `*' is not a pointer.")); - gen_deref (ax, value); + gen_deref (value); break; case UNOP_ADDR: (*pc)++; gen_expr (exp, pc, ax, value); - gen_address_of (ax, value); + gen_address_of (value); break; case UNOP_SIZEOF: @@ -2164,7 +2141,7 @@ gen_expr (struct expression *exp, union exp_element **pc, of the other unary operator functions. This is because we have to throw away the code we generate. */ gen_sizeof (exp, pc, ax, value, - builtin_type (exp->gdbarch)->builtin_int); + builtin_type (ax->gdbarch)->builtin_int); break; case STRUCTOP_STRUCT: @@ -2176,9 +2153,9 @@ gen_expr (struct expression *exp, union exp_element **pc, (*pc) += 4 + BYTES_TO_EXP_ELEM (length + 1); gen_expr (exp, pc, ax, value); if (op == STRUCTOP_STRUCT) - gen_struct_ref (exp, ax, value, name, ".", "structure or union"); + gen_struct_ref (ax, value, name, ".", "structure or union"); else if (op == STRUCTOP_PTR) - gen_struct_ref (exp, ax, value, name, "->", + gen_struct_ref (ax, value, name, "->", "pointer to a structure or union"); else /* If this `if' chain doesn't handle it, then the case list @@ -2202,7 +2179,7 @@ gen_expr (struct expression *exp, union exp_element **pc, if (!sym) error (_("no `%s' found"), lang->la_name_of_this); - gen_var_ref (exp->gdbarch, ax, value, sym); + gen_var_ref (ax, value, sym); if (value->optimized_out) error (_("`%s' has been optimized out, cannot use"), @@ -2219,8 +2196,7 @@ gen_expr (struct expression *exp, union exp_element **pc, char *name = &(*pc)[3].string; int found; - found = gen_aggregate_elt_ref (exp, ax, value, type, name, - "?", "??"); + found = gen_aggregate_elt_ref (ax, value, type, name); if (!found) error (_("There is no field named %s"), name); (*pc) += 5 + BYTES_TO_EXP_ELEM (length + 1); @@ -2248,11 +2224,11 @@ gen_expr_binop_rest (struct expression *exp, struct agent_expr *ax, struct axs_value *value, struct axs_value *value1, struct axs_value *value2) { - struct type *int_type = builtin_type (exp->gdbarch)->builtin_int; + struct type *int_type = builtin_type (ax->gdbarch)->builtin_int; gen_expr (exp, pc, ax, value2); - gen_usual_unary (exp, ax, value2); - gen_usual_arithmetic (exp, ax, value1, value2); + gen_usual_unary (ax, value2); + gen_usual_arithmetic (ax, value1, value2); switch (op) { case BINOP_ADD: @@ -2278,7 +2254,7 @@ gen_expr_binop_rest (struct expression *exp, && pointer_type (value2->type)) /* FIXME --- result type should be ptrdiff_t */ gen_ptrdiff (ax, value, value1, value2, - builtin_type (exp->gdbarch)->builtin_long); + builtin_type (ax->gdbarch)->builtin_long); else gen_binop (ax, value, value1, value2, aop_sub, aop_sub, 1, "subtraction"); @@ -2334,7 +2310,7 @@ gen_expr_binop_rest (struct expression *exp, "not a number or boolean.")); gen_ptradd (ax, value, value1, value2); - gen_deref (ax, value); + gen_deref (value); break; } case BINOP_BITWISE_AND: @@ -2404,7 +2380,7 @@ gen_trace_for_var (CORE_ADDR scope, struct gdbarch *gdbarch, ax->tracing = 1; ax->trace_string = trace_string; - gen_var_ref (gdbarch, ax.get (), &value, var); + gen_var_ref (ax.get (), &value, var); /* If there is no actual variable to trace, flag it by returning an empty agent expression. */ @@ -2412,7 +2388,7 @@ gen_trace_for_var (CORE_ADDR scope, struct gdbarch *gdbarch, return agent_expr_up (); /* Make sure we record the final object, and get rid of it. */ - gen_traced_pop (gdbarch, ax.get (), &value); + gen_traced_pop (ax.get (), &value); /* Oh, and terminate. */ ax_simple (ax.get (), aop_end); @@ -2443,7 +2419,7 @@ gen_trace_for_expr (CORE_ADDR scope, struct expression *expr, gen_expr (expr, &pc, ax.get (), &value); /* Make sure we record the final object, and get rid of it. */ - gen_traced_pop (expr->gdbarch, ax.get (), &value); + gen_traced_pop (ax.get (), &value); /* Oh, and terminate. */ ax_simple (ax.get (), aop_end); @@ -2491,7 +2467,7 @@ gen_trace_for_return_address (CORE_ADDR scope, struct gdbarch *gdbarch, gdbarch_gen_return_address (gdbarch, ax.get (), &value, scope); /* Make sure we record the final object, and get rid of it. */ - gen_traced_pop (gdbarch, ax.get (), &value); + gen_traced_pop (ax.get (), &value); /* Oh, and terminate. */ ax_simple (ax.get (), aop_end); diff --git a/gdb/block.c b/gdb/block.c index 2f44460..1c343aa 100644 --- a/gdb/block.c +++ b/gdb/block.c @@ -589,75 +589,6 @@ block_iterator_next (struct block_iterator *iterator) return block_iterator_step (iterator, 0); } -/* Perform a single step for a "name" block iterator, iterating across - symbol tables as needed. Returns the next symbol, or NULL when - iteration is complete. */ - -static struct symbol * -block_iter_name_step (struct block_iterator *iterator, const char *name, - int first) -{ - struct symbol *sym; - - gdb_assert (iterator->which != FIRST_LOCAL_BLOCK); - - while (1) - { - if (first) - { - struct compunit_symtab *cust - = find_iterator_compunit_symtab (iterator); - const struct block *block; - - /* Iteration is complete. */ - if (cust == NULL) - return NULL; - - block = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), - iterator->which); - sym = dict_iter_name_first (BLOCK_DICT (block), name, - &iterator->dict_iter); - } - else - sym = dict_iter_name_next (name, &iterator->dict_iter); - - if (sym != NULL) - return sym; - - /* We have finished iterating the appropriate block of one - symtab. Now advance to the next symtab and begin iteration - there. */ - ++iterator->idx; - first = 1; - } -} - -/* See block.h. */ - -struct symbol * -block_iter_name_first (const struct block *block, - const char *name, - struct block_iterator *iterator) -{ - initialize_block_iterator (block, iterator); - - if (iterator->which == FIRST_LOCAL_BLOCK) - return dict_iter_name_first (block->dict, name, &iterator->dict_iter); - - return block_iter_name_step (iterator, name, 1); -} - -/* See block.h. */ - -struct symbol * -block_iter_name_next (const char *name, struct block_iterator *iterator) -{ - if (iterator->which == FIRST_LOCAL_BLOCK) - return dict_iter_name_next (name, &iterator->dict_iter); - - return block_iter_name_step (iterator, name, 0); -} - /* Perform a single step for a "match" block iterator, iterating across symbol tables as needed. Returns the next symbol, or NULL when iteration is complete. */ @@ -812,9 +743,9 @@ block_lookup_symbol_primary (const struct block *block, const char *name, || BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL); other = NULL; - for (sym = dict_iter_name_first (block->dict, name, &dict_iter); + for (sym = dict_iter_match_first (block->dict, name, strcmp_iw, &dict_iter); sym != NULL; - sym = dict_iter_name_next (name, &dict_iter)) + sym = dict_iter_match_next (name, strcmp_iw, &dict_iter)) { if (SYMBOL_DOMAIN (sym) == domain) return sym; diff --git a/gdb/block.h b/gdb/block.h index eeb5ed4..1741e52 100644 --- a/gdb/block.h +++ b/gdb/block.h @@ -237,25 +237,6 @@ extern struct symbol *block_iterator_first (const struct block *block, extern struct symbol *block_iterator_next (struct block_iterator *iterator); /* Initialize ITERATOR to point at the first symbol in BLOCK whose - SYMBOL_SEARCH_NAME is NAME (as tested using strcmp_iw), and return - that first symbol, or NULL if there are no such symbols. */ - -extern struct symbol *block_iter_name_first (const struct block *block, - const char *name, - struct block_iterator *iterator); - -/* Advance ITERATOR to point at the next symbol in BLOCK whose - SYMBOL_SEARCH_NAME is NAME (as tested using strcmp_iw), or NULL if - there are no more such symbols. Don't call this if you've - previously received NULL from block_iterator_first or - block_iterator_next on this iteration. And don't call it unless - ITERATOR was created by a previous call to block_iter_name_first - with the same NAME. */ - -extern struct symbol *block_iter_name_next (const char *name, - struct block_iterator *iterator); - -/* Initialize ITERATOR to point at the first symbol in BLOCK whose SYMBOL_SEARCH_NAME is NAME, as tested using COMPARE (which must use the same conventions as strcmp_iw and be compatible with any block hashing function), and return that first symbol, or NULL @@ -340,8 +321,9 @@ extern int block_find_non_opaque_type_preferred (struct symbol *sym, must be a struct block_iterator. SYM points to the current symbol. */ #define ALL_BLOCK_SYMBOLS_WITH_NAME(block, name, iter, sym) \ - for ((sym) = block_iter_name_first ((block), (name), &(iter)); \ + for ((sym) = block_iter_match_first ((block), (name), \ + strcmp_iw, &(iter)); \ (sym) != NULL; \ - (sym) = block_iter_name_next ((name), &(iter))) + (sym) = block_iter_match_next ((name), strcmp_iw, &(iter))) #endif /* BLOCK_H */ diff --git a/gdb/break-catch-sig.c b/gdb/break-catch-sig.c index 3eede93..98888c9 100644 --- a/gdb/break-catch-sig.c +++ b/gdb/break-catch-sig.c @@ -33,30 +33,24 @@ #define INTERNAL_SIGNAL(x) ((x) == GDB_SIGNAL_TRAP || (x) == GDB_SIGNAL_INT) -typedef enum gdb_signal gdb_signal_type; - -DEF_VEC_I (gdb_signal_type); - /* An instance of this type is used to represent a signal catchpoint. A breakpoint is really of this type iff its ops pointer points to SIGNAL_CATCHPOINT_OPS. */ struct signal_catchpoint : public breakpoint { - ~signal_catchpoint () override; - /* Signal numbers used for the 'catch signal' feature. If no signal - has been specified for filtering, its value is NULL. Otherwise, + has been specified for filtering, it is empty. Otherwise, it holds a list of all signals to be caught. */ - VEC (gdb_signal_type) *signals_to_be_caught; + std::vector<gdb_signal> signals_to_be_caught; - /* If SIGNALS_TO_BE_CAUGHT is NULL, then all "ordinary" signals are - caught. If CATCH_ALL is non-zero, then internal signals are - caught as well. If SIGNALS_TO_BE_CAUGHT is non-NULL, then this - field is ignored. */ + /* If SIGNALS_TO_BE_CAUGHT is empty, then all "ordinary" signals are + caught. If CATCH_ALL is true, then internal signals are caught + as well. If SIGNALS_TO_BE_CAUGHT is not empty, then this field + is ignored. */ - int catch_all; + bool catch_all; }; /* The breakpoint_ops structure to be used in signal catchpoints. */ @@ -85,13 +79,6 @@ signal_to_name_or_int (enum gdb_signal sig) -/* signal_catchpoint destructor. */ - -signal_catchpoint::~signal_catchpoint () -{ - VEC_free (gdb_signal_type, this->signals_to_be_caught); -} - /* Implement the "insert_location" breakpoint_ops method for signal catchpoints. */ @@ -99,20 +86,15 @@ static int signal_catchpoint_insert_location (struct bp_location *bl) { struct signal_catchpoint *c = (struct signal_catchpoint *) bl->owner; - int i; - if (c->signals_to_be_caught != NULL) + if (!c->signals_to_be_caught.empty ()) { - gdb_signal_type iter; - - for (i = 0; - VEC_iterate (gdb_signal_type, c->signals_to_be_caught, i, iter); - i++) + for (gdb_signal iter : c->signals_to_be_caught) ++signal_catch_counts[iter]; } else { - for (i = 0; i < GDB_SIGNAL_LAST; ++i) + for (int i = 0; i < GDB_SIGNAL_LAST; ++i) { if (c->catch_all || !INTERNAL_SIGNAL (i)) ++signal_catch_counts[i]; @@ -132,15 +114,10 @@ signal_catchpoint_remove_location (struct bp_location *bl, enum remove_bp_reason reason) { struct signal_catchpoint *c = (struct signal_catchpoint *) bl->owner; - int i; - if (c->signals_to_be_caught != NULL) + if (!c->signals_to_be_caught.empty ()) { - gdb_signal_type iter; - - for (i = 0; - VEC_iterate (gdb_signal_type, c->signals_to_be_caught, i, iter); - i++) + for (gdb_signal iter : c->signals_to_be_caught) { gdb_assert (signal_catch_counts[iter] > 0); --signal_catch_counts[iter]; @@ -148,7 +125,7 @@ signal_catchpoint_remove_location (struct bp_location *bl, } else { - for (i = 0; i < GDB_SIGNAL_LAST; ++i) + for (int i = 0; i < GDB_SIGNAL_LAST; ++i) { if (c->catch_all || !INTERNAL_SIGNAL (i)) { @@ -174,7 +151,7 @@ signal_catchpoint_breakpoint_hit (const struct bp_location *bl, { const struct signal_catchpoint *c = (const struct signal_catchpoint *) bl->owner; - gdb_signal_type signal_number; + gdb_signal signal_number; if (ws->kind != TARGET_WAITKIND_STOPPED) return 0; @@ -184,18 +161,12 @@ signal_catchpoint_breakpoint_hit (const struct bp_location *bl, /* If we are catching specific signals in this breakpoint, then we must guarantee that the called signal is the same signal we are catching. */ - if (c->signals_to_be_caught) + if (!c->signals_to_be_caught.empty ()) { - int i; - gdb_signal_type iter; - - for (i = 0; - VEC_iterate (gdb_signal_type, c->signals_to_be_caught, i, iter); - i++) + for (gdb_signal iter : c->signals_to_be_caught) if (signal_number == iter) return 1; /* Not the same. */ - gdb_assert (!iter); return 0; } else @@ -246,26 +217,24 @@ signal_catchpoint_print_one (struct breakpoint *b, uiout->field_skip ("addr"); annotate_field (5); - if (c->signals_to_be_caught - && VEC_length (gdb_signal_type, c->signals_to_be_caught) > 1) + if (c->signals_to_be_caught.size () > 1) uiout->text ("signals \""); else uiout->text ("signal \""); - if (c->signals_to_be_caught) + if (!c->signals_to_be_caught.empty ()) { - int i; - gdb_signal_type iter; std::string text; - for (i = 0; - VEC_iterate (gdb_signal_type, c->signals_to_be_caught, i, iter); - i++) + bool first = true; + for (gdb_signal iter : c->signals_to_be_caught) { const char *name = signal_to_name_or_int (iter); - if (i > 0) + if (!first) text += " "; + first = false; + text += name; } uiout->field_string ("what", text.c_str ()); @@ -287,19 +256,14 @@ signal_catchpoint_print_mention (struct breakpoint *b) { struct signal_catchpoint *c = (struct signal_catchpoint *) b; - if (c->signals_to_be_caught) + if (!c->signals_to_be_caught.empty ()) { - int i; - gdb_signal_type iter; - - if (VEC_length (gdb_signal_type, c->signals_to_be_caught) > 1) + if (c->signals_to_be_caught.size () > 1) printf_filtered (_("Catchpoint %d (signals"), b->number); else printf_filtered (_("Catchpoint %d (signal"), b->number); - for (i = 0; - VEC_iterate (gdb_signal_type, c->signals_to_be_caught, i, iter); - i++) + for (gdb_signal iter : c->signals_to_be_caught) { const char *name = signal_to_name_or_int (iter); @@ -323,14 +287,9 @@ signal_catchpoint_print_recreate (struct breakpoint *b, struct ui_file *fp) fprintf_unfiltered (fp, "catch signal"); - if (c->signals_to_be_caught) + if (!c->signals_to_be_caught.empty ()) { - int i; - gdb_signal_type iter; - - for (i = 0; - VEC_iterate (gdb_signal_type, c->signals_to_be_caught, i, iter); - i++) + for (gdb_signal iter : c->signals_to_be_caught) fprintf_unfiltered (fp, " %s", signal_to_name_or_int (iter)); } else if (c->catch_all) @@ -349,81 +308,74 @@ signal_catchpoint_explains_signal (struct breakpoint *b, enum gdb_signal sig) /* Create a new signal catchpoint. TEMPFLAG is true if this should be a temporary catchpoint. FILTER is the list of signals to catch; it - can be NULL, meaning all signals. CATCH_ALL is a flag indicating + can be empty, meaning all signals. CATCH_ALL is a flag indicating whether signals used internally by gdb should be caught; it is only - valid if FILTER is NULL. If FILTER is NULL and CATCH_ALL is zero, + valid if FILTER is NULL. If FILTER is empty and CATCH_ALL is zero, then internal signals like SIGTRAP are not caught. */ static void -create_signal_catchpoint (int tempflag, VEC (gdb_signal_type) *filter, - int catch_all) +create_signal_catchpoint (int tempflag, std::vector<gdb_signal> &&filter, + bool catch_all) { struct signal_catchpoint *c; struct gdbarch *gdbarch = get_current_arch (); c = new signal_catchpoint (); init_catchpoint (c, gdbarch, tempflag, NULL, &signal_catchpoint_ops); - c->signals_to_be_caught = filter; + c->signals_to_be_caught = std::move (filter); c->catch_all = catch_all; install_breakpoint (0, c, 1); } -/* Splits the argument using space as delimiter. Returns an xmalloc'd - filter list, or NULL if no filtering is required. */ +/* Splits the argument using space as delimiter. Returns a filter + list, which is empty if no filtering is required. */ -static VEC (gdb_signal_type) * -catch_signal_split_args (char *arg, int *catch_all) +static std::vector<gdb_signal> +catch_signal_split_args (char *arg, bool *catch_all) { - VEC (gdb_signal_type) *result = NULL; - struct cleanup *cleanup = make_cleanup (VEC_cleanup (gdb_signal_type), - &result); - int first = 1; + std::vector<gdb_signal> result; + bool first = true; while (*arg != '\0') { int num; - gdb_signal_type signal_number; - char *one_arg, *endptr; - struct cleanup *inner_cleanup; + gdb_signal signal_number; + char *endptr; - one_arg = extract_arg (&arg); + gdb::unique_xmalloc_ptr<char> one_arg (extract_arg (&arg)); if (one_arg == NULL) break; - inner_cleanup = make_cleanup (xfree, one_arg); /* Check for the special flag "all". */ - if (strcmp (one_arg, "all") == 0) + if (strcmp (one_arg.get (), "all") == 0) { arg = skip_spaces (arg); if (*arg != '\0' || !first) error (_("'all' cannot be caught with other signals")); - *catch_all = 1; - gdb_assert (result == NULL); - do_cleanups (inner_cleanup); - discard_cleanups (cleanup); - return NULL; + *catch_all = true; + gdb_assert (result.empty ()); + return result; } - first = 0; + first = false; /* Check if the user provided a signal name or a number. */ - num = (int) strtol (one_arg, &endptr, 0); + num = (int) strtol (one_arg.get (), &endptr, 0); if (*endptr == '\0') signal_number = gdb_signal_from_command (num); else { - signal_number = gdb_signal_from_name (one_arg); + signal_number = gdb_signal_from_name (one_arg.get ()); if (signal_number == GDB_SIGNAL_UNKNOWN) - error (_("Unknown signal name '%s'."), one_arg); + error (_("Unknown signal name '%s'."), one_arg.get ()); } - VEC_safe_push (gdb_signal_type, result, signal_number); - do_cleanups (inner_cleanup); + result.push_back (signal_number); } - discard_cleanups (cleanup); + result.shrink_to_fit (); return result; } @@ -433,8 +385,9 @@ static void catch_signal_command (char *arg, int from_tty, struct cmd_list_element *command) { - int tempflag, catch_all = 0; - VEC (gdb_signal_type) *filter; + int tempflag; + bool catch_all = false; + std::vector<gdb_signal> filter; tempflag = get_cmd_context (command) == CATCH_TEMPORARY; @@ -448,10 +401,8 @@ catch_signal_command (char *arg, int from_tty, if (arg != NULL) filter = catch_signal_split_args (arg, &catch_all); - else - filter = NULL; - create_signal_catchpoint (tempflag, filter, catch_all); + create_signal_catchpoint (tempflag, std::move (filter), catch_all); } static void diff --git a/gdb/break-catch-syscall.c b/gdb/break-catch-syscall.c index 92ab91b..701645e 100644 --- a/gdb/break-catch-syscall.c +++ b/gdb/break-catch-syscall.c @@ -36,22 +36,12 @@ struct syscall_catchpoint : public breakpoint { - ~syscall_catchpoint () override; - /* Syscall numbers used for the 'catch syscall' feature. If no - syscall has been specified for filtering, its value is NULL. - Otherwise, it holds a list of all syscalls to be caught. The - list elements are allocated with xmalloc. */ - VEC(int) *syscalls_to_be_caught; + syscall has been specified for filtering, it is empty. + Otherwise, it holds a list of all syscalls to be caught. */ + std::vector<int> syscalls_to_be_caught; }; -/* catch_syscall destructor. */ - -syscall_catchpoint::~syscall_catchpoint () -{ - VEC_free (int, this->syscalls_to_be_caught); -} - static const struct inferior_data *catch_syscall_inferior_data = NULL; struct catch_syscall_inferior_data @@ -64,14 +54,14 @@ struct catch_syscall_inferior_data int any_syscall_count; /* Count of each system call. */ - VEC(int) *syscalls_counts; + std::vector<int> syscalls_counts; /* This counts all syscall catch requests, so we can readily determine if any catching is necessary. */ int total_syscalls_count; }; -static struct catch_syscall_inferior_data* +static struct catch_syscall_inferior_data * get_catch_syscall_inferior_data (struct inferior *inf) { struct catch_syscall_inferior_data *inf_data; @@ -80,7 +70,7 @@ get_catch_syscall_inferior_data (struct inferior *inf) inferior_data (inf, catch_syscall_inferior_data)); if (inf_data == NULL) { - inf_data = XCNEW (struct catch_syscall_inferior_data); + inf_data = new struct catch_syscall_inferior_data (); set_inferior_data (inf, catch_syscall_inferior_data, inf_data); } @@ -90,7 +80,9 @@ get_catch_syscall_inferior_data (struct inferior *inf) static void catch_syscall_inferior_data_cleanup (struct inferior *inf, void *arg) { - xfree (arg); + struct catch_syscall_inferior_data *inf_data + = (struct catch_syscall_inferior_data *) arg; + delete inf_data; } @@ -106,43 +98,25 @@ insert_catch_syscall (struct bp_location *bl) = get_catch_syscall_inferior_data (inf); ++inf_data->total_syscalls_count; - if (!c->syscalls_to_be_caught) + if (c->syscalls_to_be_caught.empty ()) ++inf_data->any_syscall_count; else { - int i, iter; - - for (i = 0; - VEC_iterate (int, c->syscalls_to_be_caught, i, iter); - i++) + for (int iter : c->syscalls_to_be_caught) { int elem; - if (iter >= VEC_length (int, inf_data->syscalls_counts)) - { - int old_size = VEC_length (int, inf_data->syscalls_counts); - uintptr_t vec_addr_offset - = old_size * ((uintptr_t) sizeof (int)); - uintptr_t vec_addr; - VEC_safe_grow (int, inf_data->syscalls_counts, iter + 1); - vec_addr = ((uintptr_t) VEC_address (int, - inf_data->syscalls_counts) - + vec_addr_offset); - memset ((void *) vec_addr, 0, - (iter + 1 - old_size) * sizeof (int)); - } - elem = VEC_index (int, inf_data->syscalls_counts, iter); - VEC_replace (int, inf_data->syscalls_counts, iter, ++elem); + if (iter >= inf_data->syscalls_counts.size ()) + inf_data->syscalls_counts.resize (iter + 1); + ++inf_data->syscalls_counts[iter]; } } return target_set_syscall_catchpoint (ptid_get_pid (inferior_ptid), inf_data->total_syscalls_count != 0, inf_data->any_syscall_count, - VEC_length (int, - inf_data->syscalls_counts), - VEC_address (int, - inf_data->syscalls_counts)); + inf_data->syscalls_counts.size (), + inf_data->syscalls_counts.data ()); } /* Implement the "remove" breakpoint_ops method for syscall @@ -157,32 +131,25 @@ remove_catch_syscall (struct bp_location *bl, enum remove_bp_reason reason) = get_catch_syscall_inferior_data (inf); --inf_data->total_syscalls_count; - if (!c->syscalls_to_be_caught) + if (c->syscalls_to_be_caught.empty ()) --inf_data->any_syscall_count; else { - int i, iter; - - for (i = 0; - VEC_iterate (int, c->syscalls_to_be_caught, i, iter); - i++) + for (int iter : c->syscalls_to_be_caught) { int elem; - if (iter >= VEC_length (int, inf_data->syscalls_counts)) + if (iter >= inf_data->syscalls_counts.size ()) /* Shouldn't happen. */ continue; - elem = VEC_index (int, inf_data->syscalls_counts, iter); - VEC_replace (int, inf_data->syscalls_counts, iter, --elem); + --inf_data->syscalls_counts[iter]; } } return target_set_syscall_catchpoint (ptid_get_pid (inferior_ptid), inf_data->total_syscalls_count != 0, inf_data->any_syscall_count, - VEC_length (int, - inf_data->syscalls_counts), - VEC_address (int, - inf_data->syscalls_counts)); + inf_data->syscalls_counts.size (), + inf_data->syscalls_counts.data ()); } /* Implement the "breakpoint_hit" breakpoint_ops method for syscall @@ -207,13 +174,9 @@ breakpoint_hit_catch_syscall (const struct bp_location *bl, syscall_number = ws->value.syscall_number; /* Now, checking if the syscall is the same. */ - if (c->syscalls_to_be_caught) + if (!c->syscalls_to_be_caught.empty ()) { - int i, iter; - - for (i = 0; - VEC_iterate (int, c->syscalls_to_be_caught, i, iter); - i++) + for (int iter : c->syscalls_to_be_caught) if (syscall_number == iter) return 1; @@ -296,20 +259,16 @@ print_one_catch_syscall (struct breakpoint *b, uiout->field_skip ("addr"); annotate_field (5); - if (c->syscalls_to_be_caught - && VEC_length (int, c->syscalls_to_be_caught) > 1) + if (c->syscalls_to_be_caught.size () > 1) uiout->text ("syscalls \""); else uiout->text ("syscall \""); - if (c->syscalls_to_be_caught) + if (!c->syscalls_to_be_caught.empty ()) { - int i, iter; char *text = xstrprintf ("%s", ""); - for (i = 0; - VEC_iterate (int, c->syscalls_to_be_caught, i, iter); - i++) + for (int iter : c->syscalls_to_be_caught) { char *x = text; struct syscall s; @@ -346,23 +305,19 @@ print_mention_catch_syscall (struct breakpoint *b) struct syscall_catchpoint *c = (struct syscall_catchpoint *) b; struct gdbarch *gdbarch = b->loc->gdbarch; - if (c->syscalls_to_be_caught) + if (!c->syscalls_to_be_caught.empty ()) { - int i, iter; - - if (VEC_length (int, c->syscalls_to_be_caught) > 1) + if (c->syscalls_to_be_caught.size () > 1) printf_filtered (_("Catchpoint %d (syscalls"), b->number); else printf_filtered (_("Catchpoint %d (syscall"), b->number); - for (i = 0; - VEC_iterate (int, c->syscalls_to_be_caught, i, iter); - i++) + for (int iter : c->syscalls_to_be_caught) { struct syscall s; get_syscall_by_number (gdbarch, iter, &s); - if (s.name) + if (s.name != NULL) printf_filtered (" '%s' [%d]", s.name, s.number); else printf_filtered (" %d", s.number); @@ -385,23 +340,17 @@ print_recreate_catch_syscall (struct breakpoint *b, struct ui_file *fp) fprintf_unfiltered (fp, "catch syscall"); - if (c->syscalls_to_be_caught) + for (int iter : c->syscalls_to_be_caught) { - int i, iter; - - for (i = 0; - VEC_iterate (int, c->syscalls_to_be_caught, i, iter); - i++) - { - struct syscall s; + struct syscall s; - get_syscall_by_number (gdbarch, iter, &s); - if (s.name) - fprintf_unfiltered (fp, " %s", s.name); - else - fprintf_unfiltered (fp, " %d", s.number); - } + get_syscall_by_number (gdbarch, iter, &s); + if (s.name != NULL) + fprintf_unfiltered (fp, " %s", s.name); + else + fprintf_unfiltered (fp, " %d", s.number); } + print_recreate_thread (b, fp); } @@ -418,7 +367,7 @@ syscall_catchpoint_p (struct breakpoint *b) } static void -create_syscall_event_catchpoint (int tempflag, VEC(int) *filter, +create_syscall_event_catchpoint (int tempflag, std::vector<int> &&filter, const struct breakpoint_ops *ops) { struct syscall_catchpoint *c; @@ -426,18 +375,17 @@ create_syscall_event_catchpoint (int tempflag, VEC(int) *filter, c = new syscall_catchpoint (); init_catchpoint (c, gdbarch, tempflag, NULL, ops); - c->syscalls_to_be_caught = filter; + c->syscalls_to_be_caught = std::move (filter); install_breakpoint (0, c, 1); } -/* Splits the argument using space as delimiter. Returns an xmalloc'd - filter list, or NULL if no filtering is required. */ -static VEC(int) * +/* Splits the argument using space as delimiter. */ + +static std::vector<int> catch_syscall_split_args (char *arg) { - VEC(int) *result = NULL; - struct cleanup *cleanup = make_cleanup (VEC_cleanup (int), &result); + std::vector<int> result; struct gdbarch *gdbarch = target_gdbarch (); while (*arg != '\0') @@ -460,7 +408,7 @@ catch_syscall_split_args (char *arg) if (*endptr == '\0') { get_syscall_by_number (gdbarch, syscall_number, &s); - VEC_safe_push (int, result, s.number); + result.push_back (s.number); } else if (startswith (cur_name, "g:") || startswith (cur_name, "group:")) @@ -482,7 +430,7 @@ catch_syscall_split_args (char *arg) { /* Insert each syscall that are part of the group. No need to check if it is valid. */ - VEC_safe_push (int, result, syscall_list[i].number); + result.push_back (syscall_list[i].number); } xfree (syscall_list); @@ -500,11 +448,10 @@ catch_syscall_split_args (char *arg) error (_("Unknown syscall name '%s'."), cur_name); /* Ok, it's valid. */ - VEC_safe_push (int, result, s.number); + result.push_back (s.number); } } - discard_cleanups (cleanup); return result; } @@ -515,7 +462,7 @@ catch_syscall_command_1 (char *arg, int from_tty, struct cmd_list_element *command) { int tempflag; - VEC(int) *filter; + std::vector<int> filter; struct syscall s; struct gdbarch *gdbarch = get_current_arch (); @@ -542,10 +489,8 @@ this architecture yet.")); if (arg != NULL) filter = catch_syscall_split_args (arg); - else - filter = NULL; - create_syscall_event_catchpoint (tempflag, filter, + create_syscall_event_catchpoint (tempflag, std::move (filter), &catch_syscall_breakpoint_ops); } @@ -586,12 +531,9 @@ catching_syscall_number_1 (struct breakpoint *b, { struct syscall_catchpoint *c = (struct syscall_catchpoint *) b; - if (c->syscalls_to_be_caught) + if (!c->syscalls_to_be_caught.empty ()) { - int i, iter; - for (i = 0; - VEC_iterate (int, c->syscalls_to_be_caught, i, iter); - i++) + for (int iter : c->syscalls_to_be_caught) if (syscall_number == iter) return 1; } @@ -612,15 +554,14 @@ catching_syscall_number (int syscall_number) } /* Complete syscall names. Used by "catch syscall". */ -static VEC (char_ptr) * + +static void catch_syscall_completer (struct cmd_list_element *cmd, + completion_tracker &tracker, const char *text, const char *word) { struct gdbarch *gdbarch = get_current_arch (); struct cleanup *cleanups = make_cleanup (null_cleanup, NULL); - VEC (char_ptr) *group_retlist = NULL; - VEC (char_ptr) *syscall_retlist = NULL; - VEC (char_ptr) *retlist = NULL; const char **group_list = NULL; const char **syscall_list = NULL; const char *prefix; @@ -636,8 +577,8 @@ catch_syscall_completer (struct cmd_list_element *cmd, { /* Perform completion inside 'group:' namespace only. */ group_list = get_syscall_group_names (gdbarch); - retlist = (group_list == NULL - ? NULL : complete_on_enum (group_list, word, word)); + if (group_list != NULL) + complete_on_enum (tracker, group_list, word, word); } else { @@ -654,21 +595,15 @@ catch_syscall_completer (struct cmd_list_element *cmd, make_cleanup (xfree, prefixed_group); } - syscall_retlist = ((syscall_list == NULL) - ? NULL : complete_on_enum (syscall_list, word, word)); - group_retlist = ((group_list == NULL) - ? NULL : complete_on_enum (group_list, word, word)); - - retlist = VEC_merge (char_ptr, syscall_retlist, group_retlist); + if (syscall_list != NULL) + complete_on_enum (tracker, syscall_list, word, word); + if (group_list != NULL) + complete_on_enum (tracker, group_list, word, word); } - VEC_free (char_ptr, syscall_retlist); - VEC_free (char_ptr, group_retlist); xfree (syscall_list); xfree (group_list); do_cleanups (cleanups); - - return retlist; } static void @@ -679,7 +614,7 @@ clear_syscall_counts (struct inferior *inf) inf_data->total_syscalls_count = 0; inf_data->any_syscall_count = 0; - VEC_free (int, inf_data->syscalls_counts); + inf_data->syscalls_counts.clear (); } static void diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c index 0074d06..5318e5f 100644 --- a/gdb/break-catch-throw.c +++ b/gdb/break-catch-throw.c @@ -76,16 +76,14 @@ static struct breakpoint_ops gnu_v3_exception_catchpoint_ops; struct exception_catchpoint : public breakpoint { - ~exception_catchpoint () override; - /* The kind of exception catchpoint. */ enum exception_event_kind kind; - /* If non-NULL, an xmalloc'd string holding the source form of the - regular expression to match against. */ + /* If not empty, a string holding the source form of the regular + expression to match against. */ - char *exception_rx; + std::string exception_rx; /* If non-NULL, a compiled regular expression which is used to determine which exceptions to stop on. */ @@ -140,13 +138,6 @@ classify_exception_breakpoint (struct breakpoint *b) return cp->kind; } -/* exception_catchpoint destructor. */ - -exception_catchpoint::~exception_catchpoint () -{ - xfree (this->exception_rx); -} - /* Implement the 'check_status' method. */ static void @@ -319,10 +310,10 @@ print_one_detail_exception_catchpoint (const struct breakpoint *b, const struct exception_catchpoint *cp = (const struct exception_catchpoint *) b; - if (cp->exception_rx != NULL) + if (!cp->exception_rx.empty ()) { uiout->text (_("\tmatching: ")); - uiout->field_string ("regexp", cp->exception_rx); + uiout->field_string ("regexp", cp->exception_rx.c_str ()); uiout->text ("\n"); } } @@ -371,15 +362,15 @@ print_recreate_exception_catchpoint (struct breakpoint *b, } static void -handle_gnu_v3_exceptions (int tempflag, char *except_rx, +handle_gnu_v3_exceptions (int tempflag, std::string &&except_rx, const char *cond_string, enum exception_event_kind ex_event, int from_tty) { std::unique_ptr<compiled_regex> pattern; - if (except_rx != NULL) + if (!except_rx.empty ()) { - pattern.reset (new compiled_regex (except_rx, REG_NOSUB, + pattern.reset (new compiled_regex (except_rx.c_str (), REG_NOSUB, _("invalid type-matching regexp"))); } @@ -391,7 +382,7 @@ handle_gnu_v3_exceptions (int tempflag, char *except_rx, the right thing. */ cp->type = bp_breakpoint; cp->kind = ex_event; - cp->exception_rx = except_rx; + cp->exception_rx = std::move (except_rx); cp->pattern = std::move (pattern); re_set_exception_catchpoint (cp.get ()); @@ -410,7 +401,7 @@ handle_gnu_v3_exceptions (int tempflag, char *except_rx, STRING is updated to point to the "if" token, if it exists, or to the end of the string. */ -static char * +static std::string extract_exception_regexp (const char **string) { const char *start; @@ -435,8 +426,8 @@ extract_exception_regexp (const char **string) *string = last; if (last_space > start) - return savestring (start, last_space - start); - return NULL; + return std::string (start, last_space - start); + return std::string (); } /* Deal with "catch catch", "catch throw", and "catch rethrow" @@ -447,17 +438,14 @@ catch_exception_command_1 (enum exception_event_kind ex_event, char *arg_entry, int tempflag, int from_tty) { - char *except_rx; const char *cond_string = NULL; - struct cleanup *cleanup; const char *arg = arg_entry; if (!arg) arg = ""; arg = skip_spaces_const (arg); - except_rx = extract_exception_regexp (&arg); - cleanup = make_cleanup (xfree, except_rx); + std::string except_rx = extract_exception_regexp (&arg); cond_string = ep_parse_optional_if_clause (&arg); @@ -469,10 +457,8 @@ catch_exception_command_1 (enum exception_event_kind ex_event, && ex_event != EX_EVENT_RETHROW) error (_("Unsupported or unknown exception event; cannot catch it")); - handle_gnu_v3_exceptions (tempflag, except_rx, cond_string, + handle_gnu_v3_exceptions (tempflag, std::move (except_rx), cond_string, ex_event, from_tty); - - discard_cleanups (cleanup); } /* Implementation of "catch catch" command. */ diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 053ccef..3dc9112 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -1042,8 +1042,9 @@ set_breakpoint_condition (struct breakpoint *b, const char *exp, /* Completion for the "condition" command. */ -static VEC (char_ptr) * +static void condition_completer (struct cmd_list_element *cmd, + completion_tracker &tracker, const char *text, const char *word) { const char *space; @@ -1059,9 +1060,9 @@ condition_completer (struct cmd_list_element *cmd, if (text[0] == '$') { /* We don't support completion of history indices. */ - if (isdigit (text[1])) - return NULL; - return complete_internalvar (&text[1]); + if (!isdigit (text[1])) + complete_internalvar (tracker, &text[1]); + return; } /* We're completing the breakpoint number. */ @@ -1074,15 +1075,18 @@ condition_completer (struct cmd_list_element *cmd, xsnprintf (number, sizeof (number), "%d", b->number); if (strncmp (number, text, len) == 0) - VEC_safe_push (char_ptr, result, xstrdup (number)); + { + gdb::unique_xmalloc_ptr<char> copy (xstrdup (number)); + tracker.add_completion (std::move (copy)); + } } - return result; + return; } /* We're completing the expression part. */ text = skip_spaces_const (space); - return expression_completer (cmd, text, word); + expression_completer (cmd, tracker, text, word); } /* condition N EXP -- set break condition of breakpoint N to EXP. */ @@ -6804,7 +6808,6 @@ breakpoint_1 (char *args, int allflag, struct breakpoint *b; struct bp_location *last_loc = NULL; int nr_printable_breakpoints; - struct cleanup *bkpttbl_chain; struct value_print_options opts; int print_address_bits = 0; int print_type_col_width = 14; @@ -6847,77 +6850,71 @@ breakpoint_1 (char *args, int allflag, } } - if (opts.addressprint) - bkpttbl_chain - = make_cleanup_ui_out_table_begin_end (uiout, 6, - nr_printable_breakpoints, - "BreakpointTable"); - else - bkpttbl_chain - = make_cleanup_ui_out_table_begin_end (uiout, 5, - nr_printable_breakpoints, - "BreakpointTable"); - - if (nr_printable_breakpoints > 0) - annotate_breakpoints_headers (); - if (nr_printable_breakpoints > 0) - annotate_field (0); - uiout->table_header (7, ui_left, "number", "Num"); /* 1 */ - if (nr_printable_breakpoints > 0) - annotate_field (1); - uiout->table_header (print_type_col_width, ui_left, "type", "Type"); /* 2 */ - if (nr_printable_breakpoints > 0) - annotate_field (2); - uiout->table_header (4, ui_left, "disp", "Disp"); /* 3 */ - if (nr_printable_breakpoints > 0) - annotate_field (3); - uiout->table_header (3, ui_left, "enabled", "Enb"); /* 4 */ - if (opts.addressprint) - { - if (nr_printable_breakpoints > 0) - annotate_field (4); - if (print_address_bits <= 32) - uiout->table_header (10, ui_left, "addr", "Address"); /* 5 */ - else - uiout->table_header (18, ui_left, "addr", "Address"); /* 5 */ - } - if (nr_printable_breakpoints > 0) - annotate_field (5); - uiout->table_header (40, ui_noalign, "what", "What"); /* 6 */ - uiout->table_body (); - if (nr_printable_breakpoints > 0) - annotate_breakpoints_table (); - - ALL_BREAKPOINTS (b) - { - QUIT; - /* If we have a filter, only list the breakpoints it accepts. */ - if (filter && !filter (b)) - continue; - - /* If we have an "args" string, it is a list of breakpoints to - accept. Skip the others. */ + { + ui_out_emit_table table_emitter (uiout, + opts.addressprint ? 6 : 5, + nr_printable_breakpoints, + "BreakpointTable"); + + if (nr_printable_breakpoints > 0) + annotate_breakpoints_headers (); + if (nr_printable_breakpoints > 0) + annotate_field (0); + uiout->table_header (7, ui_left, "number", "Num"); /* 1 */ + if (nr_printable_breakpoints > 0) + annotate_field (1); + uiout->table_header (print_type_col_width, ui_left, "type", "Type"); /* 2 */ + if (nr_printable_breakpoints > 0) + annotate_field (2); + uiout->table_header (4, ui_left, "disp", "Disp"); /* 3 */ + if (nr_printable_breakpoints > 0) + annotate_field (3); + uiout->table_header (3, ui_left, "enabled", "Enb"); /* 4 */ + if (opts.addressprint) + { + if (nr_printable_breakpoints > 0) + annotate_field (4); + if (print_address_bits <= 32) + uiout->table_header (10, ui_left, "addr", "Address"); /* 5 */ + else + uiout->table_header (18, ui_left, "addr", "Address"); /* 5 */ + } + if (nr_printable_breakpoints > 0) + annotate_field (5); + uiout->table_header (40, ui_noalign, "what", "What"); /* 6 */ + uiout->table_body (); + if (nr_printable_breakpoints > 0) + annotate_breakpoints_table (); + + ALL_BREAKPOINTS (b) + { + QUIT; + /* If we have a filter, only list the breakpoints it accepts. */ + if (filter && !filter (b)) + continue; - if (args != NULL && *args != '\0') - { - if (allflag) /* maintenance info breakpoint */ - { - if (parse_and_eval_long (args) != b->number) - continue; - } - else /* all others */ - { - if (!number_is_in_list (args, b->number)) - continue; - } - } - /* We only print out user settable breakpoints unless the - allflag is set. */ - if (allflag || user_breakpoint_p (b)) - print_one_breakpoint (b, &last_loc, allflag); - } + /* If we have an "args" string, it is a list of breakpoints to + accept. Skip the others. */ - do_cleanups (bkpttbl_chain); + if (args != NULL && *args != '\0') + { + if (allflag) /* maintenance info breakpoint */ + { + if (parse_and_eval_long (args) != b->number) + continue; + } + else /* all others */ + { + if (!number_is_in_list (args, b->number)) + continue; + } + } + /* We only print out user settable breakpoints unless the + allflag is set. */ + if (allflag || user_breakpoint_p (b)) + print_one_breakpoint (b, &last_loc, allflag); + } + } if (nr_printable_breakpoints == 0) { @@ -15481,7 +15478,6 @@ save_breakpoints (char *filename, int from_tty, { struct breakpoint *tp; int any = 0; - struct cleanup *cleanup; int extra_trace_bits = 0; if (filename == 0 || *filename == 0) @@ -15515,14 +15511,13 @@ save_breakpoints (char *filename, int from_tty, return; } - filename = tilde_expand (filename); - cleanup = make_cleanup (xfree, filename); + gdb::unique_xmalloc_ptr<char> expanded_filename (tilde_expand (filename)); stdio_file fp; - if (!fp.open (filename, "w")) + if (!fp.open (expanded_filename.get (), "w")) error (_("Unable to open file '%s' for saving (%s)"), - filename, safe_strerror (errno)); + expanded_filename.get (), safe_strerror (errno)); if (extra_trace_bits) save_trace_state_variables (&fp); @@ -15590,8 +15585,7 @@ save_breakpoints (char *filename, int from_tty, fp.printf ("set default-collect %s\n", default_collect); if (from_tty) - printf_filtered (_("Saved to file '%s'.\n"), filename); - do_cleanups (cleanup); + printf_filtered (_("Saved to file '%s'.\n"), expanded_filename.get ()); } /* The `save breakpoints' command. */ diff --git a/gdb/c-exp.y b/gdb/c-exp.y index a7509da..c9603cd 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -1633,13 +1633,12 @@ write_destructor_name (struct parser_state *par_state, struct stoken token) static struct stoken operator_stoken (const char *op) { - static const char *operator_string = "operator"; struct stoken st = { NULL, 0 }; char *buf; - st.length = strlen (operator_string) + strlen (op); + st.length = CP_OPERATOR_LEN + strlen (op); buf = (char *) malloc (st.length + 1); - strcpy (buf, operator_string); + strcpy (buf, CP_OPERATOR_STR); strcat (buf, op); st.ptr = buf; @@ -2814,7 +2813,7 @@ static int popping; /* Temporary storage for c_lex; this holds symbol names as they are built up. */ -static struct obstack name_obstack; +auto_obstack name_obstack; /* Classify a NAME token. The contents of the token are in `yylval'. Updates yylval and returns the new token type. BLOCK is the block @@ -3075,7 +3074,7 @@ yylex (void) current = *VEC_index (token_and_value, token_fifo, next_to_examine); ++next_to_examine; - obstack_free (&name_obstack, obstack_base (&name_obstack)); + name_obstack.clear (); checkpoint = 0; if (current.token == FILENAME) search_block = current.value.bval; @@ -3177,6 +3176,9 @@ c_parse (struct parser_state *par_state) gdb_assert (par_state != NULL); pstate = par_state; + /* Note that parsing (within yyparse) freely installs cleanups + assuming they'll be run here (below). */ + back_to = make_cleanup (free_current_contents, &expression_macro_scope); make_cleanup_clear_parser_state (&pstate); @@ -3205,8 +3207,7 @@ c_parse (struct parser_state *par_state) VEC_free (token_and_value, token_fifo); popping = 0; - obstack_init (&name_obstack); - make_cleanup_obstack_free (&name_obstack); + name_obstack.clear (); result = yyparse (); do_cleanups (back_to); diff --git a/gdb/c-lang.c b/gdb/c-lang.c index 3628ebe..a65002c 100644 --- a/gdb/c-lang.c +++ b/gdb/c-lang.c @@ -38,8 +38,6 @@ #include "block.h" #include "linespec.h" /* for find_toplevel_char */ -extern void _initialize_c_language (void); - /* Given a C string type, STR_TYPE, return the corresponding target character set name. */ @@ -573,15 +571,12 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp, { int oplen, limit; struct type *type; - struct obstack output; - struct cleanup *cleanup; struct value *result; c_string_type dest_type; const char *dest_charset; int satisfy_expected = 0; - obstack_init (&output); - cleanup = make_cleanup_obstack_free (&output); + auto_obstack output; ++*pos; oplen = longest_to_int (exp->elts[*pos].longconst); @@ -659,7 +654,6 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp, result = allocate_value (type); else result = value_cstring ("", 0, type); - do_cleanups (cleanup); return result; } @@ -705,7 +699,6 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp, obstack_object_size (&output), type); } - do_cleanups (cleanup); return result; } break; @@ -901,7 +894,7 @@ static const char *c_extensions[] = ".c", NULL }; -const struct language_defn c_language_defn = +extern const struct language_defn c_language_defn = { "c", /* Language name */ "C", @@ -935,7 +928,7 @@ const struct language_defn c_language_defn = 1, /* c-style arrays */ 0, /* String lower bound */ default_word_break_characters, - default_make_symbol_completion_list, + default_collect_symbol_completion_matches, c_language_arch_info, default_print_array_index, default_pass_by_reference, @@ -1046,7 +1039,7 @@ static const char *cplus_extensions[] = ".C", ".cc", ".cp", ".cpp", ".cxx", ".c++", NULL }; -const struct language_defn cplus_language_defn = +extern const struct language_defn cplus_language_defn = { "c++", /* Language name */ "C++", @@ -1080,7 +1073,7 @@ const struct language_defn cplus_language_defn = 1, /* c-style arrays */ 0, /* String lower bound */ default_word_break_characters, - default_make_symbol_completion_list, + default_collect_symbol_completion_matches, cplus_language_arch_info, default_print_array_index, cp_pass_by_reference, @@ -1100,7 +1093,7 @@ static const char *asm_extensions[] = ".s", ".sx", ".S", NULL }; -const struct language_defn asm_language_defn = +extern const struct language_defn asm_language_defn = { "asm", /* Language name */ "assembly", @@ -1134,7 +1127,7 @@ const struct language_defn asm_language_defn = 1, /* c-style arrays */ 0, /* String lower bound */ default_word_break_characters, - default_make_symbol_completion_list, + default_collect_symbol_completion_matches, c_language_arch_info, /* FIXME: la_language_arch_info. */ default_print_array_index, default_pass_by_reference, @@ -1154,7 +1147,7 @@ const struct language_defn asm_language_defn = to do some simple operations when debugging applications that use a language currently not supported by GDB. */ -const struct language_defn minimal_language_defn = +extern const struct language_defn minimal_language_defn = { "minimal", /* Language name */ "Minimal", @@ -1188,7 +1181,7 @@ const struct language_defn minimal_language_defn = 1, /* c-style arrays */ 0, /* String lower bound */ default_word_break_characters, - default_make_symbol_completion_list, + default_collect_symbol_completion_matches, c_language_arch_info, default_print_array_index, default_pass_by_reference, @@ -1202,12 +1195,3 @@ const struct language_defn minimal_language_defn = NULL, LANG_MAGIC }; - -void -_initialize_c_language (void) -{ - add_language (&c_language_defn); - add_language (&cplus_language_defn); - add_language (&asm_language_defn); - add_language (&minimal_language_defn); -} diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c index 01e5b14..62db590 100644 --- a/gdb/c-typeprint.c +++ b/gdb/c-typeprint.c @@ -547,7 +547,7 @@ is_type_conversion_operator (struct type *type, int i, int j) some other way, feel free to rewrite this function. */ const char *name = TYPE_FN_FIELDLIST_NAME (type, i); - if (!startswith (name, "operator")) + if (!startswith (name, CP_OPERATOR_STR)) return 0; name += 8; diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c index 0930342..d3ec4ae 100644 --- a/gdb/cli/cli-cmds.c +++ b/gdb/cli/cli-cmds.c @@ -168,6 +168,10 @@ struct cmd_list_element *maintenanceinfolist; struct cmd_list_element *maintenanceprintlist; +/* Chain containing all defined "maintenance check" subcommands. */ + +struct cmd_list_element *maintenancechecklist; + struct cmd_list_element *setprintlist; struct cmd_list_element *showprintlist; @@ -238,6 +242,7 @@ help_command (char *command, int from_tty) help_cmd (command, gdb_stdout); } + /* Note: The "complete" command is used by Emacs to implement completion. [Is that why this function writes output with *_unfiltered?] */ @@ -245,9 +250,6 @@ static void complete_command (char *arg_entry, int from_tty) { const char *arg = arg_entry; - int argpoint; - char *arg_prefix; - VEC (char_ptr) *completions; dont_repeat (); @@ -265,57 +267,66 @@ complete_command (char *arg_entry, int from_tty) if (arg == NULL) arg = ""; - argpoint = strlen (arg); - - /* complete_line assumes that its first argument is somewhere - within, and except for filenames at the beginning of, the word to - be completed. The following crude imitation of readline's - word-breaking tries to accomodate this. */ - const char *point = arg + argpoint; - while (point > arg) - { - if (strchr (rl_completer_word_break_characters, point[-1]) != 0) - break; - point--; - } - arg_prefix = (char *) alloca (point - arg + 1); - memcpy (arg_prefix, arg, point - arg); - arg_prefix[point - arg] = 0; + completion_tracker tracker_handle_brkchars; + completion_tracker tracker_handle_completions; + completion_tracker *tracker; - completions = complete_line (point, arg, argpoint); + int quote_char = '\0'; + const char *word; - if (completions) + TRY { - int ix, size = VEC_length (char_ptr, completions); - char *item, *prev = NULL; + word = completion_find_completion_word (tracker_handle_brkchars, + arg, "e_char); + + /* Completers that provide a custom word point in the + handle_brkchars phase also compute their completions then. + Completers that leave the completion word handling to readline + must be called twice. */ + if (tracker_handle_brkchars.use_custom_word_point ()) + tracker = &tracker_handle_brkchars; + else + { + complete_line (tracker_handle_completions, word, arg, strlen (arg)); + tracker = &tracker_handle_completions; + } + } + CATCH (ex, RETURN_MASK_ALL) + { + return; + } + + std::string arg_prefix (arg, word - arg); - qsort (VEC_address (char_ptr, completions), size, - sizeof (char *), compare_strings); + completion_result result + = tracker->build_completion_result (word, word - arg, strlen (arg)); - /* We do extra processing here since we only want to print each - unique item once. */ - for (ix = 0; VEC_iterate (char_ptr, completions, ix, item); ++ix) + if (result.number_matches != 0) + { + if (result.number_matches == 1) + printf_unfiltered ("%s%s\n", arg_prefix.c_str (), result.match_list[0]); + else { - if (prev == NULL || strcmp (item, prev) != 0) + result.sort_match_list (); + + for (size_t i = 0; i < result.number_matches; i++) { - printf_unfiltered ("%s%s\n", arg_prefix, item); - xfree (prev); - prev = item; + printf_unfiltered ("%s%s", + arg_prefix.c_str (), + result.match_list[i + 1]); + if (quote_char) + printf_unfiltered ("%c", quote_char); + printf_unfiltered ("\n"); } - else - xfree (item); } - xfree (prev); - VEC_free (char_ptr, completions); - - if (size == max_completions) + if (result.number_matches == max_completions) { - /* ARG_PREFIX and POINT are included in the output so that emacs + /* ARG_PREFIX and WORD are included in the output so that emacs will include the message in the output. */ printf_unfiltered (_("%s%s %s\n"), - arg_prefix, point, + arg_prefix.c_str (), word, get_max_completions_reached_message ()); } } @@ -495,57 +506,47 @@ show_script_ext_mode (struct ui_file *file, int from_tty, /* Try to open SCRIPT_FILE. If successful, the full path name is stored in *FULL_PATHP, - the stream is stored in *STREAMP, and return 1. - The caller is responsible for freeing *FULL_PATHP. - If not successful, return 0; errno is set for the last file + and the stream is returned. + If not successful, return NULL; errno is set for the last file we tried to open. If SEARCH_PATH is non-zero, and the file isn't found in cwd, search for it in the source search path. */ -int -find_and_open_script (const char *script_file, int search_path, - FILE **streamp, char **full_pathp) +gdb::optional<open_script> +find_and_open_script (const char *script_file, int search_path) { - char *file; int fd; - struct cleanup *old_cleanups; int search_flags = OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH; + gdb::optional<open_script> opened; - file = tilde_expand (script_file); - old_cleanups = make_cleanup (xfree, file); + gdb::unique_xmalloc_ptr<char> file (tilde_expand (script_file)); if (search_path) search_flags |= OPF_SEARCH_IN_PATH; /* Search for and open 'file' on the search path used for source files. Put the full location in *FULL_PATHP. */ + char *temp_path; fd = openp (source_path, search_flags, - file, O_RDONLY, full_pathp); + file.get (), O_RDONLY, &temp_path); + gdb::unique_xmalloc_ptr<char> full_path (temp_path); if (fd == -1) - { - int save_errno = errno; - do_cleanups (old_cleanups); - errno = save_errno; - return 0; - } - - do_cleanups (old_cleanups); + return opened; - *streamp = fdopen (fd, FOPEN_RT); - if (*streamp == NULL) + FILE *result = fdopen (fd, FOPEN_RT); + if (result == NULL) { int save_errno = errno; close (fd); - if (full_pathp) - xfree (*full_pathp); errno = save_errno; - return 0; } + else + opened.emplace (gdb_file_up (result), std::move (full_path)); - return 1; + return opened; } /* Load script FILE, which has already been opened as STREAM. @@ -596,14 +597,12 @@ source_script_from_stream (FILE *stream, const char *file, static void source_script_with_search (const char *file, int from_tty, int search_path) { - FILE *stream; - char *full_path; - struct cleanup *old_cleanups; if (file == NULL || *file == 0) error (_("source command requires file name of file to source.")); - if (!find_and_open_script (file, search_path, &stream, &full_path)) + gdb::optional<open_script> opened = find_and_open_script (file, search_path); + if (!opened) { /* The script wasn't found, or was otherwise inaccessible. If the source command was invoked interactively, throw an @@ -618,15 +617,13 @@ source_script_with_search (const char *file, int from_tty, int search_path) } } - old_cleanups = make_cleanup (xfree, full_path); - make_cleanup_fclose (stream); /* The python support reopens the file, so we need to pass full_path here in case the file was found on the search path. It's useful to do this anyway so that error messages show the actual file used. But only do this if we (may have) used search_path, as printing the full path in errors for the non-search case can be more noise than signal. */ - source_script_from_stream (stream, file, search_path ? full_path : file); - do_cleanups (old_cleanups); + source_script_from_stream (opened->stream.get (), file, + search_path ? opened->full_path.get () : file); } /* Wrapper around source_script_with_search to export it to main.c @@ -638,26 +635,14 @@ source_script (const char *file, int from_tty) source_script_with_search (file, from_tty, 0); } -/* Return the source_verbose global variable to its previous state - on exit from the source command, by whatever means. */ -static void -source_verbose_cleanup (void *old_value) -{ - source_verbose = *(int *)old_value; - xfree (old_value); -} - static void source_command (char *args, int from_tty) { - struct cleanup *old_cleanups; char *file = args; int *old_source_verbose = XNEW (int); int search_path = 0; - *old_source_verbose = source_verbose; - old_cleanups = make_cleanup (source_verbose_cleanup, - old_source_verbose); + scoped_restore save_source_verbose = make_scoped_restore (&source_verbose); /* -v causes the source command to run in verbose mode. -s causes the file to be searched in the source search path, @@ -698,8 +683,6 @@ source_command (char *args, int from_tty) } source_script_with_search (file, from_tty, search_path); - - do_cleanups (old_cleanups); } @@ -1407,31 +1390,27 @@ alias_command (char *args, int from_tty) { int i, alias_argc, command_argc; int abbrev_flag = 0; - char *args2, *equals; + char *equals; const char *alias, *command; - char **alias_argv, **command_argv; - struct cleanup *cleanup; if (args == NULL || strchr (args, '=') == NULL) alias_usage_error (); - args2 = xstrdup (args); - cleanup = make_cleanup (xfree, args2); - equals = strchr (args2, '='); - *equals = '\0'; - alias_argv = gdb_buildargv (args2); - make_cleanup_freeargv (alias_argv); - command_argv = gdb_buildargv (equals + 1); - make_cleanup_freeargv (command_argv); + equals = strchr (args, '='); + std::string args2 (args, equals - args); + + gdb_argv built_alias_argv (args2.c_str ()); + gdb_argv command_argv (equals + 1); - for (i = 0; alias_argv[i] != NULL; ) + char **alias_argv = built_alias_argv.get (); + while (alias_argv[0] != NULL) { - if (strcmp (alias_argv[i], "-a") == 0) + if (strcmp (alias_argv[0], "-a") == 0) { ++alias_argv; abbrev_flag = 1; } - else if (strcmp (alias_argv[i], "--") == 0) + else if (strcmp (alias_argv[0], "--") == 0) { ++alias_argv; break; @@ -1456,12 +1435,13 @@ alias_command (char *args, int from_tty) } alias_argc = countargv (alias_argv); - command_argc = countargv (command_argv); + command_argc = command_argv.count (); /* COMMAND must exist. Reconstruct the command to remove any extraneous spaces, for better error messages. */ - std::string command_string (argv_to_string (command_argv, command_argc)); + std::string command_string (argv_to_string (command_argv.get (), + command_argc)); command = command_string.c_str (); if (! valid_command_p (command)) error (_("Invalid command to alias to: %s"), command); @@ -1518,8 +1498,6 @@ alias_command (char *args, int from_tty) command_argv[command_argc - 1], class_alias, abbrev_flag, c_command->prefixlist); } - - do_cleanups (cleanup); } /* Print a list of files and line numbers which a user may choose from diff --git a/gdb/cli/cli-cmds.h b/gdb/cli/cli-cmds.h index 7ff1fca..1122a97 100644 --- a/gdb/cli/cli-cmds.h +++ b/gdb/cli/cli-cmds.h @@ -17,6 +17,9 @@ #if !defined (CLI_CMDS_H) #define CLI_CMDS_H 1 +#include "common/filestuff.h" +#include "common/gdb_optional.h" + /* Chain containing all defined commands. */ extern struct cmd_list_element *cmdlist; @@ -117,8 +120,22 @@ extern void source_script (const char *, int); /* Exported to objfiles.c. */ -extern int find_and_open_script (const char *file, int search_path, - FILE **streamp, char **full_path); +/* The script that was opened. */ +struct open_script +{ + gdb_file_up stream; + gdb::unique_xmalloc_ptr<char> full_path; + + open_script (gdb_file_up &&stream_, + gdb::unique_xmalloc_ptr<char> &&full_path_) + : stream (std::move (stream_)), + full_path (std::move (full_path_)) + { + } +}; + +extern gdb::optional<open_script> + find_and_open_script (const char *file, int search_path); /* Command tracing state. */ diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c index 383adf8..1bbbe46 100644 --- a/gdb/cli/cli-decode.c +++ b/gdb/cli/cli-decode.c @@ -166,9 +166,9 @@ set_cmd_completer (struct cmd_list_element *cmd, completer_ftype *completer) void set_cmd_completer_handle_brkchars (struct cmd_list_element *cmd, - completer_ftype_void *completer_handle_brkchars) + completer_handle_brkchars_ftype *func) { - cmd->completer_handle_brkchars = completer_handle_brkchars; + cmd->completer_handle_brkchars = func; } /* Add element named NAME. @@ -244,7 +244,7 @@ add_cmd (const char *name, enum command_class theclass, cmd_cfunc_ftype *fun, c->allow_unknown = 0; c->prefix = NULL; c->abbrev_flag = 0; - set_cmd_completer (c, make_symbol_completion_list_fn); + set_cmd_completer (c, symbol_completer); c->completer_handle_brkchars = NULL; c->destroyer = NULL; c->type = not_set_cmd; @@ -657,8 +657,9 @@ add_setshow_optional_filename_cmd (const char *name, enum command_class theclass /* Completes on literal "unlimited". Used by integer commands that support a special "unlimited" value. */ -static VEC (char_ptr) * +static void integer_unlimited_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, const char *text, const char *word) { static const char * const keywords[] = @@ -667,7 +668,7 @@ integer_unlimited_completer (struct cmd_list_element *ignore, NULL, }; - return complete_on_enum (keywords, text, word); + complete_on_enum (tracker, keywords, text, word); } /* Add element named NAME to both the set and show command LISTs (the @@ -1771,13 +1772,13 @@ lookup_cmd_composition (const char *text, "foo" and we want to complete to "foobar". If WORD is "oo", return "oobar"; if WORD is "baz/foo", return "baz/foobar". */ -VEC (char_ptr) * +void complete_on_cmdlist (struct cmd_list_element *list, + completion_tracker &tracker, const char *text, const char *word, int ignore_help_classes) { struct cmd_list_element *ptr; - VEC (char_ptr) *matchlist = NULL; int textlen = strlen (text); int pass; int saw_deprecated_match = 0; @@ -1786,8 +1787,10 @@ complete_on_cmdlist (struct cmd_list_element *list, commands. If we see no matching commands in the first pass, and if we did happen to see a matching deprecated command, we do another loop to collect those. */ - for (pass = 0; matchlist == 0 && pass < 2; ++pass) + for (pass = 0; pass < 2; ++pass) { + bool got_matches = false; + for (ptr = list; ptr; ptr = ptr->next) if (!strncmp (ptr->name, text, textlen) && !ptr->abbrev_flag @@ -1820,32 +1823,34 @@ complete_on_cmdlist (struct cmd_list_element *list, match[text - word] = '\0'; strcat (match, ptr->name); } - VEC_safe_push (char_ptr, matchlist, match); + tracker.add_completion (gdb::unique_xmalloc_ptr<char> (match)); + got_matches = true; } + + if (got_matches) + break; + /* If we saw no matching deprecated commands in the first pass, just bail out. */ if (!saw_deprecated_match) break; } - - return matchlist; } /* Helper function for SYMBOL_COMPLETION_FUNCTION. */ -/* Return a vector of char pointers which point to the different - possible completions in CMD of TEXT. +/* Add the different possible completions in ENUMLIST of TEXT. WORD points in the same buffer as TEXT, and completions should be returned relative to this position. For example, suppose TEXT is "foo" and we want to complete to "foobar". If WORD is "oo", return "oobar"; if WORD is "baz/foo", return "baz/foobar". */ -VEC (char_ptr) * -complete_on_enum (const char *const *enumlist, +void +complete_on_enum (completion_tracker &tracker, + const char *const *enumlist, const char *text, const char *word) { - VEC (char_ptr) *matchlist = NULL; int textlen = strlen (text); int i; const char *name; @@ -1870,10 +1875,8 @@ complete_on_enum (const char *const *enumlist, match[text - word] = '\0'; strcat (match, name); } - VEC_safe_push (char_ptr, matchlist, match); + tracker.add_completion (gdb::unique_xmalloc_ptr<char> (match)); } - - return matchlist; } diff --git a/gdb/cli/cli-decode.h b/gdb/cli/cli-decode.h index 11248ba..50b858c 100644 --- a/gdb/cli/cli-decode.h +++ b/gdb/cli/cli-decode.h @@ -160,19 +160,7 @@ struct cmd_list_element /* The prefix command of this command. */ struct cmd_list_element *prefix; - /* Completion routine for this command. TEXT is the text beyond - what was matched for the command itself (leading whitespace is - skipped). It stops where we are supposed to stop completing - (rl_point) and is '\0' terminated. - - Return value is a malloc'd vector of pointers to possible - completions terminated with NULL. If there are no completions, - returning a pointer to a NULL would work but returning NULL - itself is also valid. WORD points in the same buffer as TEXT, - and completions should be returned relative to this position. - For example, suppose TEXT is "foo" and we want to complete to - "foobar". If WORD is "oo", return "oobar"; if WORD is - "baz/foo", return "baz/foobar". */ + /* Completion routine for this command. */ completer_ftype *completer; /* Handle the word break characters for this completer. Usually @@ -181,8 +169,7 @@ struct cmd_list_element a class) the word break chars may need to be redefined depending on the completer type (e.g., for filename completers). */ - - completer_ftype_void *completer_handle_brkchars; + completer_handle_brkchars_ftype *completer_handle_brkchars; /* Destruction routine for this command. If non-NULL, this is called when this command instance is destroyed. This may be diff --git a/gdb/cli/cli-dump.c b/gdb/cli/cli-dump.c index d6d4aab..30897d8 100644 --- a/gdb/cli/cli-dump.c +++ b/gdb/cli/cli-dump.c @@ -33,16 +33,11 @@ #include "filestuff.h" #include "common/byte-vector.h" -static const char * -scan_expression_with_cleanup (const char **cmd, const char *def) +static gdb::unique_xmalloc_ptr<char> +scan_expression (const char **cmd, const char *def) { if ((*cmd) == NULL || (**cmd) == '\0') - { - char *exp = xstrdup (def); - - make_cleanup (xfree, exp); - return exp; - } + return gdb::unique_xmalloc_ptr<char> (xstrdup (def)); else { char *exp; @@ -50,17 +45,16 @@ scan_expression_with_cleanup (const char **cmd, const char *def) end = (*cmd) + strcspn (*cmd, " \t"); exp = savestring ((*cmd), end - (*cmd)); - make_cleanup (xfree, exp); (*cmd) = skip_spaces_const (end); - return exp; + return gdb::unique_xmalloc_ptr<char> (exp); } } -static char * -scan_filename_with_cleanup (const char **cmd, const char *defname) +static gdb::unique_xmalloc_ptr<char> +scan_filename (const char **cmd, const char *defname) { - char *filename; + gdb::unique_xmalloc_ptr<char> filename; char *fullname; /* FIXME: Need to get the ``/a(ppend)'' flag from somewhere. */ @@ -70,8 +64,7 @@ scan_filename_with_cleanup (const char **cmd, const char *defname) { if (defname == NULL) error (_("Missing filename.")); - filename = xstrdup (defname); - make_cleanup (xfree, filename); + filename.reset (xstrdup (defname)); } else { @@ -80,27 +73,12 @@ scan_filename_with_cleanup (const char **cmd, const char *defname) (*cmd) = skip_spaces_const (*cmd); end = *cmd + strcspn (*cmd, " \t"); - filename = savestring ((*cmd), end - (*cmd)); - make_cleanup (xfree, filename); + filename.reset (savestring ((*cmd), end - (*cmd))); (*cmd) = skip_spaces_const (end); } gdb_assert (filename != NULL); - fullname = tilde_expand (filename); - make_cleanup (xfree, fullname); - - return fullname; -} - -static FILE * -fopen_with_cleanup (const char *filename, const char *mode) -{ - FILE *file = gdb_fopen_cloexec (filename, mode); - - if (file == NULL) - perror_with_name (filename); - make_cleanup_fclose (file); - return file; + return gdb::unique_xmalloc_ptr<char> (tilde_expand (filename.get ())); } static gdb_bfd_ref_ptr @@ -168,11 +146,10 @@ static void dump_binary_file (const char *filename, const char *mode, const bfd_byte *buf, ULONGEST len) { - FILE *file; int status; - file = fopen_with_cleanup (filename, mode); - status = fwrite (buf, len, 1, file); + gdb_file_up file = gdb_fopen_cloexec (filename, mode); + status = fwrite (buf, len, 1, file.get ()); if (status != 1) perror_with_name (filename); } @@ -201,28 +178,25 @@ dump_bfd_file (const char *filename, const char *mode, static void dump_memory_to_file (const char *cmd, const char *mode, const char *file_format) { - struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL); CORE_ADDR lo; CORE_ADDR hi; ULONGEST count; - const char *filename; - const char *lo_exp; const char *hi_exp; /* Open the file. */ - filename = scan_filename_with_cleanup (&cmd, NULL); + gdb::unique_xmalloc_ptr<char> filename = scan_filename (&cmd, NULL); /* Find the low address. */ if (cmd == NULL || *cmd == '\0') error (_("Missing start address.")); - lo_exp = scan_expression_with_cleanup (&cmd, NULL); + gdb::unique_xmalloc_ptr<char> lo_exp = scan_expression (&cmd, NULL); /* Find the second address - rest of line. */ if (cmd == NULL || *cmd == '\0') error (_("Missing stop address.")); hi_exp = cmd; - lo = parse_and_eval_address (lo_exp); + lo = parse_and_eval_address (lo_exp.get ()); hi = parse_and_eval_address (hi_exp); if (hi <= lo) error (_("Invalid memory address range (start >= end).")); @@ -235,15 +209,9 @@ dump_memory_to_file (const char *cmd, const char *mode, const char *file_format) /* Have everything. Open/write the data. */ if (file_format == NULL || strcmp (file_format, "binary") == 0) - { - dump_binary_file (filename, mode, buf.data (), count); - } + dump_binary_file (filename.get (), mode, buf.data (), count); else - { - dump_bfd_file (filename, mode, file_format, lo, buf.data (), count); - } - - do_cleanups (old_cleanups); + dump_bfd_file (filename.get (), mode, file_format, lo, buf.data (), count); } static void @@ -255,12 +223,10 @@ dump_memory_command (char *cmd, const char *mode) static void dump_value_to_file (const char *cmd, const char *mode, const char *file_format) { - struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL); struct value *val; - const char *filename; /* Open the file. */ - filename = scan_filename_with_cleanup (&cmd, NULL); + gdb::unique_xmalloc_ptr<char> filename = scan_filename (&cmd, NULL); /* Find the value. */ if (cmd == NULL || *cmd == '\0') @@ -271,10 +237,8 @@ dump_value_to_file (const char *cmd, const char *mode, const char *file_format) /* Have everything. Open/write the data. */ if (file_format == NULL || strcmp (file_format, "binary") == 0) - { - dump_binary_file (filename, mode, value_contents (val), - TYPE_LENGTH (value_type (val))); - } + dump_binary_file (filename.get (), mode, value_contents (val), + TYPE_LENGTH (value_type (val))); else { CORE_ADDR vaddr; @@ -289,12 +253,10 @@ dump_value_to_file (const char *cmd, const char *mode, const char *file_format) warning (_("value is not an lval: address assumed to be zero")); } - dump_bfd_file (filename, mode, file_format, vaddr, + dump_bfd_file (filename.get (), mode, file_format, vaddr, value_contents (val), TYPE_LENGTH (value_type (val))); } - - do_cleanups (old_cleanups); } static void @@ -446,8 +408,6 @@ restore_section_callback (bfd *ibfd, asection *isec, void *args) bfd_vma sec_end = sec_start + size; bfd_size_type sec_offset = 0; bfd_size_type sec_load_count = size; - struct cleanup *old_chain; - gdb_byte *buf; int ret; /* Ignore non-loadable sections, eg. from elf files. */ @@ -475,9 +435,8 @@ restore_section_callback (bfd *ibfd, asection *isec, void *args) sec_load_count -= sec_end - data->load_end; /* Get the data. */ - buf = (gdb_byte *) xmalloc (size); - old_chain = make_cleanup (xfree, buf); - if (!bfd_get_section_contents (ibfd, isec, buf, 0, size)) + gdb::byte_vector buf (size); + if (!bfd_get_section_contents (ibfd, isec, buf.data (), 0, size)) error (_("Failed to read bfd file %s: '%s'."), bfd_get_filename (ibfd), bfd_errmsg (bfd_get_error ())); @@ -499,24 +458,21 @@ restore_section_callback (bfd *ibfd, asection *isec, void *args) /* Write the data. */ ret = target_write_memory (sec_start + sec_offset + data->load_offset, - buf + sec_offset, sec_load_count); + &buf[sec_offset], sec_load_count); if (ret != 0) warning (_("restore: memory write failed (%s)."), safe_strerror (ret)); - do_cleanups (old_chain); - return; } static void restore_binary_file (const char *filename, struct callback_data *data) { - struct cleanup *cleanup = make_cleanup (null_cleanup, NULL); - FILE *file = fopen_with_cleanup (filename, FOPEN_RB); + gdb_file_up file = gdb_fopen_cloexec (filename, FOPEN_RB); long len; /* Get the file size for reading. */ - if (fseek (file, 0, SEEK_END) == 0) + if (fseek (file.get (), 0, SEEK_END) == 0) { - len = ftell (file); + len = ftell (file.get ()); if (len < 0) perror_with_name (filename); } @@ -541,12 +497,12 @@ restore_binary_file (const char *filename, struct callback_data *data) (unsigned long) (data->load_start + data->load_offset + len)); /* Now set the file pos to the requested load start pos. */ - if (fseek (file, data->load_start, SEEK_SET) != 0) + if (fseek (file.get (), data->load_start, SEEK_SET) != 0) perror_with_name (filename); /* Now allocate a buffer and read the file contents. */ gdb::byte_vector buf (len); - if (fread (buf.data (), 1, len, file) != len) + if (fread (buf.data (), 1, len, file.get ()) != len) perror_with_name (filename); /* Now write the buffer into target memory. */ @@ -554,13 +510,11 @@ restore_binary_file (const char *filename, struct callback_data *data) buf.data (), len); if (len != 0) warning (_("restore: memory write failed (%s)."), safe_strerror (len)); - do_cleanups (cleanup); } static void restore_command (char *args_in, int from_tty) { - char *filename; struct callback_data data; bfd *ibfd; int binary_flag = 0; @@ -574,7 +528,7 @@ restore_command (char *args_in, int from_tty) data.load_end = 0; /* Parse the input arguments. First is filename (required). */ - filename = scan_filename_with_cleanup (&args, NULL); + gdb::unique_xmalloc_ptr<char> filename = scan_filename (&args, NULL); if (args != NULL && *args != '\0') { static const char binary_string[] = "binary"; @@ -589,13 +543,13 @@ restore_command (char *args_in, int from_tty) /* Parse offset (optional). */ if (args != NULL && *args != '\0') data.load_offset = binary_flag ? - parse_and_eval_address (scan_expression_with_cleanup (&args, NULL)) : - parse_and_eval_long (scan_expression_with_cleanup (&args, NULL)); + parse_and_eval_address (scan_expression (&args, NULL).get ()) : + parse_and_eval_long (scan_expression (&args, NULL).get ()); if (args != NULL && *args != '\0') { /* Parse start address (optional). */ data.load_start = - parse_and_eval_long (scan_expression_with_cleanup (&args, NULL)); + parse_and_eval_long (scan_expression (&args, NULL).get ()); if (args != NULL && *args != '\0') { /* Parse end address (optional). */ @@ -608,18 +562,18 @@ restore_command (char *args_in, int from_tty) if (info_verbose) printf_filtered ("Restore file %s offset 0x%lx start 0x%lx end 0x%lx\n", - filename, (unsigned long) data.load_offset, + filename.get (), (unsigned long) data.load_offset, (unsigned long) data.load_start, (unsigned long) data.load_end); if (binary_flag) { - restore_binary_file (filename, &data); + restore_binary_file (filename.get (), &data); } else { /* Open the file for loading. */ - gdb_bfd_ref_ptr ibfd (bfd_openr_or_error (filename, NULL)); + gdb_bfd_ref_ptr ibfd (bfd_openr_or_error (filename.get (), NULL)); /* Process the sections. */ bfd_map_over_sections (ibfd.get (), restore_section_callback, &data); diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c index e0e27ef..4b8ae0b 100644 --- a/gdb/cli/cli-script.c +++ b/gdb/cli/cli-script.c @@ -372,26 +372,12 @@ execute_cmd_post_hook (struct cmd_list_element *c) } } -/* Execute the command in CMD. */ -static void -do_restore_user_call_depth (void * call_depth) -{ - int *depth = (int *) call_depth; - - (*depth)--; - if ((*depth) == 0) - in_user_command = 0; -} - - void execute_user_command (struct cmd_list_element *c, char *args) { struct ui *ui = current_ui; struct command_line *cmdlines; - struct cleanup *old_chain; enum command_control_type ret; - static int user_call_depth = 0; extern unsigned int max_user_call_depth; cmdlines = c->user_commands; @@ -401,23 +387,18 @@ execute_user_command (struct cmd_list_element *c, char *args) scoped_user_args_level push_user_args (args); - if (++user_call_depth > max_user_call_depth) + if (user_args_stack.size () > max_user_call_depth) error (_("Max user call depth exceeded -- command aborted.")); - old_chain = make_cleanup (do_restore_user_call_depth, &user_call_depth); - /* Set the instream to 0, indicating execution of a user-defined function. */ - make_cleanup (do_restore_instream_cleanup, ui->instream); - ui->instream = NULL; - - /* Also set the global in_user_command, so that NULL instream is - not confused with Insight. */ - in_user_command = 1; + scoped_restore restore_instream + = make_scoped_restore (&ui->instream, nullptr); scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0); - command_nest_depth++; + scoped_restore save_nesting + = make_scoped_restore (&command_nest_depth, command_nest_depth + 1); while (cmdlines) { ret = execute_control_command (cmdlines); @@ -428,8 +409,6 @@ execute_user_command (struct cmd_list_element *c, char *args) } cmdlines = cmdlines->next; } - command_nest_depth--; - do_cleanups (old_chain); } /* This function is called every time GDB prints a prompt. It ensures @@ -548,9 +527,9 @@ execute_control_command (struct command_line *cmd) current = *cmd->body_list; while (current) { - command_nest_depth++; + scoped_restore save_nesting + = make_scoped_restore (&command_nest_depth, command_nest_depth + 1); ret = execute_control_command (current); - command_nest_depth--; /* If we got an error, or a "break" command, then stop looping. */ @@ -607,9 +586,9 @@ execute_control_command (struct command_line *cmd) /* Execute commands in the given arm. */ while (current) { - command_nest_depth++; + scoped_restore save_nesting + = make_scoped_restore (&command_nest_depth, command_nest_depth + 1); ret = execute_control_command (current); - command_nest_depth--; /* If we got an error, get out. */ if (ret != simple_control) @@ -952,6 +931,8 @@ process_next_line (char *p, struct command_line **command, int parse_commands, const char *cmd_name = p; struct cmd_list_element *cmd = lookup_cmd_1 (&cmd_name, cmdlist, NULL, 1); + cmd_name = skip_spaces_const (cmd_name); + bool inline_cmd = *cmd_name != '\0'; /* If commands are parsed, we skip initial spaces. Otherwise, which is the case for Python commands and documentation @@ -997,21 +978,20 @@ process_next_line (char *p, struct command_line **command, int parse_commands, { *command = build_command_line (commands_control, line_first_arg (p)); } - else if (command_name_equals (cmd, "python")) + else if (command_name_equals (cmd, "python") && !inline_cmd) { /* Note that we ignore the inline "python command" form here. */ *command = build_command_line (python_control, ""); } - else if (command_name_equals (cmd, "compile")) + else if (command_name_equals (cmd, "compile") && !inline_cmd) { /* Note that we ignore the inline "compile command" form here. */ *command = build_command_line (compile_control, ""); (*command)->control_u.compile.scope = COMPILE_I_INVALID_SCOPE; } - - else if (command_name_equals (cmd, "guile")) + else if (command_name_equals (cmd, "guile") && !inline_cmd) { /* Note that we ignore the inline "guile command" form here. */ *command = build_command_line (guile_control, ""); @@ -1584,58 +1564,34 @@ document_command (char *comname, int from_tty) } } -struct source_cleanup_lines_args -{ - int old_line; - const char *old_file; -}; - -static void -source_cleanup_lines (void *args) -{ - struct source_cleanup_lines_args *p = - (struct source_cleanup_lines_args *) args; - - source_line_number = p->old_line; - source_file_name = p->old_file; -} - /* Used to implement source_command. */ void script_from_file (FILE *stream, const char *file) { - struct cleanup *old_cleanups; - struct source_cleanup_lines_args old_lines; - if (stream == NULL) internal_error (__FILE__, __LINE__, _("called with NULL file pointer!")); - old_lines.old_line = source_line_number; - old_lines.old_file = source_file_name; - old_cleanups = make_cleanup (source_cleanup_lines, &old_lines); - source_line_number = 0; - source_file_name = file; - - { - scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0); + scoped_restore restore_line_number + = make_scoped_restore (&source_line_number, 0); + scoped_restore resotre_file + = make_scoped_restore (&source_file_name, file); - TRY - { - read_command_file (stream); - } - CATCH (e, RETURN_MASK_ERROR) - { - /* Re-throw the error, but with the file name information - prepended. */ - throw_error (e.error, - _("%s:%d: Error in sourced command file:\n%s"), - source_file_name, source_line_number, e.message); - } - END_CATCH - } + scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0); - do_cleanups (old_cleanups); + TRY + { + read_command_file (stream); + } + CATCH (e, RETURN_MASK_ERROR) + { + /* Re-throw the error, but with the file name information + prepended. */ + throw_error (e.error, + _("%s:%d: Error in sourced command file:\n%s"), + source_file_name, source_line_number, e.message); + } + END_CATCH } /* Print the definition of user command C to STREAM. Or, if C is a diff --git a/gdb/command.h b/gdb/command.h index aa179e9..3a4a449 100644 --- a/gdb/command.h +++ b/gdb/command.h @@ -19,6 +19,9 @@ #define COMMAND_H 1 #include "gdb_vecs.h" +#include "common/scoped_restore.h" + +struct completion_tracker; /* This file defines the public interface for any code wanting to create commands. */ @@ -173,18 +176,30 @@ typedef void cmd_sfunc_ftype (char *args, int from_tty, extern void set_cmd_sfunc (struct cmd_list_element *cmd, cmd_sfunc_ftype *sfunc); -typedef VEC (char_ptr) *completer_ftype (struct cmd_list_element *, - const char *, const char *); +/* A completion routine. Add possible completions to tracker. + + TEXT is the text beyond what was matched for the command itself + (leading whitespace is skipped). It stops where we are supposed to + stop completing (rl_point) and is '\0' terminated. WORD points in + the same buffer as TEXT, and completions should be returned + relative to this position. For example, suppose TEXT is "foo" and + we want to complete to "foobar". If WORD is "oo", return "oobar"; + if WORD is "baz/foo", return "baz/foobar". */ +typedef void completer_ftype (struct cmd_list_element *, + completion_tracker &tracker, + const char *text, const char *word); -typedef void completer_ftype_void (struct cmd_list_element *, - const char *, const char *); +/* Same, but for set_cmd_completer_handle_brkchars. */ +typedef void completer_handle_brkchars_ftype (struct cmd_list_element *, + completion_tracker &tracker, + const char *text, const char *word); extern void set_cmd_completer (struct cmd_list_element *, completer_ftype *); /* Set the completer_handle_brkchars callback. */ extern void set_cmd_completer_handle_brkchars (struct cmd_list_element *, - completer_ftype_void *); + completer_handle_brkchars_ftype *); /* HACK: cagney/2002-02-23: Code, mostly in tracepoints.c, grubs around in cmd objects to test the value of the commands sfunc(). */ @@ -248,11 +263,13 @@ extern struct cmd_list_element *add_info (const char *, extern struct cmd_list_element *add_info_alias (const char *, const char *, int); -extern VEC (char_ptr) *complete_on_cmdlist (struct cmd_list_element *, - const char *, const char *, int); +extern void complete_on_cmdlist (struct cmd_list_element *, + completion_tracker &tracker, + const char *, const char *, int); -extern VEC (char_ptr) *complete_on_enum (const char *const *enumlist, - const char *, const char *); +extern void complete_on_enum (completion_tracker &tracker, + const char *const *enumlist, + const char *, const char *); /* Functions that implement commands about CLI commands. */ diff --git a/gdb/common/buffer.h b/gdb/common/buffer.h index 2432a06..90535ca 100644 --- a/gdb/common/buffer.h +++ b/gdb/common/buffer.h @@ -46,7 +46,7 @@ void buffer_free (struct buffer *buffer); /* Initialize BUFFER. BUFFER holds no memory afterwards. */ void buffer_init (struct buffer *buffer); -/* Return a pointer into BUFFER data, effectivelly transfering +/* Return a pointer into BUFFER data, effectively transferring ownership of the buffer memory to the caller. Calling buffer_free afterwards has no effect on the returned data. */ char* buffer_finish (struct buffer *buffer); diff --git a/gdb/common/filestuff.c b/gdb/common/filestuff.c index 725fb92..4b05884 100644 --- a/gdb/common/filestuff.c +++ b/gdb/common/filestuff.c @@ -300,7 +300,7 @@ gdb_open_cloexec (const char *filename, int flags, unsigned long mode) /* See filestuff.h. */ -FILE * +gdb_file_up gdb_fopen_cloexec (const char *filename, const char *opentype) { FILE *result; @@ -336,7 +336,7 @@ gdb_fopen_cloexec (const char *filename, const char *opentype) if (result != NULL) maybe_mark_cloexec (fileno (result)); - return result; + return gdb_file_up (result); } #ifdef HAVE_SOCKETS diff --git a/gdb/common/filestuff.h b/gdb/common/filestuff.h index b0a811b..3cf2df6 100644 --- a/gdb/common/filestuff.h +++ b/gdb/common/filestuff.h @@ -46,10 +46,23 @@ extern void close_most_fds (void); extern int gdb_open_cloexec (const char *filename, int flags, /* mode_t */ unsigned long mode); +struct gdb_file_deleter +{ + void operator() (FILE *file) const + { + fclose (file); + } +}; + +/* A unique pointer to a FILE. */ + +typedef std::unique_ptr<FILE, gdb_file_deleter> gdb_file_up; + /* Like 'fopen', but ensures that the returned file descriptor has the close-on-exec flag set. */ -extern FILE *gdb_fopen_cloexec (const char *filename, const char *opentype); +extern gdb_file_up gdb_fopen_cloexec (const char *filename, + const char *opentype); /* Like 'socketpair', but ensures that the returned file descriptors have the close-on-exec flag set. */ diff --git a/gdb/common/gdb_unique_ptr.h b/gdb/common/gdb_unique_ptr.h index 4faadaf..34c993c 100644 --- a/gdb/common/gdb_unique_ptr.h +++ b/gdb/common/gdb_unique_ptr.h @@ -34,6 +34,13 @@ struct xfree_deleter void operator() (T *ptr) const { xfree (ptr); } }; +/* Same, for arrays. */ +template <typename T> +struct xfree_deleter<T[]> +{ + void operator() (T *ptr) const { xfree (ptr); } +}; + /* Import the standard unique_ptr to our namespace with a custom deleter. */ diff --git a/gdb/compile/compile-cplus-templates.c b/gdb/compile/compile-cplus-templates.c index 4b2bf46..b3d0794 100644 --- a/gdb/compile/compile-cplus-templates.c +++ b/gdb/compile/compile-cplus-templates.c @@ -591,12 +591,10 @@ print_conversion_node (const struct demangle_component *comp, case DEMANGLE_COMPONENT_QUAL_NAME: { /* Print out the qualified name. */ - struct cleanup *back_to; - char *ret = cp_comp_to_string (d_left (comp), 10); + gdb::unique_xmalloc_ptr<char> ret + = cp_comp_to_string (d_left (comp), 10); - back_to = make_cleanup (xfree, ret); - fprintf_unfiltered (stream, "%s::", ret); - do_cleanups (back_to); + fprintf_unfiltered (stream, "%s::", ret.get ()); /* Follow the rest of the name. */ comp = d_right (comp); diff --git a/gdb/compile/compile-loc2c.c b/gdb/compile/compile-loc2c.c index 856d4c2..d5a2555 100644 --- a/gdb/compile/compile-loc2c.c +++ b/gdb/compile/compile-loc2c.c @@ -723,6 +723,7 @@ do_compile_dwarf_expr_to_c (int indent, string_file &stream, break; case DW_OP_addr: + uoffset = extract_unsigned_integer (op_ptr, addr_size, byte_order); op_ptr += addr_size; /* Some versions of GCC emit DW_OP_addr before DW_OP_GNU_push_tls_address. In this case the value is an diff --git a/gdb/compile/compile-object-load.c b/gdb/compile/compile-object-load.c index fd6661c..b5431d8 100644 --- a/gdb/compile/compile-object-load.c +++ b/gdb/compile/compile-object-load.c @@ -624,44 +624,45 @@ compile_object_load (const compile_file_names &file_names, unsigned dptr_type_len = TYPE_LENGTH (dptr_type); struct compile_module *retval; struct type *regs_type, *out_value_type = NULL; - char *filename, **matching; + char **matching; struct objfile *objfile; int expect_parameters; struct type *expect_return_type; struct munmap_list *munmap_list_head = NULL; - filename = tilde_expand (file_names.object_file ()); - cleanups = make_cleanup (xfree, filename); + gdb::unique_xmalloc_ptr<char> filename + (tilde_expand (file_names.object_file ())); - gdb_bfd_ref_ptr abfd (gdb_bfd_open (filename, gnutarget, -1)); + gdb_bfd_ref_ptr abfd (gdb_bfd_open (filename.get (), gnutarget, -1)); if (abfd == NULL) error (_("\"%s\": could not open as compiled module: %s"), - filename, bfd_errmsg (bfd_get_error ())); + filename.get (), bfd_errmsg (bfd_get_error ())); if (!bfd_check_format_matches (abfd.get (), bfd_object, &matching)) error (_("\"%s\": not in loadable format: %s"), - filename, gdb_bfd_errmsg (bfd_get_error (), matching)); + filename.get (), gdb_bfd_errmsg (bfd_get_error (), matching)); if ((bfd_get_file_flags (abfd.get ()) & (EXEC_P | DYNAMIC)) != 0) - error (_("\"%s\": not in object format."), filename); + error (_("\"%s\": not in object format."), filename.get ()); setup_sections_data.last_size = 0; setup_sections_data.last_section_first = abfd->sections; setup_sections_data.last_prot = -1; setup_sections_data.last_max_alignment = 1; setup_sections_data.munmap_list_headp = &munmap_list_head; - make_cleanup (munmap_listp_free_cleanup, &munmap_list_head); + cleanups = make_cleanup (munmap_listp_free_cleanup, &munmap_list_head); bfd_map_over_sections (abfd.get (), setup_sections, &setup_sections_data); setup_sections (abfd.get (), NULL, &setup_sections_data); storage_needed = bfd_get_symtab_upper_bound (abfd.get ()); if (storage_needed < 0) error (_("Cannot read symbols of compiled module \"%s\": %s"), - filename, bfd_errmsg (bfd_get_error ())); + filename.get (), bfd_errmsg (bfd_get_error ())); /* SYMFILE_VERBOSE is not passed even if FROM_TTY, user is not interested in "Reading symbols from ..." message for automatically generated file. */ - objfile = symbol_file_add_from_bfd (abfd.get (), filename, 0, NULL, 0, NULL); + objfile = symbol_file_add_from_bfd (abfd.get (), filename.get (), + 0, NULL, 0, NULL); cleanups_free_objfile = make_cleanup_free_objfile (objfile); func_sym = lookup_global_symbol_from_objfile (objfile, @@ -713,7 +714,7 @@ compile_object_load (const compile_file_names &file_names, number_of_symbols = bfd_canonicalize_symtab (abfd.get (), symbol_table); if (number_of_symbols < 0) error (_("Cannot parse symbols of compiled module \"%s\": %s"), - filename, bfd_errmsg (bfd_get_error ())); + filename.get (), bfd_errmsg (bfd_get_error ())); missing_symbols = 0; for (symp = symbol_table; symp < symbol_table + number_of_symbols; symp++) @@ -764,7 +765,7 @@ compile_object_load (const compile_file_names &file_names, default: warning (_("Could not find symbol \"%s\" " "for compiled module \"%s\"."), - sym->name, filename); + sym->name, filename.get ()); missing_symbols++; } } diff --git a/gdb/compile/compile.c b/gdb/compile/compile.c index 74ffa64..7c8fe15 100644 --- a/gdb/compile/compile.c +++ b/gdb/compile/compile.c @@ -39,6 +39,8 @@ #include "osabi.h" #include "gdb_wait.h" #include "valprint.h" +#include "common/gdb_optional.h" +#include "common/gdb_unlinker.h" @@ -283,15 +285,17 @@ get_expr_block_and_pc (CORE_ADDR *pc) return block; } -/* Call gdb_buildargv, set its result for S into *ARGVP but calculate also the - number of parsed arguments into *ARGCP. If gdb_buildargv has returned NULL - then *ARGCP is set to zero. */ +/* Call buildargv (via gdb_argv), set its result for S into *ARGVP but + calculate also the number of parsed arguments into *ARGCP. If + buildargv has returned NULL then *ARGCP is set to zero. */ static void build_argc_argv (const char *s, int *argcp, char ***argvp) { - *argvp = gdb_buildargv (s); - *argcp = countargv (*argvp); + gdb_argv args (s); + + *argcp = args.count (); + *argvp = args.release (); } /* String for 'set compile-args' and 'show compile-args'. */ @@ -457,16 +461,6 @@ cleanup_compile_instance (void *arg) delete inst; } -/* A cleanup function to unlink a file. */ - -static void -cleanup_unlink_file (void *arg) -{ - const char *filename = (const char *) arg; - - unlink (filename); -} - /* A helper function suitable for use as the "print_callback" in the compiler object. */ @@ -485,7 +479,7 @@ compile_to_object (struct command_line *cmd, const char *cmd_string, enum compile_i_scope_types scope) { compile::compile_instance *compiler; - struct cleanup *cleanup, *inner_cleanup; + struct cleanup *cleanup; const struct block *expr_block; CORE_ADDR trash_pc, expr_pc; int argc; @@ -569,7 +563,7 @@ compile_to_object (struct command_line *cmd, const char *cmd_string, /* Set compiler command-line arguments. */ get_args (compiler, gdbarch, &argc, &argv); - make_cleanup_freeargv (argv); + gdb_argv argv_holder (argv); if (compiler->version ()>= GCC_FE_VERSION_1) error_message = compiler->set_arguments (argc, argv); @@ -593,14 +587,18 @@ compile_to_object (struct command_line *cmd, const char *cmd_string, compile_file_names fnames = get_new_file_names (); - src = gdb_fopen_cloexec (fnames.source_file (), "w"); - if (src == NULL) - perror_with_name (_("Could not open source file for writing")); - inner_cleanup = make_cleanup (cleanup_unlink_file, - (void *) fnames.source_file ()); - if (fputs (code.c_str (), src) == EOF) - perror_with_name (_("Could not write to source file")); - fclose (src); + gdb::optional<gdb::unlinker> source_remover; + + { + gdb_file_up src = gdb_fopen_cloexec (fnames.source_file (), "w"); + if (src == NULL) + perror_with_name (_("Could not open source file for writing")); + + source_remover.emplace (fnames.source_file ()); + + if (fputs (code.c_str (), src.get ()) == EOF) + perror_with_name (_("Could not write to source file")); + } if (compile_debug) fprintf_unfiltered (gdb_stdlog, "source file produced: %s\n\n", @@ -620,7 +618,9 @@ compile_to_object (struct command_line *cmd, const char *cmd_string, fprintf_unfiltered (gdb_stdlog, "object file produced: %s\n\n", fnames.object_file ()); - discard_cleanups (inner_cleanup); + /* Keep the source file. */ + source_remover->keep (); + do_cleanups (cleanup); return fnames; @@ -642,14 +642,13 @@ void eval_compile_command (struct command_line *cmd, const char *cmd_string, enum compile_i_scope_types scope, void *scope_data) { - struct cleanup *cleanup_unlink; struct compile_module *compile_module; compile_file_names fnames = compile_to_object (cmd, cmd_string, scope); - cleanup_unlink = make_cleanup (cleanup_unlink_file, - (void *) fnames.object_file ()); - make_cleanup (cleanup_unlink_file, (void *) fnames.source_file ()); + gdb::unlinker object_remover (fnames.object_file ()); + gdb::unlinker source_remover (fnames.source_file ()); + compile_module = compile_object_load (fnames, scope, scope_data); if (compile_module == NULL) { @@ -658,7 +657,11 @@ eval_compile_command (struct command_line *cmd, const char *cmd_string, COMPILE_I_PRINT_VALUE_SCOPE, scope_data); return; } - discard_cleanups (cleanup_unlink); + + /* Keep the files. */ + source_remover.keep (); + object_remover.keep (); + compile_object_run (compile_module); } diff --git a/gdb/completer.c b/gdb/completer.c index 6acf115..a029263 100644 --- a/gdb/completer.c +++ b/gdb/completer.c @@ -28,7 +28,8 @@ #include "user-regs.h" #include "arch-utils.h" #include "location.h" - +#include <algorithm> +#include "linespec.h" #include "cli/cli-decode.h" /* FIXME: This is needed because of lookup_cmd_1 (). We should be @@ -44,8 +45,28 @@ #include "completer.h" -/* An enumeration of the various things a user might - attempt to complete for a location. */ +/* Misc state that needs to be tracked across several different + readline completer entry point calls, all related to a single + completion invocation. */ + +struct gdb_completer_state +{ + /* The current completion's completion tracker. This is a global + because a tracker can be shared between the handle_brkchars and + handle_completion phases, which involves different readline + callbacks. */ + completion_tracker *tracker = NULL; + + /* Whether the current completion was aborted. */ + bool aborted = false; +}; + +/* The current completion state. */ +static gdb_completer_state current_completion; + +/* An enumeration of the various things a user might attempt to + complete for a location. If you change this, remember to update + the explicit_options array below too. */ enum explicit_location_match_type { @@ -55,15 +76,14 @@ enum explicit_location_match_type /* The name of a function or method. */ MATCH_FUNCTION, + /* A line number. */ + MATCH_LINE, + /* The name of a label. */ MATCH_LABEL }; /* Prototypes for local functions. */ -static -char *line_completion_function (const char *text, int matches, - char *line_buffer, - int point); /* readline uses the word breaks for two things: (1) In figuring out where to point the TEXT parameter to the @@ -113,27 +133,21 @@ get_gdb_completer_quote_characters (void) return gdb_completer_quote_characters; } -/* Line completion interface function for readline. */ - -char * -readline_line_completion_function (const char *text, int matches) -{ - return line_completion_function (text, matches, - rl_line_buffer, rl_point); -} - /* This can be used for functions which don't want to complete on symbols but don't want to complete on anything else either. */ -VEC (char_ptr) * + +void noop_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, const char *text, const char *prefix) { - return NULL; } /* Complete on filenames. */ -VEC (char_ptr) * -filename_completer (struct cmd_list_element *ignore, + +void +filename_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, const char *text, const char *word) { int subsequent_name; @@ -179,7 +193,7 @@ filename_completer (struct cmd_list_element *ignore, strcat (q, p); xfree (p); } - VEC_safe_push (char_ptr, return_val, q); + tracker.add_completion (gdb::unique_xmalloc_ptr<char> (q)); } #if 0 /* There is no way to do this just long enough to affect quote @@ -189,7 +203,214 @@ filename_completer (struct cmd_list_element *ignore, with respect to inserting quotes. */ rl_completer_word_break_characters = ""; #endif - return return_val; +} + +/* The corresponding completer_handle_brkchars + implementation. */ + +static void +filename_completer_handle_brkchars (struct cmd_list_element *ignore, + completion_tracker &tracker, + const char *text, const char *word) +{ + set_rl_completer_word_break_characters + (gdb_completer_file_name_break_characters); +} + +/* Possible values for the found_quote flags word used by the completion + functions. It says what kind of (shell-like) quoting we found anywhere + in the line. */ +#define RL_QF_SINGLE_QUOTE 0x01 +#define RL_QF_DOUBLE_QUOTE 0x02 +#define RL_QF_BACKSLASH 0x04 +#define RL_QF_OTHER_QUOTE 0x08 + +/* Find the bounds of the current word for completion purposes, and + return a pointer to the end of the word. This mimics (and is a + modified version of) readline's _rl_find_completion_word internal + function. + + This function skips quoted substrings (characters between matched + pairs of characters in rl_completer_quote_characters). We try to + find an unclosed quoted substring on which to do matching. If one + is not found, we use the word break characters to find the + boundaries of the current word. QC, if non-null, is set to the + opening quote character if we found an unclosed quoted substring, + '\0' otherwise. DP, if non-null, is set to the value of the + delimiter character that caused a word break. */ + +struct gdb_rl_completion_word_info +{ + const char *word_break_characters; + const char *quote_characters; + const char *basic_quote_characters; +}; + +static const char * +gdb_rl_find_completion_word (struct gdb_rl_completion_word_info *info, + int *qc, int *dp, + const char *line_buffer) +{ + int scan, end, found_quote, delimiter, pass_next, isbrk; + char quote_char; + const char *brkchars; + int point = strlen (line_buffer); + + /* The algorithm below does '--point'. Avoid buffer underflow with + the empty string. */ + if (point == 0) + { + if (qc != NULL) + *qc = '\0'; + if (dp != NULL) + *dp = '\0'; + return line_buffer; + } + + end = point; + found_quote = delimiter = 0; + quote_char = '\0'; + + brkchars = info->word_break_characters; + + if (info->quote_characters != NULL) + { + /* We have a list of characters which can be used in pairs to + quote substrings for the completer. Try to find the start of + an unclosed quoted substring. */ + /* FOUND_QUOTE is set so we know what kind of quotes we + found. */ + for (scan = pass_next = 0; + scan < end; + scan++) + { + if (pass_next) + { + pass_next = 0; + continue; + } + + /* Shell-like semantics for single quotes -- don't allow + backslash to quote anything in single quotes, especially + not the closing quote. If you don't like this, take out + the check on the value of quote_char. */ + if (quote_char != '\'' && line_buffer[scan] == '\\') + { + pass_next = 1; + found_quote |= RL_QF_BACKSLASH; + continue; + } + + if (quote_char != '\0') + { + /* Ignore everything until the matching close quote + char. */ + if (line_buffer[scan] == quote_char) + { + /* Found matching close. Abandon this + substring. */ + quote_char = '\0'; + point = end; + } + } + else if (strchr (info->quote_characters, line_buffer[scan])) + { + /* Found start of a quoted substring. */ + quote_char = line_buffer[scan]; + point = scan + 1; + /* Shell-like quoting conventions. */ + if (quote_char == '\'') + found_quote |= RL_QF_SINGLE_QUOTE; + else if (quote_char == '"') + found_quote |= RL_QF_DOUBLE_QUOTE; + else + found_quote |= RL_QF_OTHER_QUOTE; + } + } + } + + if (point == end && quote_char == '\0') + { + /* We didn't find an unclosed quoted substring upon which to do + completion, so use the word break characters to find the + substring on which to complete. */ + while (--point) + { + scan = line_buffer[point]; + + if (strchr (brkchars, scan) != 0) + break; + } + } + + /* If we are at an unquoted word break, then advance past it. */ + scan = line_buffer[point]; + + if (scan) + { + isbrk = strchr (brkchars, scan) != 0; + + if (isbrk) + { + /* If the character that caused the word break was a quoting + character, then remember it as the delimiter. */ + if (info->basic_quote_characters + && strchr (info->basic_quote_characters, scan) + && (end - point) > 1) + delimiter = scan; + + point++; + } + } + + if (qc != NULL) + *qc = quote_char; + if (dp != NULL) + *dp = delimiter; + + return line_buffer + point; +} + +/* See completer.h. */ + +const char * +advance_to_expression_complete_word_point (completion_tracker &tracker, + const char *text) +{ + gdb_rl_completion_word_info info; + + info.word_break_characters + = current_language->la_word_break_characters (); + info.quote_characters = gdb_completer_quote_characters; + info.basic_quote_characters = rl_basic_quote_characters; + + const char *start + = gdb_rl_find_completion_word (&info, NULL, NULL, text); + + tracker.advance_custom_word_point_by (start - text); + + return start; +} + +/* See completer.h. */ + +bool +completion_tracker::completes_to_completion_word (const char *word) +{ + if (m_lowest_common_denominator_unique) + { + const char *lcd = m_lowest_common_denominator; + + if (strncmp_iw (word, lcd, strlen (lcd)) == 0) + { + /* Maybe skip the function and complete on keywords. */ + size_t wordlen = strlen (word); + if (word[wordlen - 1] == ' ') + return true; + } + } + + return false; } /* Complete on linespecs, which might be of two possible forms: @@ -201,13 +422,12 @@ filename_completer (struct cmd_list_element *ignore, This is intended to be used in commands that set breakpoints etc. */ -static VEC (char_ptr) * -linespec_location_completer (struct cmd_list_element *ignore, - const char *text, const char *word) +static void +complete_files_symbols (completion_tracker &tracker, + const char *text, const char *word) { - int n_syms, n_files, ix; - VEC (char_ptr) *fn_list = NULL; - VEC (char_ptr) *list = NULL; + int ix; + completion_list fn_list; const char *p; int quote_found = 0; int quoted = *text == '\'' || *text == '"'; @@ -216,7 +436,6 @@ linespec_location_completer (struct cmd_list_element *ignore, char *file_to_match = NULL; const char *symbol_start = text; const char *orig_text = text; - size_t text_len; /* Do we have an unquoted colon, as in "break foo.c:bar"? */ for (p = text; *p != '\0'; ++p) @@ -257,7 +476,6 @@ linespec_location_completer (struct cmd_list_element *ignore, if (quoted) text++; - text_len = strlen (text); /* Where is the file name? */ if (colon) @@ -279,44 +497,27 @@ linespec_location_completer (struct cmd_list_element *ignore, symbols as well as on files. */ if (colon) { - list = make_file_symbol_completion_list (symbol_start, word, - file_to_match); + collect_file_symbol_completion_matches (tracker, + complete_symbol_mode::EXPRESSION, + symbol_start, word, + file_to_match); xfree (file_to_match); } else { - list = make_symbol_completion_list (symbol_start, word); + size_t text_len = strlen (text); + + collect_symbol_completion_matches (tracker, + complete_symbol_mode::EXPRESSION, + symbol_start, word); /* If text includes characters which cannot appear in a file name, they cannot be asking for completion on files. */ - if (strcspn (text, + if (strcspn (text, gdb_completer_file_name_break_characters) == text_len) fn_list = make_source_files_completion_list (text, text); } - n_syms = VEC_length (char_ptr, list); - n_files = VEC_length (char_ptr, fn_list); - - /* Catenate fn_list[] onto the end of list[]. */ - if (!n_syms) - { - VEC_free (char_ptr, list); /* Paranoia. */ - list = fn_list; - fn_list = NULL; - } - else - { - char *fn; - - for (ix = 0; VEC_iterate (char_ptr, fn_list, ix, fn); ++ix) - VEC_safe_push (char_ptr, list, fn); - VEC_free (char_ptr, fn_list); - } - - if (n_syms && n_files) - { - /* Nothing. */ - } - else if (n_files) + if (!fn_list.empty () && !tracker.have_completions ()) { char *fn; @@ -335,201 +536,422 @@ linespec_location_completer (struct cmd_list_element *ignore, completion, because rl_complete will prepend "/foo/" to each candidate completion. The loop below removes that leading part. */ - for (ix = 0; VEC_iterate (char_ptr, list, ix, fn); ++ix) + for (const auto &fn_up: fn_list) { - memmove (fn, fn + (word - text), - strlen (fn) + 1 - (word - text)); + char *fn = fn_up.get (); + memmove (fn, fn + (word - text), strlen (fn) + 1 - (word - text)); } } - else if (!n_syms) + + tracker.add_completions (std::move (fn_list)); + + if (!tracker.have_completions ()) { /* No completions at all. As the final resort, try completing on the entire text as a symbol. */ - list = make_symbol_completion_list (orig_text, word); + collect_symbol_completion_matches (tracker, + complete_symbol_mode::EXPRESSION, + orig_text, word); + } +} + +/* See completer.h. */ + +completion_list +complete_source_filenames (const char *text) +{ + size_t text_len = strlen (text); + + /* If text includes characters which cannot appear in a file name, + the user cannot be asking for completion on files. */ + if (strcspn (text, + gdb_completer_file_name_break_characters) + == text_len) + return make_source_files_completion_list (text, text); + + return {}; +} + +/* Complete address and linespec locations. */ + +static void +complete_address_and_linespec_locations (completion_tracker &tracker, + const char *text) +{ + if (*text == '*') + { + tracker.advance_custom_word_point_by (1); + text++; + const char *word + = advance_to_expression_complete_word_point (tracker, text); + complete_expression (tracker, text, word); + } + else + { + linespec_complete (tracker, text); } +} + +/* The explicit location options. Note that indexes into this array + must match the explicit_location_match_type enumerators. */ + +static const char *const explicit_options[] = + { + "-source", + "-function", + "-line", + "-label", + NULL + }; + +/* The probe modifier options. These can appear before a location in + breakpoint commands. */ +static const char *const probe_options[] = + { + "-probe", + "-probe-stap", + "-probe-dtrace", + NULL + }; + +/* Returns STRING if not NULL, the empty string otherwise. */ - return list; +static const char * +string_or_empty (const char *string) +{ + return string != NULL ? string : ""; } /* A helper function to collect explicit location matches for the given LOCATION, which is attempting to match on WORD. */ -static VEC (char_ptr) * -collect_explicit_location_matches (struct event_location *location, +static void +collect_explicit_location_matches (completion_tracker &tracker, + struct event_location *location, enum explicit_location_match_type what, - const char *word) + const char *word, + const struct language_defn *language) { - VEC (char_ptr) *matches = NULL; const struct explicit_location *explicit_loc = get_explicit_location (location); + /* Note, in the various MATCH_* below, we complete on + explicit_loc->foo instead of WORD, because only the former will + have already skipped past any quote char. */ switch (what) { case MATCH_SOURCE: { - const char *text = (explicit_loc->source_filename == NULL - ? "" : explicit_loc->source_filename); - - matches = make_source_files_completion_list (text, word); + const char *source = string_or_empty (explicit_loc->source_filename); + completion_list matches + = make_source_files_completion_list (source, source); + tracker.add_completions (std::move (matches)); } break; case MATCH_FUNCTION: { - const char *text = (explicit_loc->function_name == NULL - ? "" : explicit_loc->function_name); - - if (explicit_loc->source_filename != NULL) - { - const char *filename = explicit_loc->source_filename; - - matches = make_file_symbol_completion_list (text, word, filename); - } - else - matches = make_symbol_completion_list (text, word); + const char *function = string_or_empty (explicit_loc->function_name); + linespec_complete_function (tracker, function, + explicit_loc->source_filename); } break; + case MATCH_LINE: + /* Nothing to offer. */ + break; + case MATCH_LABEL: - /* Not supported. */ + { + const char *label = string_or_empty (explicit_loc->label_name); + linespec_complete_label (tracker, language, + explicit_loc->source_filename, + explicit_loc->function_name, + label); + } break; default: gdb_assert_not_reached ("unhandled explicit_location_match_type"); } - return matches; -} - -/* A convenience macro to (safely) back up P to the previous word. */ + if (tracker.completes_to_completion_word (word)) + { + tracker.discard_completions (); + tracker.advance_custom_word_point_by (strlen (word)); + complete_on_enum (tracker, explicit_options, "", ""); + complete_on_enum (tracker, linespec_keywords, "", ""); + } + else if (!tracker.have_completions ()) + { + /* Maybe we have an unterminated linespec keyword at the tail of + the string. Try completing on that. */ + size_t wordlen = strlen (word); + const char *keyword = word + wordlen; -static const char * -backup_text_ptr (const char *p, const char *text) -{ - while (p > text && isspace (*p)) - --p; - for (; p > text && !isspace (p[-1]); --p) - ; + if (wordlen > 0 && keyword[-1] != ' ') + { + while (keyword > word && *keyword != ' ') + keyword--; + /* Don't complete on keywords if we'd be completing on the + whole explicit linespec option. E.g., "b -function + thr<tab>" should not complete to the "thread" + keyword. */ + if (keyword != word) + { + keyword = skip_spaces_const (keyword); - return p; + tracker.advance_custom_word_point_by (keyword - word); + complete_on_enum (tracker, linespec_keywords, keyword, keyword); + } + } + else if (wordlen > 0 && keyword[-1] == ' ') + { + /* Assume that we're maybe past the explicit location + argument, and we didn't manage to find any match because + the user wants to create a pending breakpoint. Offer the + keyword and explicit location options as possible + completions. */ + tracker.advance_custom_word_point_by (keyword - word); + complete_on_enum (tracker, linespec_keywords, keyword, keyword); + complete_on_enum (tracker, explicit_options, keyword, keyword); + } + } } -/* A completer function for explicit locations. This function - completes both options ("-source", "-line", etc) and values. */ +/* If the next word in *TEXT_P is any of the keywords in KEYWORDS, + then advance both TEXT_P and the word point in the tracker past the + keyword and return the (0-based) index in the KEYWORDS array that + matched. Otherwise, return -1. */ -static VEC (char_ptr) * -explicit_location_completer (struct cmd_list_element *ignore, - struct event_location *location, - const char *text, const char *word) +static int +skip_keyword (completion_tracker &tracker, + const char * const *keywords, const char **text_p) { - const char *p; - VEC (char_ptr) *matches = NULL; + const char *text = *text_p; + const char *after = skip_to_space_const (text); + size_t len = after - text; - /* Find the beginning of the word. This is necessary because - we need to know if we are completing an option name or value. We - don't get the leading '-' from the completer. */ - p = backup_text_ptr (word, text); + if (text[len] != ' ') + return -1; - if (*p == '-') + int found = -1; + for (int i = 0; keywords[i] != NULL; i++) { - /* Completing on option name. */ - static const char *const keywords[] = + if (strncmp (keywords[i], text, len) == 0) { - "source", - "function", - "line", - "label", - NULL - }; - - /* Skip over the '-'. */ - ++p; + if (found == -1) + found = i; + else + return -1; + } + } - return complete_on_enum (keywords, p, p); + if (found != -1) + { + tracker.advance_custom_word_point_by (len + 1); + text += len + 1; + *text_p = text; + return found; } + + return -1; +} + +/* A completer function for explicit locations. This function + completes both options ("-source", "-line", etc) and values. If + completing a quoted string, then QUOTED_ARG_START and + QUOTED_ARG_END point to the quote characters. LANGUAGE is the + current language. */ + +static void +complete_explicit_location (completion_tracker &tracker, + struct event_location *location, + const char *text, + const language_defn *language, + const char *quoted_arg_start, + const char *quoted_arg_end) +{ + if (*text != '-') + return; + + int keyword = skip_keyword (tracker, explicit_options, &text); + + if (keyword == -1) + complete_on_enum (tracker, explicit_options, text, text); else { - /* Completing on value (or unknown). Get the previous word to see what - the user is completing on. */ - size_t len, offset; - const char *new_word, *end; - enum explicit_location_match_type what; - struct explicit_location *explicit_loc - = get_explicit_location (location); - - /* Backup P to the previous word, which should be the option - the user is attempting to complete. */ - offset = word - p; - end = --p; - p = backup_text_ptr (p, text); - len = end - p; - - if (strncmp (p, "-source", len) == 0) - { - what = MATCH_SOURCE; - new_word = explicit_loc->source_filename + offset; - } - else if (strncmp (p, "-function", len) == 0) - { - what = MATCH_FUNCTION; - new_word = explicit_loc->function_name + offset; - } - else if (strncmp (p, "-label", len) == 0) - { - what = MATCH_LABEL; - new_word = explicit_loc->label_name + offset; - } - else + /* Completing on value. */ + enum explicit_location_match_type what + = (explicit_location_match_type) keyword; + + if (quoted_arg_start != NULL && quoted_arg_end != NULL) { - /* The user isn't completing on any valid option name, - e.g., "break -source foo.c [tab]". */ - return NULL; + if (quoted_arg_end[1] == '\0') + { + /* If completing a quoted string with the cursor right + at the terminating quote char, complete the + completion word without interpretation, so that + readline advances the cursor one whitespace past the + quote, even if there's no match. This makes these + cases behave the same: + + before: "b -function function()" + after: "b -function function() " + + before: "b -function 'function()'" + after: "b -function 'function()' " + + and trusts the user in this case: + + before: "b -function 'not_loaded_function_yet()'" + after: "b -function 'not_loaded_function_yet()' " + */ + gdb::unique_xmalloc_ptr<char> text_copy + (xstrdup (text)); + tracker.add_completion (std::move (text_copy)); + } + else if (quoted_arg_end[1] == ' ') + { + /* We're maybe past the explicit location argument. + Skip the argument without interpretion, assuming the + user may want to create pending breakpoint. Offer + the keyword and explicit location options as possible + completions. */ + tracker.advance_custom_word_point_by (strlen (text)); + complete_on_enum (tracker, linespec_keywords, "", ""); + complete_on_enum (tracker, explicit_options, "", ""); + } + return; } - /* If the user hasn't entered a search expression, e.g., - "break -function <TAB><TAB>", new_word will be NULL, but - search routines require non-NULL search words. */ - if (new_word == NULL) - new_word = ""; - /* Now gather matches */ - matches = collect_explicit_location_matches (location, what, new_word); + collect_explicit_location_matches (tracker, location, what, text, + language); } - - return matches; } /* A completer for locations. */ -VEC (char_ptr) * +void location_completer (struct cmd_list_element *ignore, - const char *text, const char *word) + completion_tracker &tracker, + const char *text, const char * /* word */) { - VEC (char_ptr) *matches = NULL; + int found_probe_option = -1; + + /* If we have a probe modifier, skip it. This can only appear as + first argument. Until we have a specific completer for probes, + falling back to the linespec completer for the remainder of the + line is better than nothing. */ + if (text[0] == '-' && text[1] == 'p') + found_probe_option = skip_keyword (tracker, probe_options, &text); + + const char *option_text = text; + int saved_word_point = tracker.custom_word_point (); + const char *copy = text; - event_location_up location = string_to_explicit_location (©, - current_language, - 1); + explicit_completion_info completion_info; + event_location_up location + = string_to_explicit_location (©, current_language, + &completion_info); + if (completion_info.quoted_arg_start != NULL + && completion_info.quoted_arg_end == NULL) + { + /* Found an unbalanced quote. */ + tracker.set_quote_char (*completion_info.quoted_arg_start); + tracker.advance_custom_word_point_by (1); + } + if (location != NULL) - matches = explicit_location_completer (ignore, location.get (), - text, word); + { + if (*copy != '\0') + { + tracker.advance_custom_word_point_by (copy - text); + text = copy; + + /* We found a terminator at the tail end of the string, + which means we're past the explicit location options. We + may have a keyword to complete on. If we have a whole + keyword, then complete whatever comes after as an + expression. This is mainly for the "if" keyword. If the + "thread" and "task" keywords gain their own completers, + they should be used here. */ + int keyword = skip_keyword (tracker, linespec_keywords, &text); + + if (keyword == -1) + { + complete_on_enum (tracker, linespec_keywords, text, text); + } + else + { + const char *word + = advance_to_expression_complete_word_point (tracker, text); + complete_expression (tracker, text, word); + } + } + else + { + tracker.advance_custom_word_point_by (completion_info.last_option + - text); + text = completion_info.last_option; + + complete_explicit_location (tracker, location.get (), text, + current_language, + completion_info.quoted_arg_start, + completion_info.quoted_arg_end); + + } + } else { - /* This is an address or linespec location. - Right now both of these are handled by the (old) linespec - completer. */ - matches = linespec_location_completer (ignore, text, word); + /* This is an address or linespec location. */ + complete_address_and_linespec_locations (tracker, text); } - return matches; + /* Add matches for option names, if either: + + - Some completer above found some matches, but the word point did + not advance (e.g., "b <tab>" finds all functions, or "b -<tab>" + matches all objc selectors), or; + + - Some completer above advanced the word point, but found no + matches. + */ + if ((text[0] == '-' || text[0] == '\0') + && (!tracker.have_completions () + || tracker.custom_word_point () == saved_word_point)) + { + tracker.set_custom_word_point (saved_word_point); + text = option_text; + + if (found_probe_option == -1) + complete_on_enum (tracker, probe_options, text, text); + complete_on_enum (tracker, explicit_options, text, text); + } +} + +/* The corresponding completer_handle_brkchars + implementation. */ + +static void +location_completer_handle_brkchars (struct cmd_list_element *ignore, + completion_tracker &tracker, + const char *text, + const char *word_ignored) +{ + tracker.set_use_custom_word_point (true); + + location_completer (ignore, tracker, text, NULL); } /* Helper for expression_completer which recursively adds field and - method names from TYPE, a struct or union type, to the array - OUTPUT. */ + method names from TYPE, a struct or union type, to the OUTPUT + list. */ + static void -add_struct_fields (struct type *type, VEC (char_ptr) **output, +add_struct_fields (struct type *type, completion_list &output, char *fieldname, int namelen) { int i; @@ -548,8 +970,7 @@ add_struct_fields (struct type *type, VEC (char_ptr) **output, { if (! strncmp (TYPE_FIELD_NAME (type, i), fieldname, namelen)) - VEC_safe_push (char_ptr, *output, - xstrdup (TYPE_FIELD_NAME (type, i))); + output.emplace_back (xstrdup (TYPE_FIELD_NAME (type, i))); } else if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_UNION) { @@ -573,21 +994,19 @@ add_struct_fields (struct type *type, VEC (char_ptr) **output, } /* Omit constructors from the completion list. */ if (!type_name || strcmp (type_name, name)) - VEC_safe_push (char_ptr, *output, xstrdup (name)); + output.emplace_back (xstrdup (name)); } } } -/* Complete on expressions. Often this means completing on symbol - names, but some language parsers also have support for completing - field names. */ -VEC (char_ptr) * -expression_completer (struct cmd_list_element *ignore, - const char *text, const char *word) +/* See completer.h. */ + +void +complete_expression (completion_tracker &tracker, + const char *text, const char *word) { struct type *type = NULL; char *fieldname; - const char *p; enum type_code code = TYPE_CODE_UNDEF; /* Perform a tentative parse of the expression, to see whether a @@ -599,7 +1018,7 @@ expression_completer (struct cmd_list_element *ignore, } CATCH (except, RETURN_MASK_ERROR) { - return NULL; + return; } END_CATCH @@ -617,11 +1036,12 @@ expression_completer (struct cmd_list_element *ignore, || TYPE_CODE (type) == TYPE_CODE_STRUCT) { int flen = strlen (fieldname); - VEC (char_ptr) *result = NULL; + completion_list result; - add_struct_fields (type, &result, fieldname, flen); + add_struct_fields (type, result, fieldname, flen); xfree (fieldname); - return result; + tracker.add_completions (std::move (result)); + return; } } else if (fieldname && code != TYPE_CODE_UNDEF) @@ -629,21 +1049,26 @@ expression_completer (struct cmd_list_element *ignore, VEC (char_ptr) *result; struct cleanup *cleanup = make_cleanup (xfree, fieldname); - result = make_symbol_completion_type (fieldname, fieldname, code); + collect_symbol_completion_matches_type (tracker, fieldname, fieldname, + code); do_cleanups (cleanup); - return result; + return; } xfree (fieldname); - /* Commands which complete on locations want to see the entire - argument. */ - for (p = word; - p > text && p[-1] != ' ' && p[-1] != '\t'; - p--) - ; + complete_files_symbols (tracker, text, word); +} + +/* Complete on expressions. Often this means completing on symbol + names, but some language parsers also have support for completing + field names. */ - /* Not ideal but it is what we used to do before... */ - return location_completer (ignore, p, word); +void +expression_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, + const char *text, const char *word) +{ + complete_expression (tracker, text, word); } /* See definition in completer.h. */ @@ -671,6 +1096,17 @@ set_gdb_completion_word_break_characters (completer_ftype *fn) set_rl_completer_word_break_characters (break_chars); } +/* Complete on symbols. */ + +void +symbol_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, + const char *text, const char *word) +{ + collect_symbol_completion_matches (tracker, complete_symbol_mode::EXPRESSION, + text, word); +} + /* Here are some useful test cases for completion. FIXME: These should be put in the test suite. They should be tested with both M-? and TAB. @@ -694,14 +1130,84 @@ set_gdb_completion_word_break_characters (completer_ftype *fn) "file ../gdb.stabs/we" "ird" (needs to not break word at slash) */ -typedef enum +enum complete_line_internal_reason { + /* Preliminary phase, called by gdb_completion_word_break_characters + function, is used to either: + + #1 - Determine the set of chars that are word delimiters + depending on the current command in line_buffer. + + #2 - Manually advance RL_POINT to the "word break" point instead + of letting readline do it (based on too-simple character + matching). + + Simpler completers that just pass a brkchars array to readline + (#1 above) must defer generating the completions to the main + phase (below). No completion list should be generated in this + phase. + + OTOH, completers that manually advance the word point(#2 above) + must set "use_custom_word_point" in the tracker and generate + their completion in this phase. Note that this is the convenient + thing to do since they'll be parsing the input line anyway. */ handle_brkchars, + + /* Main phase, called by complete_line function, is used to get the + list of possible completions. */ handle_completions, - handle_help -} -complete_line_internal_reason; + /* Special case when completing a 'help' command. In this case, + once sub-command completions are exhausted, we simply return + NULL. */ + handle_help, +}; + +/* Helper for complete_line_internal to simplify it. */ + +static void +complete_line_internal_normal_command (completion_tracker &tracker, + const char *command, const char *word, + const char *cmd_args, + complete_line_internal_reason reason, + struct cmd_list_element *c) +{ + const char *p = cmd_args; + + if (c->completer == filename_completer) + { + /* Many commands which want to complete on file names accept + several file names, as in "run foo bar >>baz". So we don't + want to complete the entire text after the command, just the + last word. To this end, we need to find the beginning of the + file name by starting at `word' and going backwards. */ + for (p = word; + p > command + && strchr (gdb_completer_file_name_break_characters, + p[-1]) == NULL; + p--) + ; + } + + if (reason == handle_brkchars) + { + completer_handle_brkchars_ftype *brkchars_fn; + + if (c->completer_handle_brkchars != NULL) + brkchars_fn = c->completer_handle_brkchars; + else + { + brkchars_fn + = (completer_handle_brkchars_func_for_completer + (c->completer)); + } + + brkchars_fn (c, tracker, p, word); + } + + if (reason != handle_brkchars && c->completer != NULL) + (*c->completer) (c, tracker, p, word); +} /* Internal function used to handle completions. @@ -712,35 +1218,19 @@ complete_line_internal_reason; text of the line. POINT is the offset in that line of the cursor. You should pretend that the line ends at POINT. - REASON is of type complete_line_internal_reason. - - If REASON is handle_brkchars: - Preliminary phase, called by gdb_completion_word_break_characters - function, is used to determine the correct set of chars that are - word delimiters depending on the current command in line_buffer. - No completion list should be generated; the return value should be - NULL. This is checked by an assertion in that function. + See complete_line_internal_reason for description of REASON. */ - If REASON is handle_completions: - Main phase, called by complete_line function, is used to get the list - of posible completions. - - If REASON is handle_help: - Special case when completing a 'help' command. In this case, - once sub-command completions are exhausted, we simply return NULL. - */ - -static VEC (char_ptr) * -complete_line_internal (const char *text, - const char *line_buffer, int point, - complete_line_internal_reason reason) +static void +complete_line_internal_1 (completion_tracker &tracker, + const char *text, + const char *line_buffer, int point, + complete_line_internal_reason reason) { - VEC (char_ptr) *list = NULL; char *tmp_command; const char *p; int ignore_help_classes; /* Pointer within tmp_command which corresponds to text. */ - char *word; + const char *word; struct cmd_list_element *c, *result_list; /* Choose the default set of word break characters to break @@ -763,10 +1253,18 @@ complete_line_internal (const char *text, strncpy (tmp_command, line_buffer, point); tmp_command[point] = '\0'; - /* Since text always contains some number of characters leading up - to point, we can find the equivalent position in tmp_command - by subtracting that many characters from the end of tmp_command. */ - word = tmp_command + point - strlen (text); + if (reason == handle_brkchars) + { + gdb_assert (text == NULL); + word = NULL; + } + else + { + /* Since text always contains some number of characters leading up + to point, we can find the equivalent position in tmp_command + by subtracting that many characters from the end of tmp_command. */ + word = tmp_command + point - strlen (text); + } if (point == 0) { @@ -786,11 +1284,12 @@ complete_line_internal (const char *text, p++; } + tracker.advance_custom_word_point_by (p - tmp_command); + if (!c) { /* It is an unrecognized command. So there are no possible completions. */ - list = NULL; } else if (c == CMD_LIST_AMBIGUOUS) { @@ -808,7 +1307,6 @@ complete_line_internal (const char *text, example, "info t " or "info t foo" does not complete to anything, because "info t" can be "info target" or "info terminal". */ - list = NULL; } else { @@ -817,14 +1315,14 @@ complete_line_internal (const char *text, if (result_list) { if (reason != handle_brkchars) - list = complete_on_cmdlist (*result_list->prefixlist, p, - word, ignore_help_classes); + complete_on_cmdlist (*result_list->prefixlist, tracker, p, + word, ignore_help_classes); } else { if (reason != handle_brkchars) - list = complete_on_cmdlist (cmdlist, p, word, - ignore_help_classes); + complete_on_cmdlist (cmdlist, tracker, p, word, + ignore_help_classes); } /* Ensure that readline does the right thing with respect to inserting quotes. */ @@ -850,8 +1348,8 @@ complete_line_internal (const char *text, /* It is a prefix command; what comes after it is a subcommand (e.g. "info "). */ if (reason != handle_brkchars) - list = complete_on_cmdlist (*c->prefixlist, p, word, - ignore_help_classes); + complete_on_cmdlist (*c->prefixlist, tracker, p, word, + ignore_help_classes); /* Ensure that readline does the right thing with respect to inserting quotes. */ @@ -859,11 +1357,11 @@ complete_line_internal (const char *text, (gdb_completer_command_word_break_characters); } else if (reason == handle_help) - list = NULL; + ; else if (c->enums) { if (reason != handle_brkchars) - list = complete_on_enum (c->enums, p, word); + complete_on_enum (tracker, c->enums, p, word); set_rl_completer_word_break_characters (gdb_completer_command_word_break_characters); } @@ -871,29 +1369,9 @@ complete_line_internal (const char *text, { /* It is a normal command; what comes after it is completed by the command's completer function. */ - if (c->completer == filename_completer) - { - /* Many commands which want to complete on - file names accept several file names, as - in "run foo bar >>baz". So we don't want - to complete the entire text after the - command, just the last word. To this - end, we need to find the beginning of the - file name by starting at `word' and going - backwards. */ - for (p = word; - p > tmp_command - && strchr (gdb_completer_file_name_break_characters, p[-1]) == NULL; - p--) - ; - set_rl_completer_word_break_characters - (gdb_completer_file_name_break_characters); - } - if (reason == handle_brkchars - && c->completer_handle_brkchars != NULL) - (*c->completer_handle_brkchars) (c, p, word); - if (reason != handle_brkchars && c->completer != NULL) - list = (*c->completer) (c, p, word); + complete_line_internal_normal_command (tracker, + tmp_command, word, p, + reason, c); } } else @@ -915,8 +1393,8 @@ complete_line_internal (const char *text, } if (reason != handle_brkchars) - list = complete_on_cmdlist (result_list, q, word, - ignore_help_classes); + complete_on_cmdlist (result_list, tracker, q, word, + ignore_help_classes); /* Ensure that readline does the right thing with respect to inserting quotes. */ @@ -925,7 +1403,7 @@ complete_line_internal (const char *text, } } else if (reason == handle_help) - list = NULL; + ; else { /* There is non-whitespace beyond the command. */ @@ -934,120 +1412,133 @@ complete_line_internal (const char *text, { /* It is an unrecognized subcommand of a prefix command, e.g. "info adsfkdj". */ - list = NULL; } else if (c->enums) { if (reason != handle_brkchars) - list = complete_on_enum (c->enums, p, word); + complete_on_enum (tracker, c->enums, p, word); } else { /* It is a normal command. */ - if (c->completer == filename_completer) - { - /* See the commentary above about the specifics - of file-name completion. */ - for (p = word; - p > tmp_command - && strchr (gdb_completer_file_name_break_characters, - p[-1]) == NULL; - p--) - ; - set_rl_completer_word_break_characters - (gdb_completer_file_name_break_characters); - } - if (reason == handle_brkchars - && c->completer_handle_brkchars != NULL) - (*c->completer_handle_brkchars) (c, p, word); - if (reason != handle_brkchars && c->completer != NULL) - list = (*c->completer) (c, p, word); + complete_line_internal_normal_command (tracker, + tmp_command, word, p, + reason, c); } } } +} + +/* Wrapper around complete_line_internal_1 to handle + MAX_COMPLETIONS_REACHED_ERROR. */ - return list; +static void +complete_line_internal (completion_tracker &tracker, + const char *text, + const char *line_buffer, int point, + complete_line_internal_reason reason) +{ + TRY + { + complete_line_internal_1 (tracker, text, line_buffer, point, reason); + } + CATCH (except, RETURN_MASK_ERROR) + { + if (except.error != MAX_COMPLETIONS_REACHED_ERROR) + throw_exception (except); + } } /* See completer.h. */ int max_completions = 200; +/* Initial size of the table. It automagically grows from here. */ +#define INITIAL_COMPLETION_HTAB_SIZE 200 + /* See completer.h. */ -completion_tracker_t -new_completion_tracker (void) +completion_tracker::completion_tracker () { - if (max_completions <= 0) - return NULL; - - return htab_create_alloc (max_completions, - htab_hash_string, (htab_eq) streq, - NULL, xcalloc, xfree); + m_entries_hash = htab_create_alloc (INITIAL_COMPLETION_HTAB_SIZE, + htab_hash_string, (htab_eq) streq, + NULL, xcalloc, xfree); } -/* Cleanup routine to free a completion tracker and reset the pointer - to NULL. */ +/* See completer.h. */ -static void -free_completion_tracker (void *p) +void +completion_tracker::discard_completions () { - completion_tracker_t *tracker_ptr = (completion_tracker_t *) p; + xfree (m_lowest_common_denominator); + m_lowest_common_denominator = NULL; - htab_delete (*tracker_ptr); - *tracker_ptr = NULL; + m_lowest_common_denominator_unique = false; + + m_entries_vec.clear (); + + htab_delete (m_entries_hash); + m_entries_hash = htab_create_alloc (INITIAL_COMPLETION_HTAB_SIZE, + htab_hash_string, (htab_eq) streq, + NULL, xcalloc, xfree); } /* See completer.h. */ -struct cleanup * -make_cleanup_free_completion_tracker (completion_tracker_t *tracker_ptr) +completion_tracker::~completion_tracker () { - if (*tracker_ptr == NULL) - return make_cleanup (null_cleanup, NULL); - - return make_cleanup (free_completion_tracker, tracker_ptr); + xfree (m_lowest_common_denominator); + htab_delete (m_entries_hash); } /* See completer.h. */ -enum maybe_add_completion_enum -maybe_add_completion (completion_tracker_t tracker, char *name) +bool +completion_tracker::maybe_add_completion (gdb::unique_xmalloc_ptr<char> name) { void **slot; - if (max_completions < 0) - return MAYBE_ADD_COMPLETION_OK; if (max_completions == 0) - return MAYBE_ADD_COMPLETION_MAX_REACHED; + return false; + + if (htab_elements (m_entries_hash) >= max_completions) + return false; - gdb_assert (tracker != NULL); + slot = htab_find_slot (m_entries_hash, name.get (), INSERT); + if (*slot == HTAB_EMPTY_ENTRY) + { + const char *match_for_lcd_str = name.get (); - if (htab_elements (tracker) >= max_completions) - return MAYBE_ADD_COMPLETION_MAX_REACHED; + recompute_lowest_common_denominator (match_for_lcd_str); - slot = htab_find_slot (tracker, name, INSERT); + *slot = name.get (); + m_entries_vec.push_back (std::move (name)); + } - if (*slot != HTAB_EMPTY_ENTRY) - return MAYBE_ADD_COMPLETION_DUPLICATE; + return true; +} - *slot = name; +/* See completer.h. */ - return (htab_elements (tracker) < max_completions - ? MAYBE_ADD_COMPLETION_OK - : MAYBE_ADD_COMPLETION_OK_MAX_REACHED); +void +completion_tracker::add_completion (gdb::unique_xmalloc_ptr<char> name) +{ + if (!maybe_add_completion (std::move (name))) + throw_error (MAX_COMPLETIONS_REACHED_ERROR, _("Max completions reached.")); } +/* See completer.h. */ + void -throw_max_completions_reached_error (void) +completion_tracker::add_completions (completion_list &&list) { - throw_error (MAX_COMPLETIONS_REACHED_ERROR, _("Max completions reached.")); + for (auto &candidate : list) + add_completion (std::move (candidate)); } -/* Generate completions all at once. Returns a vector of unique strings - allocated with xmalloc. Returns NULL if there are no completions - or if max_completions is 0. If max_completions is non-negative, this will - return at most max_completions strings. +/* Generate completions all at once. Does nothing if max_completions + is 0. If max_completions is non-negative, this will collect at + most max_completions strings. TEXT is the caller's idea of the "word" we are looking at. @@ -1057,79 +1548,45 @@ throw_max_completions_reached_error (void) POINT is the offset in that line of the cursor. You should pretend that the line ends at POINT. */ -VEC (char_ptr) * -complete_line (const char *text, const char *line_buffer, int point) +void +complete_line (completion_tracker &tracker, + const char *text, const char *line_buffer, int point) { - VEC (char_ptr) *list; - VEC (char_ptr) *result = NULL; - struct cleanup *cleanups; - completion_tracker_t tracker; - char *candidate; - int ix, max_reached; - if (max_completions == 0) - return NULL; - list = complete_line_internal (text, line_buffer, point, - handle_completions); - if (max_completions < 0) - return list; - - tracker = new_completion_tracker (); - cleanups = make_cleanup_free_completion_tracker (&tracker); - make_cleanup_free_char_ptr_vec (list); - - /* Do a final test for too many completions. Individual completers may - do some of this, but are not required to. Duplicates are also removed - here. Otherwise the user is left scratching his/her head: readline and - complete_command will remove duplicates, and if removal of duplicates - there brings the total under max_completions the user may think gdb quit - searching too early. */ - - for (ix = 0, max_reached = 0; - !max_reached && VEC_iterate (char_ptr, list, ix, candidate); - ++ix) - { - enum maybe_add_completion_enum add_status; - - add_status = maybe_add_completion (tracker, candidate); - - switch (add_status) - { - case MAYBE_ADD_COMPLETION_OK: - VEC_safe_push (char_ptr, result, xstrdup (candidate)); - break; - case MAYBE_ADD_COMPLETION_OK_MAX_REACHED: - VEC_safe_push (char_ptr, result, xstrdup (candidate)); - max_reached = 1; - break; - case MAYBE_ADD_COMPLETION_MAX_REACHED: - gdb_assert_not_reached ("more than max completions reached"); - case MAYBE_ADD_COMPLETION_DUPLICATE: - break; - } - } - - do_cleanups (cleanups); - - return result; + return; + complete_line_internal (tracker, text, line_buffer, point, + handle_completions); } /* Complete on command names. Used by "help". */ -VEC (char_ptr) * + +void command_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, const char *text, const char *word) { - return complete_line_internal (word, text, - strlen (text), handle_help); + complete_line_internal (tracker, word, text, + strlen (text), handle_help); +} + +/* The corresponding completer_handle_brkchars implementation. */ + +static void +command_completer_handle_brkchars (struct cmd_list_element *ignore, + completion_tracker &tracker, + const char *text, const char *word) +{ + set_rl_completer_word_break_characters + (gdb_completer_command_word_break_characters); } /* Complete on signals. */ -VEC (char_ptr) * +void signal_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, const char *text, const char *word) { - VEC (char_ptr) *return_val = NULL; size_t len = strlen (word); int signum; const char *signame; @@ -1147,10 +1604,11 @@ signal_completer (struct cmd_list_element *ignore, continue; if (strncasecmp (signame, word, len) == 0) - VEC_safe_push (char_ptr, return_val, xstrdup (signame)); + { + gdb::unique_xmalloc_ptr<char> copy (xstrdup (signame)); + tracker.add_completion (std::move (copy)); + } } - - return return_val; } /* Bit-flags for selecting what the register and/or register-group @@ -1166,12 +1624,11 @@ DEF_ENUM_FLAGS_TYPE (enum reg_completer_target, reg_completer_targets); /* Complete register names and/or reggroup names based on the value passed in TARGETS. At least one bit in TARGETS must be set. */ -static VEC (char_ptr) * -reg_or_group_completer_1 (struct cmd_list_element *ignore, +static void +reg_or_group_completer_1 (completion_tracker &tracker, const char *text, const char *word, reg_completer_targets targets) { - VEC (char_ptr) *result = NULL; size_t len = strlen (word); struct gdbarch *gdbarch; const char *name; @@ -1189,7 +1646,10 @@ reg_or_group_completer_1 (struct cmd_list_element *ignore, i++) { if (*name != '\0' && strncmp (word, name, len) == 0) - VEC_safe_push (char_ptr, result, xstrdup (name)); + { + gdb::unique_xmalloc_ptr<char> copy (xstrdup (name)); + tracker.add_completion (std::move (copy)); + } } } @@ -1203,120 +1663,479 @@ reg_or_group_completer_1 (struct cmd_list_element *ignore, { name = reggroup_name (group); if (strncmp (word, name, len) == 0) - VEC_safe_push (char_ptr, result, xstrdup (name)); + { + gdb::unique_xmalloc_ptr<char> copy (xstrdup (name)); + tracker.add_completion (std::move (copy)); + } } } - - return result; } /* Perform completion on register and reggroup names. */ -VEC (char_ptr) * +void reg_or_group_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, const char *text, const char *word) { - return reg_or_group_completer_1 (ignore, text, word, - (complete_register_names - | complete_reggroup_names)); + reg_or_group_completer_1 (tracker, text, word, + (complete_register_names + | complete_reggroup_names)); } /* Perform completion on reggroup names. */ -VEC (char_ptr) * +void reggroup_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, const char *text, const char *word) { - return reg_or_group_completer_1 (ignore, text, word, - complete_reggroup_names); + reg_or_group_completer_1 (tracker, text, word, + complete_reggroup_names); +} + +/* The default completer_handle_brkchars implementation. */ + +static void +default_completer_handle_brkchars (struct cmd_list_element *ignore, + completion_tracker &tracker, + const char *text, const char *word) +{ + set_rl_completer_word_break_characters + (current_language->la_word_break_characters ()); +} + +/* See definition in completer.h. */ + +completer_handle_brkchars_ftype * +completer_handle_brkchars_func_for_completer (completer_ftype *fn) +{ + if (fn == filename_completer) + return filename_completer_handle_brkchars; + + if (fn == location_completer) + return location_completer_handle_brkchars; + + if (fn == command_completer) + return command_completer_handle_brkchars; + + return default_completer_handle_brkchars; } +/* Used as brkchars when we want to tell readline we have a custom + word point. We do that by making our rl_completion_word_break_hook + set RL_POINT to the desired word point, and return the character at + the word break point as the break char. This is two bytes in order + to fit one break character plus the terminating null. */ +static char gdb_custom_word_point_brkchars[2]; + +/* Since rl_basic_quote_characters is not completer-specific, we save + its original value here, in order to be able to restore it in + gdb_rl_attempted_completion_function. */ +static const char *gdb_org_rl_basic_quote_characters = rl_basic_quote_characters; + /* Get the list of chars that are considered as word breaks for the current command. */ -char * -gdb_completion_word_break_characters (void) +static char * +gdb_completion_word_break_characters_throw () { - VEC (char_ptr) *list; + /* New completion starting. Get rid of the previous tracker and + start afresh. */ + delete current_completion.tracker; + current_completion.tracker = new completion_tracker (); + + completion_tracker &tracker = *current_completion.tracker; + + complete_line_internal (tracker, NULL, rl_line_buffer, + rl_point, handle_brkchars); + + if (tracker.use_custom_word_point ()) + { + gdb_assert (tracker.custom_word_point () > 0); + rl_point = tracker.custom_word_point () - 1; + gdb_custom_word_point_brkchars[0] = rl_line_buffer[rl_point]; + rl_completer_word_break_characters = gdb_custom_word_point_brkchars; + rl_completer_quote_characters = NULL; + + /* Clear this too, so that if we're completing a quoted string, + readline doesn't consider the quote character a delimiter. + If we didn't do this, readline would auto-complete {b + 'fun<tab>} to {'b 'function()'}, i.e., add the terminating + \', but, it wouldn't append the separator space either, which + is not desirable. So instead we take care of appending the + quote character to the LCD ourselves, in + gdb_rl_attempted_completion_function. Since this global is + not just completer-specific, we'll restore it back to the + default in gdb_rl_attempted_completion_function. */ + rl_basic_quote_characters = NULL; + } - list = complete_line_internal (rl_line_buffer, rl_line_buffer, rl_point, - handle_brkchars); - gdb_assert (list == NULL); return rl_completer_word_break_characters; } -/* Generate completions one by one for the completer. Each time we - are called return another potential completion to the caller. - line_completion just completes on commands or passes the buck to - the command's completer function, the stuff specific to symbol - completion is in make_symbol_completion_list. - - TEXT is the caller's idea of the "word" we are looking at. +char * +gdb_completion_word_break_characters () +{ + /* New completion starting. */ + current_completion.aborted = false; - MATCHES is the number of matches that have currently been collected - from calling this completion function. When zero, then we need to - initialize, otherwise the initialization has already taken place - and we can just return the next potential completion string. + TRY + { + return gdb_completion_word_break_characters_throw (); + } + CATCH (ex, RETURN_MASK_ALL) + { + /* Set this to that gdb_rl_attempted_completion_function knows + to abort early. */ + current_completion.aborted = true; + } + END_CATCH - LINE_BUFFER is available to be looked at; it contains the entire - text of the line. POINT is the offset in that line of the cursor. - You should pretend that the line ends at POINT. + return NULL; +} - Returns NULL if there are no more completions, else a pointer to a - string which is a possible completion, it is the caller's - responsibility to free the string. */ +/* See completer.h. */ -static char * -line_completion_function (const char *text, int matches, - char *line_buffer, int point) +const char * +completion_find_completion_word (completion_tracker &tracker, const char *text, + int *quote_char) { - static VEC (char_ptr) *list = NULL; /* Cache of completions. */ - static int index; /* Next cached completion. */ - char *output = NULL; + size_t point = strlen (text); - if (matches == 0) + complete_line_internal (tracker, NULL, text, point, handle_brkchars); + + if (tracker.use_custom_word_point ()) { - /* The caller is beginning to accumulate a new set of - completions, so we need to find all of them now, and cache - them for returning one at a time on future calls. */ + gdb_assert (tracker.custom_word_point () > 0); + *quote_char = tracker.quote_char (); + return text + tracker.custom_word_point (); + } + + gdb_rl_completion_word_info info; + + info.word_break_characters = rl_completer_word_break_characters; + info.quote_characters = gdb_completer_quote_characters; + info.basic_quote_characters = rl_basic_quote_characters; + + return gdb_rl_find_completion_word (&info, quote_char, NULL, text); +} - if (list) +/* See completer.h. */ + +void +completion_tracker::recompute_lowest_common_denominator (const char *new_match) +{ + if (m_lowest_common_denominator == NULL) + { + /* We don't have a lowest common denominator yet, so simply take + the whole NEW_MATCH as being it. */ + m_lowest_common_denominator = xstrdup (new_match); + m_lowest_common_denominator_unique = true; + } + else + { + /* Find the common denominator between the currently-known + lowest common denominator and NEW_MATCH. That becomes the + new lowest common denominator. */ + size_t i; + + for (i = 0; + (new_match[i] != '\0' + && new_match[i] == m_lowest_common_denominator[i]); + i++) + ; + if (m_lowest_common_denominator[i] != new_match[i]) { - /* Free the storage used by LIST, but not by the strings - inside. This is because rl_complete_internal () frees - the strings. As complete_line may abort by calling - `error' clear LIST now. */ - VEC_free (char_ptr, list); + m_lowest_common_denominator[i] = '\0'; + m_lowest_common_denominator_unique = false; } - index = 0; - list = complete_line (text, line_buffer, point); } +} - /* If we found a list of potential completions during initialization - then dole them out one at a time. After returning the last one, - return NULL (and continue to do so) each time we are called after - that, until a new list is available. */ +/* See completer.h. */ - if (list) +void +completion_tracker::advance_custom_word_point_by (size_t len) +{ + m_custom_word_point += len; +} + +/* Build a new C string that is a copy of LCD with the whitespace of + ORIG/ORIG_LEN preserved. + + Say the user is completing a symbol name, with spaces, like: + + "foo ( i" + + and the resulting completion match is: + + "foo(int)" + + we want to end up with an input line like: + + "foo ( int)" + ^^^^^^^ => text from LCD [1], whitespace from ORIG preserved. + ^^ => new text from LCD + + [1] - We must take characters from the LCD instead of the original + text, since some completions want to change upper/lowercase. E.g.: + + "handle sig<>" + + completes to: + + "handle SIG[QUIT|etc.]" +*/ + +static char * +expand_preserving_ws (const char *orig, size_t orig_len, + const char *lcd) +{ + const char *p_orig = orig; + const char *orig_end = orig + orig_len; + const char *p_lcd = lcd; + std::string res; + + while (p_orig < orig_end) { - if (index < VEC_length (char_ptr, list)) + if (*p_orig == ' ') { - output = VEC_index (char_ptr, list, index); - index++; + while (p_orig < orig_end && *p_orig == ' ') + res += *p_orig++; + p_lcd = skip_spaces_const (p_lcd); + } + else + { + /* Take characters from the LCD instead of the original + text, since some completions change upper/lowercase. + E.g.: + "handle sig<>" + completes to: + "handle SIG[QUIT|etc.]" + */ + res += *p_lcd; + p_orig++; + p_lcd++; } } -#if 0 - /* Can't do this because readline hasn't yet checked the word breaks - for figuring out whether to insert a quote. */ - if (output == NULL) - /* Make sure the word break characters are set back to normal for - the next time that readline tries to complete something. */ - rl_completer_word_break_characters = - current_language->la_word_break_characters(); -#endif + while (*p_lcd != '\0') + res += *p_lcd++; + + return xstrdup (res.c_str ()); +} + +/* See completer.h. */ + +completion_result +completion_tracker::build_completion_result (const char *text, + int start, int end) +{ + completion_list &list = m_entries_vec; /* The completions. */ + + if (list.empty ()) + return {}; + + /* +1 for the LCD, and +1 for NULL termination. */ + char **match_list = XNEWVEC (char *, 1 + list.size () + 1); + + /* Build replacement word, based on the LCD. */ + + match_list[0] + = expand_preserving_ws (text, end - start, + m_lowest_common_denominator); + + if (m_lowest_common_denominator_unique) + { + /* We don't rely on readline appending the quote char as + delimiter as then readline wouldn't append the ' ' after the + completion. */ + char buf[2] = { quote_char () }; + + match_list[0] = reconcat (match_list[0], match_list[0], + buf, (char *) NULL); + match_list[1] = NULL; + + /* If the tracker wants to, or we already have a space at the + end of the match, tell readline to skip appending + another. */ + bool completion_suppress_append + = (suppress_append_ws () + || match_list[0][strlen (match_list[0]) - 1] == ' '); + + return completion_result (match_list, 1, completion_suppress_append); + } + else + { + int ix; + + for (ix = 0; ix < list.size (); ++ix) + match_list[ix + 1] = list[ix].release (); + match_list[ix + 1] = NULL; + + return completion_result (match_list, list.size (), false); + } +} + +/* See completer.h */ + +completion_result::completion_result () + : match_list (NULL), number_matches (0), + completion_suppress_append (false) +{} + +/* See completer.h */ + +completion_result::completion_result (char **match_list_, + size_t number_matches_, + bool completion_suppress_append_) + : match_list (match_list_), + number_matches (number_matches_), + completion_suppress_append (completion_suppress_append_) +{} + +/* See completer.h */ + +completion_result::~completion_result () +{ + reset_match_list (); +} + +/* See completer.h */ - return (output); +completion_result::completion_result (completion_result &&rhs) +{ + if (this == &rhs) + return; + + reset_match_list (); + match_list = rhs.match_list; + rhs.match_list = NULL; + number_matches = rhs.number_matches; + rhs.number_matches = 0; +} + +/* See completer.h */ + +char ** +completion_result::release_match_list () +{ + char **ret = match_list; + match_list = NULL; + return ret; +} + +/* See completer.h */ + +void +completion_result::sort_match_list () +{ + if (number_matches > 1) + { + /* Element 0 is special (it's the common prefix), leave it + be. */ + std::sort (&match_list[1], + &match_list[number_matches + 1], + compare_cstrings); + } +} + +/* See completer.h */ + +void +completion_result::reset_match_list () +{ + if (match_list != NULL) + { + for (char **p = match_list; *p != NULL; p++) + xfree (*p); + xfree (match_list); + match_list = NULL; + } +} + +/* Helper for gdb_rl_attempted_completion_function, which does most of + the work. This is called by readline to build the match list array + and to determine the lowest common denominator. The real matches + list starts at match[1], while match[0] is the slot holding + readline's idea of the lowest common denominator of all matches, + which is what readline replaces the completion "word" with. + + TEXT is the caller's idea of the "word" we are looking at, as + computed in the handle_brkchars phase. + + START is the offset from RL_LINE_BUFFER where TEXT starts. END is + the offset from RL_LINE_BUFFER where TEXT ends (i.e., where + rl_point is). + + You should thus pretend that the line ends at END (relative to + RL_LINE_BUFFER). + + RL_LINE_BUFFER contains the entire text of the line. RL_POINT is + the offset in that line of the cursor. You should pretend that the + line ends at POINT. + + Returns NULL if there are no completions. */ + +static char ** +gdb_rl_attempted_completion_function_throw (const char *text, int start, int end) +{ + /* Completers that provide a custom word point in the + handle_brkchars phase also compute their completions then. + Completers that leave the completion word handling to readline + must be called twice. If rl_point (i.e., END) is at column 0, + then readline skips the handle_brkchars phase, and so we create a + tracker now in that case too. */ + if (end == 0 || !current_completion.tracker->use_custom_word_point ()) + { + delete current_completion.tracker; + current_completion.tracker = new completion_tracker (); + + complete_line (*current_completion.tracker, text, + rl_line_buffer, rl_point); + } + + completion_tracker &tracker = *current_completion.tracker; + + completion_result result + = tracker.build_completion_result (text, start, end); + + rl_completion_suppress_append = result.completion_suppress_append; + return result.release_match_list (); +} + +/* Function installed as "rl_attempted_completion_function" readline + hook. Wrapper around gdb_rl_attempted_completion_function_throw + that catches C++ exceptions, which can't cross readline. */ + +char ** +gdb_rl_attempted_completion_function (const char *text, int start, int end) +{ + /* Restore globals that might have been tweaked in + gdb_completion_word_break_characters. */ + rl_basic_quote_characters = gdb_org_rl_basic_quote_characters; + + /* If we end up returning NULL, either on error, or simple because + there are no matches, inhibit readline's default filename + completer. */ + rl_attempted_completion_over = 1; + + /* If the handle_brkchars phase was aborted, don't try + completing. */ + if (current_completion.aborted) + return NULL; + + TRY + { + return gdb_rl_attempted_completion_function_throw (text, start, end); + } + CATCH (ex, RETURN_MASK_ALL) + { + } + END_CATCH + + return NULL; } /* Skip over the possibly quoted word STR (as defined by the quote diff --git a/gdb/completer.h b/gdb/completer.h index 2aa1987..f68c6dc 100644 --- a/gdb/completer.h +++ b/gdb/completer.h @@ -63,41 +63,292 @@ struct match_list_displayer mld_read_key_ftype *read_key; }; +/* A list of completion candidates. Each element is a malloc string, + because ownership of the strings is transferred to readline, which + calls free on each element. */ +typedef std::vector<gdb::unique_xmalloc_ptr<char>> completion_list; + +/* The final result of a completion that is handed over to either + readline or the "completion" command (which pretends to be + readline). Mainly a wrapper for a readline-style match list array, + though other bits of info are included too. */ + +struct completion_result +{ + /* Create an empty result. */ + completion_result (); + + /* Create a result. */ + completion_result (char **match_list, size_t number_matches, + bool completion_suppress_append); + + /* Destroy a result. */ + ~completion_result (); + + /* Disable copying, since we don't need it. */ + completion_result (const completion_result &rhs) = delete; + void operator= (const completion_result &rhs) = delete; + + /* Move a result. */ + completion_result (completion_result &&rhs); + + /* Release ownership of the match list array. */ + char **release_match_list (); + + /* Sort the match list. */ + void sort_match_list (); + +private: + /* Destroy the match list array and its contents. */ + void reset_match_list (); + +public: + /* (There's no point in making these fields private, since the whole + point of this wrapper is to build data in the layout expected by + readline. Making them private would require adding getters for + the "complete" command, which would expose the same + implementation details anyway.) */ + + /* The match list array, in the format that readline expects. + match_list[0] contains the common prefix. The real match list + starts at index 1. The list is NULL terminated. If there's only + one match, then match_list[1] is NULL. If there are no matches, + then this is NULL. */ + char **match_list; + /* The number of matched completions in MATCH_LIST. Does not + include the NULL terminator or the common prefix. */ + size_t number_matches; + + /* Whether readline should suppress appending a whitespace, when + there's only one possible completion. */ + bool completion_suppress_append; +}; + +/* Object used by completers to build a completion match list to hand + over to readline. It tracks: + + - How many unique completions have been generated, to terminate + completion list generation early if the list has grown to a size + so large as to be useless. This helps avoid GDB seeming to lock + up in the event the user requests to complete on something vague + that necessitates the time consuming expansion of many symbol + tables. + + - The custom word point to hand over to readline, for completers + that parse the input string in order to dynamically adjust + themselves depending on exactly what they're completing. E.g., + the linespec completer needs to bypass readline's too-simple word + breaking algorithm. +*/ +class completion_tracker +{ +public: + completion_tracker (); + ~completion_tracker (); + + /* Disable copy. */ + completion_tracker (const completion_tracker &rhs) = delete; + void operator= (const completion_tracker &rhs) = delete; + + /* Add the completion NAME to the list of generated completions if + it is not there already. If too many completions were already + found, this throws an error. */ + void add_completion (gdb::unique_xmalloc_ptr<char> name); + + /* Add all completions matches in LIST. Elements are moved out of + LIST. */ + void add_completions (completion_list &&list); + + /* Set the quote char to be appended after a unique completion is + added to the input line. Set to '\0' to clear. See + m_quote_char's description. */ + void set_quote_char (int quote_char) + { m_quote_char = quote_char; } + + /* The quote char to be appended after a unique completion is added + to the input line. Returns '\0' if no quote char has been set. + See m_quote_char's description. */ + int quote_char () { return m_quote_char; } + + /* Tell the tracker that the current completer wants to provide a + custom word point instead of a list of a break chars, in the + handle_brkchars phase. Such completers must also compute their + completions then. */ + void set_use_custom_word_point (bool enable) + { m_use_custom_word_point = enable; } + + /* Whether the current completer computes a custom word point. */ + bool use_custom_word_point () const + { return m_use_custom_word_point; } + + /* The custom word point. */ + int custom_word_point () const + { return m_custom_word_point; } + + /* Set the custom word point to POINT. */ + void set_custom_word_point (int point) + { m_custom_word_point = point; } + + /* Advance the custom word point by LEN. */ + void advance_custom_word_point_by (size_t len); + + /* Whether to tell readline to skip appending a whitespace after the + completion. See m_suppress_append_ws. */ + bool suppress_append_ws () const + { return m_suppress_append_ws; } + + /* Set whether to tell readline to skip appending a whitespace after + the completion. See m_suppress_append_ws. */ + void set_suppress_append_ws (bool suppress) + { m_suppress_append_ws = suppress; } + + /* Return true if we only have one completion, and it matches + exactly the completion word. I.e., completing results in what we + already have. */ + bool completes_to_completion_word (const char *word); + + /* True if we have any completion match recorded. */ + bool have_completions () const + { return !m_entries_vec.empty (); } + + /* Discard the current completion match list and the current + LCD. */ + void discard_completions (); + + /* Build a completion_result containing the list of completion + matches to hand over to readline. The parameters are as in + rl_attempted_completion_function. */ + completion_result build_completion_result (const char *text, + int start, int end); + +private: + + /* Add the completion NAME to the list of generated completions if + it is not there already. If false is returned, too many + completions were found. */ + bool maybe_add_completion (gdb::unique_xmalloc_ptr<char> name); + + /* Given a new match, recompute the lowest common denominator (LCD) + to hand over to readline. */ + void recompute_lowest_common_denominator (const char *new_match); + + /* The completion matches found so far, in a vector. */ + completion_list m_entries_vec; + + /* The completion matches found so far, in a hash table, for + duplicate elimination as entries are added. Otherwise the user + is left scratching his/her head: readline and complete_command + will remove duplicates, and if removal of duplicates there brings + the total under max_completions the user may think gdb quit + searching too early. */ + htab_t m_entries_hash; + + /* If non-zero, then this is the quote char that needs to be + appended after completion (iff we have a unique completion). We + don't rely on readline appending the quote char as delimiter as + then readline wouldn't append the ' ' after the completion. + I.e., we want this: + + before tab: "b 'function(" + after tab: "b 'function()' " + */ + int m_quote_char = '\0'; + + /* If true, the completer has its own idea of "word" point, and + doesn't want to rely on readline computing it based on brkchars. + Set in the handle_brkchars phase. */ + bool m_use_custom_word_point = false; + + /* The completer's idea of where the "word" we were looking at is + relative to RL_LINE_BUFFER. This is advanced in the + handle_brkchars phase as the completer discovers potential + completable words. */ + int m_custom_word_point = 0; + + /* If true, tell readline to skip appending a whitespace after the + completion. Automatically set if we have a unique completion + that already has a space at the end. A completer may also + explicitly set this. E.g., the linespec completer sets this when + the completion ends with the ":" separator between filename and + function name. */ + bool m_suppress_append_ws = false; + + /* Our idea of lowest common denominator to hand over to readline. + See intro. */ + char *m_lowest_common_denominator = NULL; + + /* If true, the LCD is unique. I.e., all completion candidates had + the same string. */ + bool m_lowest_common_denominator_unique = false; +}; + extern void gdb_display_match_list (char **matches, int len, int max, const struct match_list_displayer *); extern const char *get_max_completions_reached_message (void); -extern VEC (char_ptr) *complete_line (const char *text, - const char *line_buffer, - int point); +extern void complete_line (completion_tracker &tracker, + const char *text, + const char *line_buffer, + int point); -extern char *readline_line_completion_function (const char *text, - int matches); +/* Find the bounds of the word in TEXT for completion purposes, and + return a pointer to the end of the word. Calls the completion + machinery for a handle_brkchars phase (using TRACKER) to figure out + the right work break characters for the command in TEXT. + QUOTE_CHAR, if non-null, is set to the opening quote character if + we found an unclosed quoted substring, '\0' otherwise. */ +extern const char *completion_find_completion_word (completion_tracker &tracker, + const char *text, + int *quote_char); -extern VEC (char_ptr) *noop_completer (struct cmd_list_element *, - const char *, const char *); -extern VEC (char_ptr) *filename_completer (struct cmd_list_element *, - const char *, const char *); +/* Assuming TEXT is an expression in the current language, find the + completion word point for TEXT, emulating the algorithm readline + uses to find the word point, using the current language's word + break characters. */ -extern VEC (char_ptr) *expression_completer (struct cmd_list_element *, - const char *, const char *); +const char *advance_to_expression_complete_word_point + (completion_tracker &tracker, const char *text); -extern VEC (char_ptr) *location_completer (struct cmd_list_element *, - const char *, const char *); +extern char **gdb_rl_attempted_completion_function (const char *text, + int start, int end); -extern VEC (char_ptr) *command_completer (struct cmd_list_element *, - const char *, const char *); +extern void noop_completer (struct cmd_list_element *, + completion_tracker &tracker, + const char *, const char *); -extern VEC (char_ptr) *signal_completer (struct cmd_list_element *, - const char *, const char *); +extern void filename_completer (struct cmd_list_element *, + completion_tracker &tracker, + const char *, const char *); -extern VEC (char_ptr) *reg_or_group_completer (struct cmd_list_element *, - const char *, const char *); +extern void expression_completer (struct cmd_list_element *, + completion_tracker &tracker, + const char *, const char *); -extern VEC (char_ptr) *reggroup_completer (struct cmd_list_element *, - const char *, const char *); +extern void location_completer (struct cmd_list_element *, + completion_tracker &tracker, + const char *, const char *); + +extern void symbol_completer (struct cmd_list_element *, + completion_tracker &tracker, + const char *, const char *); + +extern void command_completer (struct cmd_list_element *, + completion_tracker &tracker, + const char *, const char *); + +extern void signal_completer (struct cmd_list_element *, + completion_tracker &tracker, + const char *, const char *); + +extern void reg_or_group_completer (struct cmd_list_element *, + completion_tracker &tracker, + const char *, const char *); + +extern void reggroup_completer (struct cmd_list_element *, + completion_tracker &tracker, + const char *, const char *); extern const char *get_gdb_completer_quote_characters (void); @@ -109,15 +360,27 @@ extern char *gdb_completion_word_break_characters (void); not "const char *". */ extern void set_rl_completer_word_break_characters (const char *break_chars); -/* Set the word break characters array to the corresponding set of - chars, based on FN. This function is useful for cases when the - completer doesn't know the type of the completion until some +/* Get the matching completer_handle_brkchars_ftype function for FN. + FN is one of the core completer functions above (filename, + location, symbol, etc.). This function is useful for cases when + the completer doesn't know the type of the completion until some calculation is done (e.g., for Python functions). */ -extern void set_gdb_completion_word_break_characters (completer_ftype *fn); +extern completer_handle_brkchars_ftype * + completer_handle_brkchars_func_for_completer (completer_ftype *fn); /* Exported to linespec.c */ +/* Return a list of all source files whose names begin with matching + TEXT. */ +extern completion_list complete_source_filenames (const char *text); + +/* Complete on expressions. Often this means completing on symbol + names, but some language parsers also have support for completing + field names. */ +extern void complete_expression (completion_tracker &tracker, + const char *text, const char *word); + extern const char *skip_quoted_chars (const char *, const char *, const char *); @@ -129,62 +392,4 @@ extern const char *skip_quoted (const char *); extern int max_completions; -/* Object to track how many unique completions have been generated. - Used to limit the size of generated completion lists. */ - -typedef htab_t completion_tracker_t; - -/* Create a new completion tracker. - The result is a hash table to track added completions, or NULL - if max_completions <= 0. If max_completions < 0, tracking is disabled. - If max_completions == 0, the max is indeed zero. */ - -extern completion_tracker_t new_completion_tracker (void); - -/* Make a cleanup to free a completion tracker, and reset its pointer - to NULL. */ - -extern struct cleanup *make_cleanup_free_completion_tracker - (completion_tracker_t *tracker_ptr); - -/* Return values for maybe_add_completion. */ - -enum maybe_add_completion_enum -{ - /* NAME has been recorded and max_completions has not been reached, - or completion tracking is disabled (max_completions < 0). */ - MAYBE_ADD_COMPLETION_OK, - - /* NAME has been recorded and max_completions has been reached - (thus the caller can stop searching). */ - MAYBE_ADD_COMPLETION_OK_MAX_REACHED, - - /* max-completions entries has been reached. - Whether NAME is a duplicate or not is not determined. */ - MAYBE_ADD_COMPLETION_MAX_REACHED, - - /* NAME has already been recorded. - Note that this is never returned if completion tracking is disabled - (max_completions < 0). */ - MAYBE_ADD_COMPLETION_DUPLICATE -}; - -/* Add the completion NAME to the list of generated completions if - it is not there already. - If max_completions is negative, nothing is done, not even watching - for duplicates, and MAYBE_ADD_COMPLETION_OK is always returned. - - If MAYBE_ADD_COMPLETION_MAX_REACHED is returned, callers are required to - record at least one more completion. The final list will be pruned to - max_completions, but recording at least one more than max_completions is - the signal to the completion machinery that too many completions were - found. */ - -extern enum maybe_add_completion_enum - maybe_add_completion (completion_tracker_t tracker, char *name); - -/* Wrapper to throw MAX_COMPLETIONS_REACHED_ERROR. */ - -extern void throw_max_completions_reached_error (void); - #endif /* defined (COMPLETER_H) */ diff --git a/gdb/configure.nat b/gdb/configure.nat index 2026ee7..b32c9aa 100644 --- a/gdb/configure.nat +++ b/gdb/configure.nat @@ -345,11 +345,12 @@ case ${gdb_host} in # Host: NetBSD/sparc64 NATDEPFILES="${NATDEPFILES} sparc64-nbsd-nat.o sparc-nat.o \ bsd-kvm.o" + LOADLIBES='-lkvm' ;; esac ;; - nbdself) + nbsdelf) case ${gdb_host_cpu} in arm) # Host: NetBSD/arm diff --git a/gdb/corefile.c b/gdb/corefile.c index 33eb4d1..d9773cf 100644 --- a/gdb/corefile.c +++ b/gdb/corefile.c @@ -483,8 +483,9 @@ set_gnutarget_command (char *ignore, int from_tty, /* A completion function for "set gnutarget". */ -static VEC (char_ptr) * +static void complete_set_gnutarget (struct cmd_list_element *cmd, + completion_tracker &tracker, const char *text, const char *word) { static const char **bfd_targets; @@ -502,7 +503,7 @@ complete_set_gnutarget (struct cmd_list_element *cmd, bfd_targets[last + 1] = NULL; } - return complete_on_enum (bfd_targets, text, word); + complete_on_enum (tracker, bfd_targets, text, word); } /* Set the gnutarget. */ diff --git a/gdb/corelow.c b/gdb/corelow.c index 0aff02d..ac72268 100644 --- a/gdb/corelow.c +++ b/gdb/corelow.c @@ -277,7 +277,6 @@ core_open (const char *arg, int from_tty) char *temp; int scratch_chan; int flags; - char *filename; target_preopen (from_tty); if (!arg) @@ -289,31 +288,25 @@ core_open (const char *arg, int from_tty) error (_("No core file specified.")); } - filename = tilde_expand (arg); - if (!IS_ABSOLUTE_PATH (filename)) - { - temp = concat (current_directory, "/", - filename, (char *) NULL); - xfree (filename); - filename = temp; - } - - old_chain = make_cleanup (xfree, filename); + gdb::unique_xmalloc_ptr<char> filename (tilde_expand (arg)); + if (!IS_ABSOLUTE_PATH (filename.get ())) + filename.reset (concat (current_directory, "/", + filename.get (), (char *) NULL)); flags = O_BINARY | O_LARGEFILE; if (write_files) flags |= O_RDWR; else flags |= O_RDONLY; - scratch_chan = gdb_open_cloexec (filename, flags, 0); + scratch_chan = gdb_open_cloexec (filename.get (), flags, 0); if (scratch_chan < 0) - perror_with_name (filename); + perror_with_name (filename.get ()); - gdb_bfd_ref_ptr temp_bfd (gdb_bfd_fopen (filename, gnutarget, + gdb_bfd_ref_ptr temp_bfd (gdb_bfd_fopen (filename.get (), gnutarget, write_files ? FOPEN_RUB : FOPEN_RB, scratch_chan)); if (temp_bfd == NULL) - perror_with_name (filename); + perror_with_name (filename.get ()); if (!bfd_check_format (temp_bfd.get (), bfd_core) && !gdb_check_format (temp_bfd.get ())) @@ -323,13 +316,12 @@ core_open (const char *arg, int from_tty) thing, on error it does not free all the storage associated with the bfd). */ error (_("\"%s\" is not a core dump: %s"), - filename, bfd_errmsg (bfd_get_error ())); + filename.get (), bfd_errmsg (bfd_get_error ())); } /* Looks semi-reasonable. Toss the old core file and work on the new. */ - do_cleanups (old_chain); unpush_target (&core_ops); core_bfd = temp_bfd.release (); old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/); @@ -485,51 +477,6 @@ core_detach (struct target_ops *ops, const char *args, int from_tty) printf_filtered (_("No core file now.\n")); } -/* Build either a single-thread or multi-threaded section name for - PTID. - - If ptid's lwp member is zero, we want to do the single-threaded - thing: look for a section named NAME (as passed to the - constructor). If ptid's lwp member is non-zero, we'll want do the - multi-threaded thing: look for a section named "NAME/LWP", where - LWP is the shortest ASCII decimal representation of ptid's lwp - member. */ - -class thread_section_name -{ -public: - /* NAME is the single-threaded section name. If PTID represents an - LWP, then the build section name is "NAME/LWP", otherwise it's - just "NAME" unmodified. */ - thread_section_name (const char *name, ptid_t ptid) - { - if (ptid.lwp_p ()) - { - m_storage = string_printf ("%s/%ld", name, ptid.lwp ()); - m_section_name = m_storage.c_str (); - } - else - m_section_name = name; - } - - /* Return the computed section name. The result is valid as long as - this thread_section_name object is live. */ - const char *c_str () const - { return m_section_name; } - - /* Disable copy. */ - thread_section_name (const thread_section_name &) = delete; - void operator= (const thread_section_name &) = delete; - -private: - /* Either a pointer into M_STORAGE, or a pointer to the name passed - as parameter to the constructor. */ - const char *m_section_name; - /* If we need to build a new section name, this is where we store - it. */ - std::string m_storage; -}; - /* Try to retrieve registers from a section in core_bfd, and supply them to core_vec->core_read_registers, as the register set numbered WHICH. @@ -713,25 +660,6 @@ add_to_spuid_list (bfd *abfd, asection *asect, void *list_p) list->pos += 4; } -/* Read siginfo data from the core, if possible. Returns -1 on - failure. Otherwise, returns the number of bytes read. ABFD is the - core file's BFD; READBUF, OFFSET, and LEN are all as specified by - the to_xfer_partial interface. */ - -static LONGEST -get_core_siginfo (bfd *abfd, gdb_byte *readbuf, ULONGEST offset, ULONGEST len) -{ - thread_section_name section_name (".note.linuxcore.siginfo", inferior_ptid); - asection *section = bfd_get_section_by_name (abfd, section_name.c_str ()); - if (section == NULL) - return -1; - - if (!bfd_get_section_contents (abfd, section, readbuf, offset, len)) - return -1; - - return len; -} - static enum target_xfer_status core_xfer_partial (struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *readbuf, @@ -919,12 +847,20 @@ core_xfer_partial (struct target_ops *ops, enum target_object object, case TARGET_OBJECT_SIGNAL_INFO: if (readbuf) { - LONGEST l = get_core_siginfo (core_bfd, readbuf, offset, len); - - if (l > 0) + if (core_gdbarch + && gdbarch_core_xfer_siginfo_p (core_gdbarch)) { - *xfered_len = len; - return TARGET_XFER_OK; + LONGEST l = gdbarch_core_xfer_siginfo (core_gdbarch, readbuf, + offset, len); + + if (l >= 0) + { + *xfered_len = l; + if (l == 0) + return TARGET_XFER_EOF; + else + return TARGET_XFER_OK; + } } } return TARGET_XFER_E_IO; diff --git a/gdb/cp-abi.c b/gdb/cp-abi.c index b72f227..f4cf944 100644 --- a/gdb/cp-abi.c +++ b/gdb/cp-abi.c @@ -355,8 +355,9 @@ set_cp_abi_cmd (char *args, int from_tty) /* A completion function for "set cp-abi". */ -static VEC (char_ptr) * +static void cp_abi_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, const char *text, const char *word) { static const char **cp_abi_names; @@ -371,7 +372,7 @@ cp_abi_completer (struct cmd_list_element *ignore, cp_abi_names[i] = NULL; } - return complete_on_enum (cp_abi_names, text, word); + complete_on_enum (tracker, cp_abi_names, text, word); } /* Show the currently selected C++ ABI. */ diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y index 2593641..301c26b 100644 --- a/gdb/cp-name-parser.y +++ b/gdb/cp-name-parser.y @@ -1966,13 +1966,14 @@ allocate_info (void) cplus_demangle_print does not, specifically the global destructor and constructor labels. */ -char * +gdb::unique_xmalloc_ptr<char> cp_comp_to_string (struct demangle_component *result, int estimated_len) { size_t err; - return cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI, result, estimated_len, - &err); + char *res = cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI, + result, estimated_len, &err); + return gdb::unique_xmalloc_ptr<char> (res); } /* Constructor for demangle_parse_info. */ diff --git a/gdb/cp-support.c b/gdb/cp-support.c index 26af2bc..cc5c5e7 100644 --- a/gdb/cp-support.c +++ b/gdb/cp-support.c @@ -293,8 +293,6 @@ replace_typedefs_qualified_name (struct demangle_parse_info *info, canonicalization_ftype *finder, void *data) { - long len; - char *name; string_file buf; struct demangle_component *comp = ret_comp; @@ -310,14 +308,14 @@ replace_typedefs_qualified_name (struct demangle_parse_info *info, struct demangle_component newobj; buf.write (d_left (comp)->u.s_name.s, d_left (comp)->u.s_name.len); - len = buf.size (); - name = (char *) obstack_copy0 (&info->obstack, buf.c_str (), len); newobj.type = DEMANGLE_COMPONENT_NAME; - newobj.u.s_name.s = name; - newobj.u.s_name.len = len; + newobj.u.s_name.s + = (char *) obstack_copy0 (&info->obstack, + buf.c_str (), buf.size ()); + newobj.u.s_name.len = buf.size (); if (inspect_type (info, &newobj, finder, data)) { - char *n, *s; + char *s; long slen; /* A typedef was substituted in NEW. Convert it to a @@ -325,15 +323,15 @@ replace_typedefs_qualified_name (struct demangle_parse_info *info, node. */ buf.clear (); - n = cp_comp_to_string (&newobj, 100); + gdb::unique_xmalloc_ptr<char> n + = cp_comp_to_string (&newobj, 100); if (n == NULL) { /* If something went astray, abort typedef substitutions. */ return; } - s = copy_string_to_obstack (&info->obstack, n, &slen); - xfree (n); + s = copy_string_to_obstack (&info->obstack, n.get (), &slen); d_left (ret_comp)->type = DEMANGLE_COMPONENT_NAME; d_left (ret_comp)->u.s_name.s = s; @@ -349,14 +347,14 @@ replace_typedefs_qualified_name (struct demangle_parse_info *info, typedefs in it. Then print it to the stream to continue checking for more typedefs in the tree. */ replace_typedefs (info, d_left (comp), finder, data); - name = cp_comp_to_string (d_left (comp), 100); + gdb::unique_xmalloc_ptr<char> name + = cp_comp_to_string (d_left (comp), 100); if (name == NULL) { /* If something went astray, abort typedef substitutions. */ return; } - buf.puts (name); - xfree (name); + buf.puts (name.get ()); } buf.write ("::", 2); @@ -370,15 +368,15 @@ replace_typedefs_qualified_name (struct demangle_parse_info *info, if (comp->type == DEMANGLE_COMPONENT_NAME) { buf.write (comp->u.s_name.s, comp->u.s_name.len); - len = buf.size (); - name = (char *) obstack_copy0 (&info->obstack, buf.c_str (), len); /* Replace the top (DEMANGLE_COMPONENT_QUAL_NAME) node with a DEMANGLE_COMPONENT_NAME node containing the whole name. */ ret_comp->type = DEMANGLE_COMPONENT_NAME; - ret_comp->u.s_name.s = name; - ret_comp->u.s_name.len = len; + ret_comp->u.s_name.s + = (char *) obstack_copy0 (&info->obstack, + buf.c_str (), buf.size ()); + ret_comp->u.s_name.len = buf.size (); inspect_type (info, ret_comp, finder, data); } else @@ -420,7 +418,8 @@ replace_typedefs (struct demangle_parse_info *info, || ret_comp->type == DEMANGLE_COMPONENT_TEMPLATE || ret_comp->type == DEMANGLE_COMPONENT_BUILTIN_TYPE)) { - char *local_name = cp_comp_to_string (ret_comp, 10); + gdb::unique_xmalloc_ptr<char> local_name + = cp_comp_to_string (ret_comp, 10); if (local_name != NULL) { @@ -429,15 +428,14 @@ replace_typedefs (struct demangle_parse_info *info, sym = NULL; TRY { - sym = lookup_symbol (local_name, 0, VAR_DOMAIN, 0).symbol; + sym = lookup_symbol (local_name.get (), 0, + VAR_DOMAIN, 0).symbol; } CATCH (except, RETURN_MASK_ALL) { } END_CATCH - xfree (local_name); - if (sym != NULL) { struct type *otype = SYMBOL_TYPE (sym); @@ -524,9 +522,11 @@ cp_canonicalize_string_full (const char *string, replace_typedefs (info.get (), info->tree, finder, data); /* Convert the tree back into a string. */ - ret = cp_comp_to_string (info->tree, estimated_len); - gdb_assert (!ret.empty ()); + gdb::unique_xmalloc_ptr<char> us = cp_comp_to_string (info->tree, + estimated_len); + gdb_assert (us); + ret = us.get (); /* Finally, compare the original string with the computed name, returning NULL if they are the same. */ if (ret == string) @@ -563,15 +563,18 @@ cp_canonicalize_string (const char *string) return std::string (); estimated_len = strlen (string) * 2; - std::string ret = cp_comp_to_string (info->tree, estimated_len); + gdb::unique_xmalloc_ptr<char> us (cp_comp_to_string (info->tree, + estimated_len)); - if (ret.empty ()) + if (!us) { warning (_("internal error: string \"%s\" failed to be canonicalized"), string); return std::string (); } + std::string ret (us.get ()); + if (ret == string) return std::string (); @@ -630,7 +633,9 @@ cp_mangled_name_to_comp (const char *mangled_name, int options) char * cp_class_name_from_physname (const char *physname) { - char *ret; + void *storage = NULL; + char *demangled_name = NULL; + gdb::unique_xmalloc_ptr<char> ret; struct demangle_component *ret_comp, *prev_comp, *cur_comp; std::unique_ptr<demangle_parse_info> info; int done; @@ -698,7 +703,6 @@ cp_class_name_from_physname (const char *physname) break; } - ret = NULL; if (cur_comp != NULL && prev_comp != NULL) { /* We want to discard the rightmost child of PREV_COMP. */ @@ -708,7 +712,9 @@ cp_class_name_from_physname (const char *physname) ret = cp_comp_to_string (ret_comp, 10); } - return ret; + xfree (storage); + xfree (demangled_name); + return ret.release (); } /* Return the child of COMP which is the basename of a method, @@ -775,7 +781,9 @@ unqualified_name_from_comp (struct demangle_component *comp) char * method_name_from_physname (const char *physname) { - char *ret; + void *storage = NULL; + char *demangled_name = NULL; + gdb::unique_xmalloc_ptr<char> ret; struct demangle_component *ret_comp; std::unique_ptr<demangle_parse_info> info; @@ -785,13 +793,14 @@ method_name_from_physname (const char *physname) ret_comp = unqualified_name_from_comp (info->tree); - ret = NULL; if (ret_comp != NULL) /* The ten is completely arbitrary; we don't have a good estimate. */ ret = cp_comp_to_string (ret_comp, 10); - return ret; + xfree (storage); + xfree (demangled_name); + return ret.release (); } /* If FULL_NAME is the demangled name of a C++ function (including an @@ -803,7 +812,7 @@ method_name_from_physname (const char *physname) char * cp_func_name (const char *full_name) { - char *ret; + gdb::unique_xmalloc_ptr<char> ret; struct demangle_component *ret_comp; std::unique_ptr<demangle_parse_info> info; @@ -813,11 +822,10 @@ cp_func_name (const char *full_name) ret_comp = unqualified_name_from_comp (info->tree); - ret = NULL; if (ret_comp != NULL) ret = cp_comp_to_string (ret_comp, 10); - return ret; + return ret.release (); } /* See description in cp-support.h. */ @@ -873,7 +881,7 @@ cp_remove_params (const char *demangled_name) int done = 0; struct demangle_component *ret_comp; std::unique_ptr<demangle_parse_info> info; - char *ret = NULL; + gdb::unique_xmalloc_ptr<char> ret; if (demangled_name == NULL) return NULL; @@ -905,7 +913,7 @@ cp_remove_params (const char *demangled_name) if (ret_comp->type == DEMANGLE_COMPONENT_TYPED_NAME) ret = cp_comp_to_string (d_left (ret_comp), 10); - return ret; + return ret.release (); } /* Here are some random pieces of trivia to keep in mind while trying @@ -961,10 +969,6 @@ cp_find_first_component (const char *name) the recursion easier, it also stops if it reaches an unexpected ')' or '>' if the value of PERMISSIVE is nonzero. */ -/* Let's optimize away calls to strlen("operator"). */ - -#define LENGTH_OF_OPERATOR 8 - static unsigned int cp_find_first_component_aux (const char *name, int permissive) { @@ -1036,14 +1040,15 @@ cp_find_first_component_aux (const char *name, int permissive) case 'o': /* Operator names can screw up the recursion. */ if (operator_possible - && strncmp (name + index, "operator", - LENGTH_OF_OPERATOR) == 0) + && startswith (name + index, CP_OPERATOR_STR)) { - index += LENGTH_OF_OPERATOR; + index += CP_OPERATOR_LEN; while (ISSPACE(name[index])) ++index; switch (name[index]) { + case '\0': + return index; /* Skip over one less than the appropriate number of characters: the for loop will skip over the last one. */ diff --git a/gdb/cp-support.h b/gdb/cp-support.h index 85d6461..1a4dd77 100644 --- a/gdb/cp-support.h +++ b/gdb/cp-support.h @@ -48,6 +48,14 @@ struct using_direct; #define CP_ANONYMOUS_NAMESPACE_LEN 21 +/* A string representing the start of an operator name. */ + +#define CP_OPERATOR_STR "operator" + +/* The length of CP_OPERATOR_STR. */ + +#define CP_OPERATOR_LEN 8 + /* The result of parsing a name. */ struct demangle_parse_info @@ -163,8 +171,8 @@ extern std::unique_ptr<demangle_parse_info> #define d_left(dc) (dc)->u.s_binary.left #define d_right(dc) (dc)->u.s_binary.right -extern char *cp_comp_to_string (struct demangle_component *result, - int estimated_len); +extern gdb::unique_xmalloc_ptr<char> cp_comp_to_string + (struct demangle_component *result, int estimated_len); extern void cp_merge_demangle_parse_infos (struct demangle_parse_info *, struct demangle_component *, diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c index 73fe03d..af70421 100644 --- a/gdb/cp-valprint.c +++ b/gdb/cp-valprint.c @@ -35,6 +35,7 @@ #include "language.h" #include "extension.h" #include "typeprint.h" +#include "byte-vector.h" /* Controls printing of vtbl's. */ static void @@ -534,23 +535,18 @@ cp_print_value (struct type *type, struct type *real_type, if ((boffset + offset) < 0 || (boffset + offset) >= TYPE_LENGTH (real_type)) { - gdb_byte *buf; - struct cleanup *back_to; + gdb::byte_vector buf (TYPE_LENGTH (baseclass)); - buf = (gdb_byte *) xmalloc (TYPE_LENGTH (baseclass)); - back_to = make_cleanup (xfree, buf); - - if (target_read_memory (address + boffset, buf, + if (target_read_memory (address + boffset, buf.data (), TYPE_LENGTH (baseclass)) != 0) skip = 1; base_val = value_from_contents_and_address (baseclass, - buf, + buf.data (), address + boffset); baseclass = value_type (base_val); thisoffset = 0; boffset = 0; thistype = baseclass; - do_cleanups (back_to); } else { diff --git a/gdb/d-exp.y b/gdb/d-exp.y index 62df737..d392a5c 100644 --- a/gdb/d-exp.y +++ b/gdb/d-exp.y @@ -1342,7 +1342,7 @@ static int popping; /* Temporary storage for yylex; this holds symbol names as they are built up. */ -static struct obstack name_obstack; +static auto_obstack name_obstack; /* Classify an IDENTIFIER token. The contents of the token are in `yylval'. Updates yylval and returns the new token type. BLOCK is the block @@ -1480,7 +1480,7 @@ yylex (void) first try building up a name until we find the qualified module. */ if (current.token == UNKNOWN_NAME) { - obstack_free (&name_obstack, obstack_base (&name_obstack)); + name_obstack.clear (); obstack_grow (&name_obstack, current.value.sval.ptr, current.value.sval.length); @@ -1533,7 +1533,7 @@ yylex (void) if (current.token != TYPENAME && current.token != '.') goto do_pop; - obstack_free (&name_obstack, obstack_base (&name_obstack)); + name_obstack.clear (); checkpoint = 0; if (current.token == '.') search_block = NULL; @@ -1627,6 +1627,8 @@ d_parse (struct parser_state *par_state) gdb_assert (par_state != NULL); pstate = par_state; + /* Note that parsing (within yyparse) freely installs cleanups + assuming they're run here (below). */ back_to = make_cleanup (null_cleanup, NULL); scoped_restore restore_yydebug = make_scoped_restore (&yydebug, @@ -1639,8 +1641,7 @@ d_parse (struct parser_state *par_state) VEC_free (token_and_value, token_fifo); popping = 0; - obstack_init (&name_obstack); - make_cleanup_obstack_free (&name_obstack); + name_obstack.clear (); result = yyparse (); do_cleanups (back_to); diff --git a/gdb/d-lang.c b/gdb/d-lang.c index 4416343..bf128b0 100644 --- a/gdb/d-lang.c +++ b/gdb/d-lang.c @@ -204,7 +204,7 @@ static const char *d_extensions[] = ".d", NULL }; -static const struct language_defn d_language_defn = +extern const struct language_defn d_language_defn = { "d", "D", @@ -239,7 +239,7 @@ static const struct language_defn d_language_defn = 1, /* C-style arrays. */ 0, /* String lower bound. */ default_word_break_characters, - default_make_symbol_completion_list, + default_collect_symbol_completion_matches, d_language_arch_info, default_print_array_index, default_pass_by_reference, @@ -350,6 +350,4 @@ void _initialize_d_language (void) { d_type_data = gdbarch_data_register_post_init (build_d_types); - - add_language (&d_language_defn); } diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c index cd67249..b721da8 100644 --- a/gdb/darwin-nat.c +++ b/gdb/darwin-nat.c @@ -367,29 +367,14 @@ darwin_check_new_threads (struct inferior *inf) if (new_ix < new_nbr && (old_ix == old_nbr || new_id < old_id)) { /* A thread was created. */ - struct thread_info *tp; struct private_thread_info *pti; pti = XCNEW (struct private_thread_info); pti->gdb_port = new_id; pti->msg_state = DARWIN_RUNNING; - if (old_nbr == 0 && new_ix == 0) - { - /* A ptid is create when the inferior is started (see - fork-child.c) with lwp=tid=0. This ptid will be renamed - later by darwin_init_thread_list (). */ - tp = find_thread_ptid (ptid_build (inf->pid, 0, 0)); - gdb_assert (tp); - gdb_assert (tp->priv == NULL); - tp->priv = pti; - } - else - { - /* Add the new thread. */ - tp = add_thread_with_info - (ptid_build (inf->pid, 0, new_id), pti); - } + /* Add the new thread. */ + add_thread_with_info (ptid_build (inf->pid, 0, new_id), pti); VEC_safe_push (darwin_thread_t, thread_vec, pti); new_ix++; continue; @@ -1701,23 +1686,38 @@ darwin_attach_pid (struct inferior *inf) push_target (darwin_ops); } +/* Get the thread_info object corresponding to this private_thread_info. */ + +static struct thread_info * +thread_info_from_private_thread_info (private_thread_info *pti) +{ + struct thread_info *it; + + ALL_THREADS (it) + { + if (it->priv->gdb_port == pti->gdb_port) + break; + } + + gdb_assert (it != NULL); + + return it; +} + static void darwin_init_thread_list (struct inferior *inf) { - darwin_thread_t *thread; - ptid_t new_ptid; - darwin_check_new_threads (inf); - gdb_assert (inf->priv->threads - && VEC_length (darwin_thread_t, inf->priv->threads) > 0); - thread = VEC_index (darwin_thread_t, inf->priv->threads, 0); + gdb_assert (inf->priv->threads != NULL); + gdb_assert (VEC_length (darwin_thread_t, inf->priv->threads) > 0); - /* Note: fork_inferior automatically add a thead but it uses a wrong ptid. - Fix up. */ - new_ptid = ptid_build (inf->pid, 0, thread->gdb_port); - thread_change_ptid (inferior_ptid, new_ptid); - inferior_ptid = new_ptid; + private_thread_info *first_pti + = VEC_index (darwin_thread_t, inf->priv->threads, 0); + struct thread_info *first_thread + = thread_info_from_private_thread_info (first_pti); + + inferior_ptid = first_thread->ptid; } /* The child must synchronize with gdb: gdb must set the exception port @@ -1834,23 +1834,10 @@ darwin_create_inferior (struct target_ops *ops, const std::string &allargs, char **env, int from_tty) { - pid_t pid; - ptid_t ptid; - /* Do the hard work. */ - pid = fork_inferior (exec_file, allargs, env, darwin_ptrace_me, - darwin_ptrace_him, darwin_pre_ptrace, NULL, - darwin_execvp); - - ptid = pid_to_ptid (pid); - /* Return now in case of error. */ - if (ptid_equal (inferior_ptid, null_ptid)) - return; - - /* We have something that executes now. We'll be running through - the shell at this point (if startup-with-shell is true), but the - pid shouldn't change. */ - add_thread_silent (ptid); + fork_inferior (exec_file, allargs, env, darwin_ptrace_me, + darwin_ptrace_him, darwin_pre_ptrace, NULL, + darwin_execvp); } @@ -1920,9 +1907,6 @@ darwin_attach (struct target_ops *ops, const char *args, int from_tty) inferior_appeared (inf, pid); inf->attach_flag = 1; - /* Always add a main thread. */ - add_thread_silent (inferior_ptid); - darwin_attach_pid (inf); darwin_suspend_inferior (inf); @@ -203,7 +203,8 @@ extern void quit_serial_event_clear (void); several languages. For that reason, the constants here are sorted in the order we'll attempt demangling them. For example: Rust uses C++ mangling, so must come after C++; Ada must come last (see - ada_sniff_from_mangled_name). */ + ada_sniff_from_mangled_name). (Keep this order in sync with the + 'languages' array in language.c.) */ enum language { diff --git a/gdb/dictionary.c b/gdb/dictionary.c index fc6498d..1d9b1f0 100644 --- a/gdb/dictionary.c +++ b/gdb/dictionary.c @@ -536,20 +536,6 @@ dict_iterator_next (struct dict_iterator *iterator) } struct symbol * -dict_iter_name_first (const struct dictionary *dict, - const char *name, - struct dict_iterator *iterator) -{ - return dict_iter_match_first (dict, name, strcmp_iw, iterator); -} - -struct symbol * -dict_iter_name_next (const char *name, struct dict_iterator *iterator) -{ - return dict_iter_match_next (name, strcmp_iw, iterator); -} - -struct symbol * dict_iter_match_first (const struct dictionary *dict, const char *name, symbol_compare_ftype *compare, struct dict_iterator *iterator) diff --git a/gdb/dictionary.h b/gdb/dictionary.h index cf0dc5d..45d059f 100644 --- a/gdb/dictionary.h +++ b/gdb/dictionary.h @@ -130,25 +130,6 @@ extern struct symbol *dict_iterator_first (const struct dictionary *dict, extern struct symbol *dict_iterator_next (struct dict_iterator *iterator); /* Initialize ITERATOR to point at the first symbol in DICT whose - SYMBOL_SEARCH_NAME is NAME (as tested using strcmp_iw), and return - that first symbol, or NULL if there are no such symbols. */ - -extern struct symbol *dict_iter_name_first (const struct dictionary *dict, - const char *name, - struct dict_iterator *iterator); - -/* Advance ITERATOR to point at the next symbol in DICT whose - SYMBOL_SEARCH_NAME is NAME (as tested using strcmp_iw), or NULL if - there are no more such symbols. Don't call this if you've - previously received NULL from dict_iterator_first or - dict_iterator_next on this iteration. And don't call it unless - ITERATOR was created by a previous call to dict_iter_name_first - with the same NAME. */ - -extern struct symbol *dict_iter_name_next (const char *name, - struct dict_iterator *iterator); - -/* Initialize ITERATOR to point at the first symbol in DICT whose SYMBOL_SEARCH_NAME is NAME, as tested using COMPARE (which must use the same conventions as strcmp_iw and be compatible with any dictionary hashing function), and return that first symbol, or NULL diff --git a/gdb/disasm.c b/gdb/disasm.c index 83f9871..76c4ff3 100644 --- a/gdb/disasm.c +++ b/gdb/disasm.c @@ -1030,8 +1030,9 @@ The following disassembler options are supported for use with the\n\ /* A completion function for "set disassembler". */ -static VEC (char_ptr) * +static void disassembler_options_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, const char *text, const char *word) { struct gdbarch *gdbarch = get_current_arch (); @@ -1044,9 +1045,8 @@ disassembler_options_completer (struct cmd_list_element *ignore, if (separator != NULL) text = separator + 1; text = skip_spaces_const (text); - return complete_on_enum (opts->name, text, word); + complete_on_enum (tracker, opts->name, text, word); } - return NULL; } diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 8c7c3da..4b40698 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,34 @@ +2017-08-12 Sergio Durigan Junior <sergiodj@redhat.com> + + PR gdb/21925 + * gdb.texinfo (Starting) <startup-with-shell>: Fix typo ("show + set..."). + +2017-08-09 Simon Marchi <simon.marchi@ericsson.com> + + * gdb.texinfo (Packets): Fix Z0 cmd_list doc referring to + conditional expression. + +2017-07-31 Simon Marchi <simon.marchi@ericsson.com> + + * agentexpr.texi (rot): Fix symbolic description, improve + textual description. + +2017-07-26 Yao Qi <yao.qi@linaro.org> + + * gdb.texinfo (Maintenance Commands): Document command + "maint check xml-descriptions". + +2017-07-26 Yao Qi <yao.qi@linaro.org> + + * gdb.texinfo (Maintenance Commands): Document optional + argument of "maint print c-tdesc". + +2017-07-18 Yao Qi <yao.qi@linaro.org> + + * gdb.texinfo (Maintenance Commands): Improve the doc to + command "maint print c-tdesc". + 2017-06-20 Sergio Durigan Junior <sergiodj@redhat.com> PR gdb/21606 diff --git a/gdb/doc/agentexpr.texi b/gdb/doc/agentexpr.texi index 5668e9c..081e5fa 100644 --- a/gdb/doc/agentexpr.texi +++ b/gdb/doc/agentexpr.texi @@ -396,8 +396,10 @@ is zero, this is the same as @code{dup}; if @var{n} is one, it copies the item under the top item, etc. If @var{n} exceeds the number of items on the stack, terminate with an error. -@item @code{rot} (0x33): @var{a} @var{b} @var{c} => @var{c} @var{b} @var{a} -Rotate the top three items on the stack. +@item @code{rot} (0x33): @var{a} @var{b} @var{c} => @var{c} @var{a} @var{b} +Rotate the top three items on the stack. The top item (c) becomes the third +item, the next-to-top item (b) becomes the top item and the third item (a) from +the top becomes the next-to-top item. @item @code{if_goto} (0x20) @var{offset}: @var{a} @result{} Pop an integer off the stack; if it is non-zero, branch to the given diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 2e16570..bcce2a8 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -2157,7 +2157,7 @@ This command is available when debugging locally on most targets, excluding @item set startup-with-shell @itemx set startup-with-shell on @itemx set startup-with-shell off -@itemx show set startup-with-shell +@itemx show startup-with-shell On Unix systems, by default, if a shell is available on your target, @value{GDBN}) uses it to start your program. Arguments of the @code{run} command are passed to the shell, which does variable @@ -34711,11 +34711,21 @@ checksum. Print the entire architecture configuration. The optional argument @var{file} names the file where the output goes. -@kindex maint print c-tdesc +@kindex maint print c-tdesc @r{[}@var{file}@r{]} @item maint print c-tdesc -Print the current target description (@pxref{Target Descriptions}) as -a C source file. The created source file can be used in @value{GDBN} -when an XML parser is not available to parse the description. +Print the target description (@pxref{Target Descriptions}) as +a C source file. By default, the target description is for the current +target, but if the optional argument @var{file} is provided, that file +is used to produce the description. The @var{file} should be an XML +document, of the form described in @ref{Target Description Format}. +The created source file is built into @value{GDBN} when @value{GDBN} is +built again. This command is used by developers after they add or +modify XML target descriptions. + +@kindex maint check xml-descriptions +@item maint check xml-descriptions @var{dir} +Check that the target descriptions dynamically created by @value{GDBN} +equal the descriptions created from XML files found in @var{dir}. @kindex maint print dummy-frames @item maint print dummy-frames @@ -35980,7 +35990,7 @@ separators. Each expression has the following form: @item X @var{len},@var{expr} @var{len} is the length of the bytecode expression and @var{expr} is the -actual conditional expression in bytecode form. +actual commands expression in bytecode form. @end table diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index d7f985b..f8e6522 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -38,6 +38,10 @@ #include "ax.h" #include "dwarf2loc.h" #include "dwarf2-frame-tailcall.h" +#if GDB_SELF_TEST +#include "selftest.h" +#include "selftest-arch.h" +#endif struct comp_unit; @@ -169,67 +173,11 @@ static CORE_ADDR read_encoded_value (struct comp_unit *unit, gdb_byte encoding, which is unused in that case. */ #define cfa_exp_len cfa_reg -/* Assert that the register set RS is large enough to store gdbarch_num_regs - columns. If necessary, enlarge the register set. */ - -void -dwarf2_frame_state_alloc_regs (struct dwarf2_frame_state_reg_info *rs, - int num_regs) +dwarf2_frame_state::dwarf2_frame_state (CORE_ADDR pc_, struct dwarf2_cie *cie) + : pc (pc_), data_align (cie->data_alignment_factor), + code_align (cie->code_alignment_factor), + retaddr_column (cie->return_address_register) { - size_t size = sizeof (struct dwarf2_frame_state_reg); - - if (num_regs <= rs->num_regs) - return; - - rs->reg = (struct dwarf2_frame_state_reg *) - xrealloc (rs->reg, num_regs * size); - - /* Initialize newly allocated registers. */ - memset (rs->reg + rs->num_regs, 0, (num_regs - rs->num_regs) * size); - rs->num_regs = num_regs; -} - -/* Copy the register columns in register set RS into newly allocated - memory and return a pointer to this newly created copy. */ - -static struct dwarf2_frame_state_reg * -dwarf2_frame_state_copy_regs (struct dwarf2_frame_state_reg_info *rs) -{ - size_t size = rs->num_regs * sizeof (struct dwarf2_frame_state_reg); - struct dwarf2_frame_state_reg *reg; - - reg = (struct dwarf2_frame_state_reg *) xmalloc (size); - memcpy (reg, rs->reg, size); - - return reg; -} - -/* Release the memory allocated to register set RS. */ - -static void -dwarf2_frame_state_free_regs (struct dwarf2_frame_state_reg_info *rs) -{ - if (rs) - { - dwarf2_frame_state_free_regs (rs->prev); - - xfree (rs->reg); - xfree (rs); - } -} - -/* Release the memory allocated to the frame state FS. */ - -static void -dwarf2_frame_state_free (void *p) -{ - struct dwarf2_frame_state *fs = (struct dwarf2_frame_state *) p; - - dwarf2_frame_state_free_regs (fs->initial.prev); - dwarf2_frame_state_free_regs (fs->regs.prev); - xfree (fs->initial.reg); - xfree (fs->regs.reg); - xfree (fs); } @@ -254,7 +202,7 @@ dwarf2_restore_rule (struct gdbarch *gdbarch, ULONGEST reg_num, gdb_assert (fs->initial.reg); reg = dwarf2_frame_adjust_regnum (gdbarch, reg_num, eh_frame_p); - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); /* Check if this register was explicitly initialized in the CIE initial instructions. If not, default the rule to @@ -408,7 +356,7 @@ execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr, reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p); insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp); offset = utmp * fs->data_align; - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET; fs->regs.reg[reg].loc.offset = offset; } @@ -452,7 +400,7 @@ execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr, reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p); insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp); offset = utmp * fs->data_align; - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET; fs->regs.reg[reg].loc.offset = offset; break; @@ -465,14 +413,14 @@ execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr, case DW_CFA_undefined: insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p); - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); fs->regs.reg[reg].how = DWARF2_FRAME_REG_UNDEFINED; break; case DW_CFA_same_value: insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p); - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAME_VALUE; break; @@ -481,7 +429,7 @@ execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr, reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p); insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp); utmp = dwarf2_frame_adjust_regnum (gdbarch, utmp, eh_frame_p); - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_REG; fs->regs.reg[reg].loc.reg = utmp; break; @@ -490,9 +438,7 @@ execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr, { struct dwarf2_frame_state_reg_info *new_rs; - new_rs = XNEW (struct dwarf2_frame_state_reg_info); - *new_rs = fs->regs; - fs->regs.reg = dwarf2_frame_state_copy_regs (&fs->regs); + new_rs = new dwarf2_frame_state_reg_info (fs->regs); fs->regs.prev = new_rs; } break; @@ -508,11 +454,7 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"), paddress (gdbarch, fs->pc)); } else - { - xfree (fs->regs.reg); - fs->regs = *old_rs; - xfree (old_rs); - } + fs->regs = std::move (*old_rs); } break; @@ -559,10 +501,10 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"), case DW_CFA_expression: insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p); - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp); - fs->regs.reg[reg].loc.exp = insn_ptr; - fs->regs.reg[reg].exp_len = utmp; + fs->regs.reg[reg].loc.exp.start = insn_ptr; + fs->regs.reg[reg].loc.exp.len = utmp; fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_EXP; insn_ptr += utmp; break; @@ -572,14 +514,14 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"), reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p); insn_ptr = safe_read_sleb128 (insn_ptr, insn_end, &offset); offset *= fs->data_align; - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET; fs->regs.reg[reg].loc.offset = offset; break; case DW_CFA_val_offset: insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp); offset = utmp * fs->data_align; fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_VAL_OFFSET; @@ -588,7 +530,7 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"), case DW_CFA_val_offset_sf: insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); insn_ptr = safe_read_sleb128 (insn_ptr, insn_end, &offset); offset *= fs->data_align; fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_VAL_OFFSET; @@ -597,10 +539,10 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"), case DW_CFA_val_expression: insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp); - fs->regs.reg[reg].loc.exp = insn_ptr; - fs->regs.reg[reg].exp_len = utmp; + fs->regs.reg[reg].loc.exp.start = insn_ptr; + fs->regs.reg[reg].loc.exp.len = utmp; fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_VAL_EXP; insn_ptr += utmp; break; @@ -630,7 +572,7 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"), reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p); insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp); offset = utmp * fs->data_align; - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET; fs->regs.reg[reg].loc.offset = -offset; break; @@ -654,12 +596,73 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"), if (fs->initial.reg == NULL) { /* Don't allow remember/restore between CIE and FDE programs. */ - dwarf2_frame_state_free_regs (fs->regs.prev); + delete fs->regs.prev; fs->regs.prev = NULL; } return insn_ptr; } + +#if GDB_SELF_TEST + +namespace selftests { + +/* Unit test to function execute_cfa_program. */ + +static void +execute_cfa_program_test (struct gdbarch *gdbarch) +{ + struct dwarf2_fde fde; + struct dwarf2_cie cie; + + memset (&fde, 0, sizeof fde); + memset (&cie, 0, sizeof cie); + + cie.data_alignment_factor = -4; + cie.code_alignment_factor = 2; + fde.cie = &cie; + + dwarf2_frame_state fs (0, fde.cie); + + gdb_byte insns[] = + { + DW_CFA_def_cfa, 1, 4, /* DW_CFA_def_cfa: r1 ofs 4 */ + DW_CFA_offset | 0x2, 1, /* DW_CFA_offset: r2 at cfa-4 */ + DW_CFA_remember_state, + DW_CFA_restore_state, + }; + + const gdb_byte *insn_end = insns + sizeof (insns); + const gdb_byte *out = execute_cfa_program (&fde, insns, insn_end, gdbarch, + 0, &fs); + + SELF_CHECK (out == insn_end); + SELF_CHECK (fs.pc == 0); + + /* The instructions above only use r1 and r2, but the register numbers + used are adjusted by dwarf2_frame_adjust_regnum. */ + auto r1 = dwarf2_frame_adjust_regnum (gdbarch, 1, fde.eh_frame_p); + auto r2 = dwarf2_frame_adjust_regnum (gdbarch, 2, fde.eh_frame_p); + + SELF_CHECK (fs.regs.num_regs == (std::max (r1, r2) + 1)); + + SELF_CHECK (fs.regs.reg[r2].how == DWARF2_FRAME_REG_SAVED_OFFSET); + SELF_CHECK (fs.regs.reg[r2].loc.offset == -4); + + for (auto i = 0; i < fs.regs.num_regs; i++) + if (i != r2) + SELF_CHECK (fs.regs.reg[i].how == DWARF2_FRAME_REG_UNSPECIFIED); + + SELF_CHECK (fs.regs.cfa_reg == 1); + SELF_CHECK (fs.regs.cfa_offset == 4); + SELF_CHECK (fs.regs.cfa_how == CFA_REG_OFFSET); + SELF_CHECK (fs.regs.cfa_exp == NULL); + SELF_CHECK (fs.regs.prev == NULL); +} + +} // namespace selftests +#endif /* GDB_SELF_TEST */ + /* Architecture-specific operations. */ @@ -865,21 +868,14 @@ dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc, { struct dwarf2_fde *fde; CORE_ADDR text_offset; - struct dwarf2_frame_state fs; - - memset (&fs, 0, sizeof (struct dwarf2_frame_state)); - - fs.pc = pc; + CORE_ADDR pc1 = pc; /* Find the correct FDE. */ - fde = dwarf2_frame_find_fde (&fs.pc, &text_offset); + fde = dwarf2_frame_find_fde (&pc1, &text_offset); if (fde == NULL) error (_("Could not compute CFA; needed to translate this expression")); - /* Extract any interesting information from the CIE. */ - fs.data_align = fde->cie->data_alignment_factor; - fs.code_align = fde->cie->code_alignment_factor; - fs.retaddr_column = fde->cie->return_address_register; + dwarf2_frame_state fs (pc1, fde->cie); /* Check for "quirks" - known bugs in producers. */ dwarf2_frame_find_quirks (&fs, fde); @@ -890,7 +886,6 @@ dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc, /* Save the initialized register set. */ fs.initial = fs.regs; - fs.initial.reg = dwarf2_frame_state_copy_regs (&fs.regs); /* Then decode the insns in the FDE up to our target PC. */ execute_cfa_program (fde, fde->instructions, fde->end, gdbarch, pc, &fs); @@ -965,25 +960,13 @@ struct dwarf2_frame_cache int entry_cfa_sp_offset_p; }; -/* A cleanup that sets a pointer to NULL. */ - -static void -clear_pointer_cleanup (void *arg) -{ - void **ptr = (void **) arg; - - *ptr = NULL; -} - static struct dwarf2_frame_cache * dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) { - struct cleanup *reset_cache_cleanup, *old_chain; struct gdbarch *gdbarch = get_frame_arch (this_frame); const int num_regs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); struct dwarf2_frame_cache *cache; - struct dwarf2_frame_state *fs; struct dwarf2_fde *fde; CORE_ADDR entry_pc; const gdb_byte *instr; @@ -995,11 +978,6 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) cache = FRAME_OBSTACK_ZALLOC (struct dwarf2_frame_cache); cache->reg = FRAME_OBSTACK_CALLOC (num_regs, struct dwarf2_frame_state_reg); *this_cache = cache; - reset_cache_cleanup = make_cleanup (clear_pointer_cleanup, this_cache); - - /* Allocate and initialize the frame state. */ - fs = XCNEW (struct dwarf2_frame_state); - old_chain = make_cleanup (dwarf2_frame_state_free, fs); /* Unwind the PC. @@ -1016,41 +994,39 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) get_frame_address_in_block does just this. It's not clear how reliable the method is though; there is the potential for the register state pre-call being different to that on return. */ - fs->pc = get_frame_address_in_block (this_frame); + CORE_ADDR pc1 = get_frame_address_in_block (this_frame); /* Find the correct FDE. */ - fde = dwarf2_frame_find_fde (&fs->pc, &cache->text_offset); + fde = dwarf2_frame_find_fde (&pc1, &cache->text_offset); gdb_assert (fde != NULL); - /* Extract any interesting information from the CIE. */ - fs->data_align = fde->cie->data_alignment_factor; - fs->code_align = fde->cie->code_alignment_factor; - fs->retaddr_column = fde->cie->return_address_register; + /* Allocate and initialize the frame state. */ + struct dwarf2_frame_state fs (pc1, fde->cie); + cache->addr_size = fde->cie->addr_size; /* Check for "quirks" - known bugs in producers. */ - dwarf2_frame_find_quirks (fs, fde); + dwarf2_frame_find_quirks (&fs, fde); /* First decode all the insns in the CIE. */ execute_cfa_program (fde, fde->cie->initial_instructions, fde->cie->end, gdbarch, - get_frame_address_in_block (this_frame), fs); + get_frame_address_in_block (this_frame), &fs); /* Save the initialized register set. */ - fs->initial = fs->regs; - fs->initial.reg = dwarf2_frame_state_copy_regs (&fs->regs); + fs.initial = fs.regs; if (get_frame_func_if_available (this_frame, &entry_pc)) { /* Decode the insns in the FDE up to the entry PC. */ instr = execute_cfa_program (fde, fde->instructions, fde->end, gdbarch, - entry_pc, fs); + entry_pc, &fs); - if (fs->regs.cfa_how == CFA_REG_OFFSET - && (dwarf_reg_to_regnum (gdbarch, fs->regs.cfa_reg) + if (fs.regs.cfa_how == CFA_REG_OFFSET + && (dwarf_reg_to_regnum (gdbarch, fs.regs.cfa_reg) == gdbarch_sp_regnum (gdbarch))) { - cache->entry_cfa_sp_offset = fs->regs.cfa_offset; + cache->entry_cfa_sp_offset = fs.regs.cfa_offset; cache->entry_cfa_sp_offset_p = 1; } } @@ -1059,24 +1035,24 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) /* Then decode the insns in the FDE up to our target PC. */ execute_cfa_program (fde, instr, fde->end, gdbarch, - get_frame_address_in_block (this_frame), fs); + get_frame_address_in_block (this_frame), &fs); TRY { /* Calculate the CFA. */ - switch (fs->regs.cfa_how) + switch (fs.regs.cfa_how) { case CFA_REG_OFFSET: - cache->cfa = read_addr_from_reg (this_frame, fs->regs.cfa_reg); - if (fs->armcc_cfa_offsets_reversed) - cache->cfa -= fs->regs.cfa_offset; + cache->cfa = read_addr_from_reg (this_frame, fs.regs.cfa_reg); + if (fs.armcc_cfa_offsets_reversed) + cache->cfa -= fs.regs.cfa_offset; else - cache->cfa += fs->regs.cfa_offset; + cache->cfa += fs.regs.cfa_offset; break; case CFA_EXP: cache->cfa = - execute_stack_op (fs->regs.cfa_exp, fs->regs.cfa_exp_len, + execute_stack_op (fs.regs.cfa_exp, fs.regs.cfa_exp_len, cache->addr_size, cache->text_offset, this_frame, 0, 0); break; @@ -1090,8 +1066,6 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) if (ex.error == NOT_AVAILABLE_ERROR) { cache->unavailable_retaddr = 1; - do_cleanups (old_chain); - discard_cleanups (reset_cache_cleanup); return cache; } @@ -1114,7 +1088,7 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) { int column; /* CFI speak for "register number". */ - for (column = 0; column < fs->regs.num_regs; column++) + for (column = 0; column < fs.regs.num_regs; column++) { /* Use the GDB register number as the destination index. */ int regnum = dwarf_reg_to_regnum (gdbarch, column); @@ -1134,16 +1108,16 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) problems when a debug info register falls outside of the table. We need a way of iterating through all the valid DWARF2 register numbers. */ - if (fs->regs.reg[column].how == DWARF2_FRAME_REG_UNSPECIFIED) + if (fs.regs.reg[column].how == DWARF2_FRAME_REG_UNSPECIFIED) { if (cache->reg[regnum].how == DWARF2_FRAME_REG_UNSPECIFIED) complaint (&symfile_complaints, _("\ incomplete CFI data; unspecified registers (e.g., %s) at %s"), gdbarch_register_name (gdbarch, regnum), - paddress (gdbarch, fs->pc)); + paddress (gdbarch, fs.pc)); } else - cache->reg[regnum] = fs->regs.reg[column]; + cache->reg[regnum] = fs.regs.reg[column]; } } @@ -1158,7 +1132,7 @@ incomplete CFI data; unspecified registers (e.g., %s) at %s"), || cache->reg[regnum].how == DWARF2_FRAME_REG_RA_OFFSET) { struct dwarf2_frame_state_reg *retaddr_reg = - &fs->regs.reg[fs->retaddr_column]; + &fs.regs.reg[fs.retaddr_column]; /* It seems rather bizarre to specify an "empty" column as the return adress column. However, this is exactly @@ -1167,7 +1141,7 @@ incomplete CFI data; unspecified registers (e.g., %s) at %s"), register corresponding to the return address column. Incidentally, that's how we should treat a return address column specifying "same value" too. */ - if (fs->retaddr_column < fs->regs.num_regs + if (fs.retaddr_column < fs.regs.num_regs && retaddr_reg->how != DWARF2_FRAME_REG_UNSPECIFIED && retaddr_reg->how != DWARF2_FRAME_REG_SAME_VALUE) { @@ -1180,12 +1154,12 @@ incomplete CFI data; unspecified registers (e.g., %s) at %s"), { if (cache->reg[regnum].how == DWARF2_FRAME_REG_RA) { - cache->reg[regnum].loc.reg = fs->retaddr_column; + cache->reg[regnum].loc.reg = fs.retaddr_column; cache->reg[regnum].how = DWARF2_FRAME_REG_SAVED_REG; } else { - cache->retaddr_reg.loc.reg = fs->retaddr_column; + cache->retaddr_reg.loc.reg = fs.retaddr_column; cache->retaddr_reg.how = DWARF2_FRAME_REG_SAVED_REG; } } @@ -1193,12 +1167,10 @@ incomplete CFI data; unspecified registers (e.g., %s) at %s"), } } - if (fs->retaddr_column < fs->regs.num_regs - && fs->regs.reg[fs->retaddr_column].how == DWARF2_FRAME_REG_UNDEFINED) + if (fs.retaddr_column < fs.regs.num_regs + && fs.regs.reg[fs.retaddr_column].how == DWARF2_FRAME_REG_UNDEFINED) cache->undefined_retaddr = 1; - do_cleanups (old_chain); - discard_cleanups (reset_cache_cleanup); return cache; } @@ -1286,8 +1258,8 @@ dwarf2_frame_prev_register (struct frame_info *this_frame, void **this_cache, return frame_unwind_got_register (this_frame, regnum, realnum); case DWARF2_FRAME_REG_SAVED_EXP: - addr = execute_stack_op (cache->reg[regnum].loc.exp, - cache->reg[regnum].exp_len, + addr = execute_stack_op (cache->reg[regnum].loc.exp.start, + cache->reg[regnum].loc.exp.len, cache->addr_size, cache->text_offset, this_frame, cache->cfa, 1); return frame_unwind_got_memory (this_frame, regnum, addr); @@ -1297,8 +1269,8 @@ dwarf2_frame_prev_register (struct frame_info *this_frame, void **this_cache, return frame_unwind_got_constant (this_frame, regnum, addr); case DWARF2_FRAME_REG_SAVED_VAL_EXP: - addr = execute_stack_op (cache->reg[regnum].loc.exp, - cache->reg[regnum].exp_len, + addr = execute_stack_op (cache->reg[regnum].loc.exp.start, + cache->reg[regnum].loc.exp.len, cache->addr_size, cache->text_offset, this_frame, cache->cfa, 1); return frame_unwind_got_constant (this_frame, regnum, addr); @@ -2432,4 +2404,8 @@ _initialize_dwarf2_frame (void) { dwarf2_frame_data = gdbarch_data_register_pre_init (dwarf2_frame_init); dwarf2_frame_objfile_data = register_objfile_data (); + +#if GDB_SELF_TEST + register_self_test_foreach_arch (selftests::execute_cfa_program_test); +#endif } diff --git a/gdb/dwarf2-frame.h b/gdb/dwarf2-frame.h index 9e8668e..2c3d14c 100644 --- a/gdb/dwarf2-frame.h +++ b/gdb/dwarf2-frame.h @@ -74,11 +74,14 @@ struct dwarf2_frame_state_reg union { LONGEST offset; ULONGEST reg; - const gdb_byte *exp; + struct + { + const gdb_byte *start; + ULONGEST len; + } exp; struct value *(*fn) (struct frame_info *this_frame, void **this_cache, int regnum); } loc; - ULONGEST exp_len; enum dwarf2_frame_reg_rule how; }; @@ -91,47 +94,120 @@ enum cfa_how_kind struct dwarf2_frame_state_reg_info { - struct dwarf2_frame_state_reg *reg; - int num_regs; + dwarf2_frame_state_reg_info () = default; + ~dwarf2_frame_state_reg_info () + { + delete prev; + xfree (reg); + } + + /* Copy constructor. */ + dwarf2_frame_state_reg_info (const dwarf2_frame_state_reg_info &src) + : num_regs (src.num_regs), cfa_offset (src.cfa_offset), + cfa_reg (src.cfa_reg), cfa_how (src.cfa_how), cfa_exp (src.cfa_exp), + prev (src.prev) + { + size_t size = src.num_regs * sizeof (struct dwarf2_frame_state_reg); + + reg = (struct dwarf2_frame_state_reg *) xmalloc (size); + memcpy (reg, src.reg, size); + } + + /* Assignment operator for both move-assignment and copy-assignment. */ + dwarf2_frame_state_reg_info& + operator= (dwarf2_frame_state_reg_info rhs) + { + swap (*this, rhs); + return *this; + } + + /* Move constructor. */ + dwarf2_frame_state_reg_info (dwarf2_frame_state_reg_info &&rhs) noexcept + : reg (rhs.reg), num_regs (rhs.num_regs), cfa_offset (rhs.cfa_offset), + cfa_reg (rhs.cfa_reg), cfa_how (rhs.cfa_how), cfa_exp (rhs.cfa_exp), + prev (rhs.prev) + { + rhs.prev = nullptr; + rhs.reg = nullptr; + } - LONGEST cfa_offset; - ULONGEST cfa_reg; - enum cfa_how_kind cfa_how; - const gdb_byte *cfa_exp; +/* Assert that the register set RS is large enough to store gdbarch_num_regs + columns. If necessary, enlarge the register set. */ + void alloc_regs (int num_regs_requested) + { + if (num_regs_requested <= num_regs) + return; + + size_t size = sizeof (struct dwarf2_frame_state_reg); + + reg = (struct dwarf2_frame_state_reg *) + xrealloc (reg, num_regs_requested * size); + + /* Initialize newly allocated registers. */ + memset (reg + num_regs, 0, (num_regs_requested - num_regs) * size); + num_regs = num_regs_requested; + } + + struct dwarf2_frame_state_reg *reg = NULL; + int num_regs = 0; + + LONGEST cfa_offset = 0; + ULONGEST cfa_reg = 0; + enum cfa_how_kind cfa_how = CFA_UNSET; + const gdb_byte *cfa_exp = NULL; /* Used to implement DW_CFA_remember_state. */ - struct dwarf2_frame_state_reg_info *prev; + struct dwarf2_frame_state_reg_info *prev = NULL; + +private: + friend void swap (dwarf2_frame_state_reg_info& lhs, + dwarf2_frame_state_reg_info& rhs) + { + using std::swap; + + swap (lhs.reg, rhs.reg); + swap (lhs.num_regs, rhs.num_regs); + swap (lhs.cfa_offset, rhs.cfa_offset); + swap (lhs.cfa_reg, rhs.cfa_reg); + swap (lhs.cfa_how, rhs.cfa_how); + swap (lhs.cfa_exp, rhs.cfa_exp); + swap (lhs.prev, rhs.prev); + } }; +struct dwarf2_cie; + /* Structure describing a frame state. */ struct dwarf2_frame_state { + dwarf2_frame_state (CORE_ADDR pc, struct dwarf2_cie *cie); + /* Each register save state can be described in terms of a CFA slot, another register, or a location expression. */ - struct dwarf2_frame_state_reg_info regs; + struct dwarf2_frame_state_reg_info regs {}; /* The PC described by the current frame state. */ CORE_ADDR pc; /* Initial register set from the CIE. Used to implement DW_CFA_restore. */ - struct dwarf2_frame_state_reg_info initial; + struct dwarf2_frame_state_reg_info initial {}; /* The information we care about from the CIE. */ - LONGEST data_align; - ULONGEST code_align; - ULONGEST retaddr_column; + const LONGEST data_align; + const ULONGEST code_align; + const ULONGEST retaddr_column; /* Flags for known producer quirks. */ /* The ARM compilers, in DWARF2 mode, assume that DW_CFA_def_cfa and DW_CFA_def_cfa_offset takes a factored offset. */ - int armcc_cfa_offsets_sf; + bool armcc_cfa_offsets_sf = false; /* The ARM compilers, in DWARF2 or DWARF3 mode, may assume that the CFA is defined as REG - OFFSET rather than REG + OFFSET. */ - int armcc_cfa_offsets_reversed; + bool armcc_cfa_offsets_reversed = false; }; /* Set the architecture-specific register state initialization @@ -172,12 +248,6 @@ extern const struct frame_base * CORE_ADDR dwarf2_frame_cfa (struct frame_info *this_frame); -/* Assert that the register set RS is large enough to store gdbarch_num_regs - columns. If necessary, enlarge the register set. */ - -void dwarf2_frame_state_alloc_regs (struct dwarf2_frame_state_reg_info *rs, - int num_regs); - /* Find the CFA information for PC. Return 1 if a register is used for the CFA, or 0 if another diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index 08b0aa2..927d950 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -2121,13 +2121,10 @@ fetch_const_value_from_synthetic_pointer (sect_offset die, LONGEST byte_offset, struct type *type) { struct value *result = NULL; - struct obstack temp_obstack; - struct cleanup *cleanup; const gdb_byte *bytes; LONGEST len; - obstack_init (&temp_obstack); - cleanup = make_cleanup_obstack_free (&temp_obstack); + auto_obstack temp_obstack; bytes = dwarf2_fetch_constant_bytes (die, per_cu, &temp_obstack, &len); if (bytes != NULL) @@ -2144,8 +2141,6 @@ fetch_const_value_from_synthetic_pointer (sect_offset die, LONGEST byte_offset, else result = allocate_optimized_out_value (TYPE_TARGET_TYPE (type)); - do_cleanups (cleanup); - return result; } @@ -2403,7 +2398,9 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, for (i = 0; i < ctx.num_pieces; ++i) bit_size += ctx.pieces[i].size; - if (8 * (subobj_byte_offset + TYPE_LENGTH (subobj_type)) > bit_size) + /* Complain if the expression is larger than the size of the + outer type. */ + if (bit_size > 8 * TYPE_LENGTH (type)) invalid_synthetic_pointer (); c = allocate_piece_closure (per_cu, ctx.num_pieces, ctx.pieces, @@ -3021,10 +3018,11 @@ get_ax_pc (void *baton) void dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc, - struct gdbarch *arch, unsigned int addr_size, - const gdb_byte *op_ptr, const gdb_byte *op_end, + unsigned int addr_size, const gdb_byte *op_ptr, + const gdb_byte *op_end, struct dwarf2_per_cu_data *per_cu) { + gdbarch *arch = expr->gdbarch; int i; std::vector<int> dw_labels, patches; const gdb_byte * const base = op_ptr; @@ -3300,7 +3298,7 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc, &datastart, &datalen); op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); - dwarf2_compile_expr_to_ax (expr, loc, arch, addr_size, datastart, + dwarf2_compile_expr_to_ax (expr, loc, addr_size, datastart, datastart + datalen, per_cu); if (loc->kind == axs_lvalue_register) require_rvalue (expr, loc); @@ -3526,8 +3524,8 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc, { /* Another expression. */ ax_const_l (expr, text_offset); - dwarf2_compile_expr_to_ax (expr, loc, arch, addr_size, - cfa_start, cfa_end, per_cu); + dwarf2_compile_expr_to_ax (expr, loc, addr_size, cfa_start, + cfa_end, per_cu); } loc->kind = axs_lvalue_memory; @@ -3651,9 +3649,8 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc, /* DW_OP_call_ref is currently not supported. */ gdb_assert (block.per_cu == per_cu); - dwarf2_compile_expr_to_ax (expr, loc, arch, addr_size, - block.data, block.data + block.size, - per_cu); + dwarf2_compile_expr_to_ax (expr, loc, addr_size, block.data, + block.data + block.size, per_cu); } break; @@ -4410,8 +4407,8 @@ locexpr_describe_location (struct symbol *symbol, CORE_ADDR addr, any necessary bytecode in AX. */ static void -locexpr_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch, - struct agent_expr *ax, struct axs_value *value) +locexpr_tracepoint_var_ref (struct symbol *symbol, struct agent_expr *ax, + struct axs_value *value) { struct dwarf2_locexpr_baton *dlbaton = (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (symbol); @@ -4420,9 +4417,8 @@ locexpr_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch, if (dlbaton->size == 0) value->optimized_out = 1; else - dwarf2_compile_expr_to_ax (ax, value, gdbarch, addr_size, - dlbaton->data, dlbaton->data + dlbaton->size, - dlbaton->per_cu); + dwarf2_compile_expr_to_ax (ax, value, addr_size, dlbaton->data, + dlbaton->data + dlbaton->size, dlbaton->per_cu); } /* symbol_computed_ops 'generate_c_location' method. */ @@ -4618,8 +4614,8 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr, /* Describe the location of SYMBOL as an agent value in VALUE, generating any necessary bytecode in AX. */ static void -loclist_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch, - struct agent_expr *ax, struct axs_value *value) +loclist_tracepoint_var_ref (struct symbol *symbol, struct agent_expr *ax, + struct axs_value *value) { struct dwarf2_loclist_baton *dlbaton = (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (symbol); @@ -4631,7 +4627,7 @@ loclist_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch, if (size == 0) value->optimized_out = 1; else - dwarf2_compile_expr_to_ax (ax, value, gdbarch, addr_size, data, data + size, + dwarf2_compile_expr_to_ax (ax, value, addr_size, data, data + size, dlbaton->per_cu); } diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h index 9063b6e..db026d3e 100644 --- a/gdb/dwarf2loc.h +++ b/gdb/dwarf2loc.h @@ -270,7 +270,6 @@ extern const struct symbol_block_ops dwarf2_block_frame_base_loclist_funcs; extern void dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc, - struct gdbarch *arch, unsigned int addr_size, const gdb_byte *op_ptr, const gdb_byte *op_end, diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 696c354..d8d049f 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -74,7 +74,7 @@ #include "common/gdb_optional.h" #include "common/underlying.h" #include "common/byte-vector.h" - +#include "filename-seen-cache.h" #include <fcntl.h> #include <sys/types.h> #include <algorithm> @@ -227,85 +227,107 @@ struct tu_stats struct dwarf2_per_objfile { - struct dwarf2_section_info info; - struct dwarf2_section_info abbrev; - struct dwarf2_section_info line; - struct dwarf2_section_info loc; - struct dwarf2_section_info loclists; - struct dwarf2_section_info macinfo; - struct dwarf2_section_info macro; - struct dwarf2_section_info str; - struct dwarf2_section_info line_str; - struct dwarf2_section_info ranges; - struct dwarf2_section_info rnglists; - struct dwarf2_section_info addr; - struct dwarf2_section_info frame; - struct dwarf2_section_info eh_frame; - struct dwarf2_section_info gdb_index; + /* Construct a dwarf2_per_objfile for OBJFILE. NAMES points to the + dwarf2 section names, or is NULL if the standard ELF names are + used. */ + dwarf2_per_objfile (struct objfile *objfile, + const dwarf2_debug_sections *names); - VEC (dwarf2_section_info_def) *types; + ~dwarf2_per_objfile (); + + /* Disable copy. */ + dwarf2_per_objfile (const dwarf2_per_objfile &) = delete; + void operator= (const dwarf2_per_objfile &) = delete; + + /* Free all cached compilation units. */ + void free_cached_comp_units (); +private: + /* This function is mapped across the sections and remembers the + offset and size of each of the debugging sections we are + interested in. */ + void locate_sections (bfd *abfd, asection *sectp, + const dwarf2_debug_sections &names); + +public: + dwarf2_section_info info {}; + dwarf2_section_info abbrev {}; + dwarf2_section_info line {}; + dwarf2_section_info loc {}; + dwarf2_section_info loclists {}; + dwarf2_section_info macinfo {}; + dwarf2_section_info macro {}; + dwarf2_section_info str {}; + dwarf2_section_info line_str {}; + dwarf2_section_info ranges {}; + dwarf2_section_info rnglists {}; + dwarf2_section_info addr {}; + dwarf2_section_info frame {}; + dwarf2_section_info eh_frame {}; + dwarf2_section_info gdb_index {}; + + VEC (dwarf2_section_info_def) *types = NULL; /* Back link. */ - struct objfile *objfile; + struct objfile *objfile = NULL; /* Table of all the compilation units. This is used to locate the target compilation unit of a particular reference. */ - struct dwarf2_per_cu_data **all_comp_units; + struct dwarf2_per_cu_data **all_comp_units = NULL; /* The number of compilation units in ALL_COMP_UNITS. */ - int n_comp_units; + int n_comp_units = 0; /* The number of .debug_types-related CUs. */ - int n_type_units; + int n_type_units = 0; /* The number of elements allocated in all_type_units. If there are skeleton-less TUs, we add them to all_type_units lazily. */ - int n_allocated_type_units; + int n_allocated_type_units = 0; /* The .debug_types-related CUs (TUs). This is stored in malloc space because we may realloc it. */ - struct signatured_type **all_type_units; + struct signatured_type **all_type_units = NULL; /* Table of struct type_unit_group objects. The hash key is the DW_AT_stmt_list value. */ - htab_t type_unit_groups; + htab_t type_unit_groups {}; /* A table mapping .debug_types signatures to its signatured_type entry. This is NULL if the .debug_types section hasn't been read in yet. */ - htab_t signatured_types; + htab_t signatured_types {}; /* Type unit statistics, to see how well the scaling improvements are doing. */ - struct tu_stats tu_stats; + struct tu_stats tu_stats {}; /* A chain of compilation units that are currently read in, so that they can be freed later. */ - struct dwarf2_per_cu_data *read_in_chain; + dwarf2_per_cu_data *read_in_chain = NULL; /* A table mapping DW_AT_dwo_name values to struct dwo_file objects. This is NULL if the table hasn't been allocated yet. */ - htab_t dwo_files; + htab_t dwo_files {}; - /* Non-zero if we've check for whether there is a DWP file. */ - int dwp_checked; + /* True if we've checked for whether there is a DWP file. */ + bool dwp_checked = false; /* The DWP file if there is one, or NULL. */ - struct dwp_file *dwp_file; + struct dwp_file *dwp_file = NULL; /* The shared '.dwz' file, if one exists. This is used when the original data was compressed using 'dwz -m'. */ - struct dwz_file *dwz_file; + struct dwz_file *dwz_file = NULL; - /* A flag indicating wether this objfile has a section loaded at a + /* A flag indicating whether this objfile has a section loaded at a VMA of 0. */ - int has_section_at_zero; + bool has_section_at_zero = false; /* True if we are using the mapped index, or we are faking it for OBJF_READNOW's sake. */ - unsigned char using_index; + bool using_index = false; /* The mapped index, or NULL if .gdb_index is missing or not being used. */ - struct mapped_index *index_table; + mapped_index *index_table = NULL; /* When using index_table, this keeps track of all quick_file_names entries. TUs typically share line table entries with a CU, so we maintain a @@ -314,22 +336,26 @@ struct dwarf2_per_objfile sorted all the TUs into "type unit groups", grouped by their DW_AT_stmt_list value. Therefore the only sharing done here is with a CU and its associated TU group if there is one. */ - htab_t quick_file_names_table; + htab_t quick_file_names_table {}; /* Set during partial symbol reading, to prevent queueing of full symbols. */ - int reading_partial_symbols; + bool reading_partial_symbols = false; /* Table mapping type DIEs to their struct type *. This is NULL if not allocated yet. The mapping is done via (CU/TU + DIE offset) -> type. */ - htab_t die_type_hash; + htab_t die_type_hash {}; /* The CUs we recently read. */ - VEC (dwarf2_per_cu_ptr) *just_read_cus; + VEC (dwarf2_per_cu_ptr) *just_read_cus = NULL; /* Table containing line_header indexed by offset and offset_in_dwz. */ - htab_t line_header_hash; + htab_t line_header_hash {}; + + /* Table containing all filenames. This is an optional because the + table is lazily constructed on first access. */ + gdb::optional<filename_seen_cache> filenames_cache; }; static struct dwarf2_per_objfile *dwarf2_per_objfile; @@ -858,12 +884,11 @@ struct dwo_file sections (for lack of a better name). */ struct dwo_sections sections; - /* The CU in the file. - We only support one because having more than one requires hacking the - dwo_name of each to match, which is highly unlikely to happen. - Doing this means all TUs can share comp_dir: We also assume that - DW_AT_comp_dir across all TUs in a DWO file will be identical. */ - struct dwo_unit *cu; + /* The CUs in the file. + Each element is a struct dwo_unit. Multiple CUs per DWO are supported as + an extension to handle LLVM's Link Time Optimization output (where + multiple source files may be compiled into a single object/dwo pair). */ + htab_t cus; /* Table of TUs in the file. Each element is a struct dwo_unit. */ @@ -1518,8 +1543,6 @@ static const char *get_section_name (const struct dwarf2_section_info *); static const char *get_section_file_name (const struct dwarf2_section_info *); -static void dwarf2_locate_sections (bfd *, asection *, void *); - static void dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu); @@ -2204,6 +2227,52 @@ attr_value_as_address (struct attribute *attr) /* The suffix for an index file. */ #define INDEX_SUFFIX ".gdb-index" +/* See declaration. */ + +dwarf2_per_objfile::dwarf2_per_objfile (struct objfile *objfile_, + const dwarf2_debug_sections *names) + : objfile (objfile_) +{ + if (names == NULL) + names = &dwarf2_elf_names; + + bfd *obfd = objfile->obfd; + + for (asection *sec = obfd->sections; sec != NULL; sec = sec->next) + locate_sections (obfd, sec, *names); +} + +dwarf2_per_objfile::~dwarf2_per_objfile () +{ + /* Cached DIE trees use xmalloc and the comp_unit_obstack. */ + free_cached_comp_units (); + + if (quick_file_names_table) + htab_delete (quick_file_names_table); + + if (line_header_hash) + htab_delete (line_header_hash); + + /* Everything else should be on the objfile obstack. */ +} + +/* See declaration. */ + +void +dwarf2_per_objfile::free_cached_comp_units () +{ + dwarf2_per_cu_data *per_cu = read_in_chain; + dwarf2_per_cu_data **last_chain = &read_in_chain; + while (per_cu != NULL) + { + dwarf2_per_cu_data *next_cu = per_cu->cu->read_in_chain; + + free_heap_comp_unit (per_cu->cu); + *last_chain = next_cu; + per_cu = next_cu; + } +} + /* Try to locate the sections we need for DWARF 2 debugging information and return true if we have enough to do something. NAMES points to the dwarf2 section names, or is NULL if the standard @@ -2221,13 +2290,8 @@ dwarf2_has_info (struct objfile *objfile, struct dwarf2_per_objfile *data = XOBNEW (&objfile->objfile_obstack, struct dwarf2_per_objfile); - memset (data, 0, sizeof (*data)); - set_objfile_data (objfile, dwarf2_objfile_data_key, data); - dwarf2_per_objfile = data; - - bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections, - (void *) names); - dwarf2_per_objfile->objfile = objfile; + dwarf2_per_objfile = new (data) struct dwarf2_per_objfile (objfile, names); + set_objfile_data (objfile, dwarf2_objfile_data_key, dwarf2_per_objfile); } return (!dwarf2_per_objfile->info.is_virtual && dwarf2_per_objfile->info.s.section != NULL @@ -2333,95 +2397,88 @@ section_is_p (const char *section_name, return 0; } -/* This function is mapped across the sections and remembers the - offset and size of each of the debugging sections we are interested - in. */ +/* See declaration. */ -static void -dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames) +void +dwarf2_per_objfile::locate_sections (bfd *abfd, asection *sectp, + const dwarf2_debug_sections &names) { - const struct dwarf2_debug_sections *names; flagword aflag = bfd_get_section_flags (abfd, sectp); - if (vnames == NULL) - names = &dwarf2_elf_names; - else - names = (const struct dwarf2_debug_sections *) vnames; - if ((aflag & SEC_HAS_CONTENTS) == 0) { } - else if (section_is_p (sectp->name, &names->info)) + else if (section_is_p (sectp->name, &names.info)) { - dwarf2_per_objfile->info.s.section = sectp; - dwarf2_per_objfile->info.size = bfd_get_section_size (sectp); + this->info.s.section = sectp; + this->info.size = bfd_get_section_size (sectp); } - else if (section_is_p (sectp->name, &names->abbrev)) + else if (section_is_p (sectp->name, &names.abbrev)) { - dwarf2_per_objfile->abbrev.s.section = sectp; - dwarf2_per_objfile->abbrev.size = bfd_get_section_size (sectp); + this->abbrev.s.section = sectp; + this->abbrev.size = bfd_get_section_size (sectp); } - else if (section_is_p (sectp->name, &names->line)) + else if (section_is_p (sectp->name, &names.line)) { - dwarf2_per_objfile->line.s.section = sectp; - dwarf2_per_objfile->line.size = bfd_get_section_size (sectp); + this->line.s.section = sectp; + this->line.size = bfd_get_section_size (sectp); } - else if (section_is_p (sectp->name, &names->loc)) + else if (section_is_p (sectp->name, &names.loc)) { - dwarf2_per_objfile->loc.s.section = sectp; - dwarf2_per_objfile->loc.size = bfd_get_section_size (sectp); + this->loc.s.section = sectp; + this->loc.size = bfd_get_section_size (sectp); } - else if (section_is_p (sectp->name, &names->loclists)) + else if (section_is_p (sectp->name, &names.loclists)) { - dwarf2_per_objfile->loclists.s.section = sectp; - dwarf2_per_objfile->loclists.size = bfd_get_section_size (sectp); + this->loclists.s.section = sectp; + this->loclists.size = bfd_get_section_size (sectp); } - else if (section_is_p (sectp->name, &names->macinfo)) + else if (section_is_p (sectp->name, &names.macinfo)) { - dwarf2_per_objfile->macinfo.s.section = sectp; - dwarf2_per_objfile->macinfo.size = bfd_get_section_size (sectp); + this->macinfo.s.section = sectp; + this->macinfo.size = bfd_get_section_size (sectp); } - else if (section_is_p (sectp->name, &names->macro)) + else if (section_is_p (sectp->name, &names.macro)) { - dwarf2_per_objfile->macro.s.section = sectp; - dwarf2_per_objfile->macro.size = bfd_get_section_size (sectp); + this->macro.s.section = sectp; + this->macro.size = bfd_get_section_size (sectp); } - else if (section_is_p (sectp->name, &names->str)) + else if (section_is_p (sectp->name, &names.str)) { - dwarf2_per_objfile->str.s.section = sectp; - dwarf2_per_objfile->str.size = bfd_get_section_size (sectp); + this->str.s.section = sectp; + this->str.size = bfd_get_section_size (sectp); } - else if (section_is_p (sectp->name, &names->line_str)) + else if (section_is_p (sectp->name, &names.line_str)) { - dwarf2_per_objfile->line_str.s.section = sectp; - dwarf2_per_objfile->line_str.size = bfd_get_section_size (sectp); + this->line_str.s.section = sectp; + this->line_str.size = bfd_get_section_size (sectp); } - else if (section_is_p (sectp->name, &names->addr)) + else if (section_is_p (sectp->name, &names.addr)) { - dwarf2_per_objfile->addr.s.section = sectp; - dwarf2_per_objfile->addr.size = bfd_get_section_size (sectp); + this->addr.s.section = sectp; + this->addr.size = bfd_get_section_size (sectp); } - else if (section_is_p (sectp->name, &names->frame)) + else if (section_is_p (sectp->name, &names.frame)) { - dwarf2_per_objfile->frame.s.section = sectp; - dwarf2_per_objfile->frame.size = bfd_get_section_size (sectp); + this->frame.s.section = sectp; + this->frame.size = bfd_get_section_size (sectp); } - else if (section_is_p (sectp->name, &names->eh_frame)) + else if (section_is_p (sectp->name, &names.eh_frame)) { - dwarf2_per_objfile->eh_frame.s.section = sectp; - dwarf2_per_objfile->eh_frame.size = bfd_get_section_size (sectp); + this->eh_frame.s.section = sectp; + this->eh_frame.size = bfd_get_section_size (sectp); } - else if (section_is_p (sectp->name, &names->ranges)) + else if (section_is_p (sectp->name, &names.ranges)) { - dwarf2_per_objfile->ranges.s.section = sectp; - dwarf2_per_objfile->ranges.size = bfd_get_section_size (sectp); + this->ranges.s.section = sectp; + this->ranges.size = bfd_get_section_size (sectp); } - else if (section_is_p (sectp->name, &names->rnglists)) + else if (section_is_p (sectp->name, &names.rnglists)) { - dwarf2_per_objfile->rnglists.s.section = sectp; - dwarf2_per_objfile->rnglists.size = bfd_get_section_size (sectp); + this->rnglists.s.section = sectp; + this->rnglists.size = bfd_get_section_size (sectp); } - else if (section_is_p (sectp->name, &names->types)) + else if (section_is_p (sectp->name, &names.types)) { struct dwarf2_section_info type_section; @@ -2429,18 +2486,18 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames) type_section.s.section = sectp; type_section.size = bfd_get_section_size (sectp); - VEC_safe_push (dwarf2_section_info_def, dwarf2_per_objfile->types, + VEC_safe_push (dwarf2_section_info_def, this->types, &type_section); } - else if (section_is_p (sectp->name, &names->gdb_index)) + else if (section_is_p (sectp->name, &names.gdb_index)) { - dwarf2_per_objfile->gdb_index.s.section = sectp; - dwarf2_per_objfile->gdb_index.size = bfd_get_section_size (sectp); + this->gdb_index.s.section = sectp; + this->gdb_index.size = bfd_get_section_size (sectp); } if ((bfd_get_section_flags (abfd, sectp) & (SEC_LOAD | SEC_ALLOC)) && bfd_section_vma (abfd, sectp) == 0) - dwarf2_per_objfile->has_section_at_zero = 1; + this->has_section_at_zero = true; } /* A helper function that decides whether a section is empty, @@ -3079,13 +3136,11 @@ create_addrmap_from_index (struct objfile *objfile, struct mapped_index *index) { struct gdbarch *gdbarch = get_objfile_arch (objfile); const gdb_byte *iter, *end; - struct obstack temp_obstack; struct addrmap *mutable_map; - struct cleanup *cleanup; CORE_ADDR baseaddr; - obstack_init (&temp_obstack); - cleanup = make_cleanup_obstack_free (&temp_obstack); + auto_obstack temp_obstack; + mutable_map = addrmap_create_mutable (&temp_obstack); iter = index->address_table; @@ -3126,7 +3181,6 @@ create_addrmap_from_index (struct objfile *objfile, struct mapped_index *index) objfile->psymtabs_addrmap = addrmap_create_fixed (mutable_map, &objfile->objfile_obstack); - do_cleanups (cleanup); } /* The hash function for strings in the mapped index. This is the same as @@ -3872,10 +3926,10 @@ dw2_lookup_symbol (struct objfile *objfile, int block_index, information (but NAME might contain it). */ if (sym != NULL - && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0) + && SYMBOL_MATCHES_SEARCH_NAME (sym, name)) return stab; if (with_opaque != NULL - && strcmp_iw (SYMBOL_SEARCH_NAME (with_opaque), name) == 0) + && SYMBOL_MATCHES_SEARCH_NAME (with_opaque, name)) stab_best = stab; /* Keep looking through other CUs. */ @@ -4281,64 +4335,75 @@ static void dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun, void *data, int need_fullname) { - int i; - htab_up visited (htab_create_alloc (10, htab_hash_pointer, htab_eq_pointer, - NULL, xcalloc, xfree)); - dw2_setup (objfile); - /* The rule is CUs specify all the files, including those used by - any TU, so there's no need to scan TUs here. - We can ignore file names coming from already-expanded CUs. */ - - for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i) + if (!dwarf2_per_objfile->filenames_cache) { - struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (i); + dwarf2_per_objfile->filenames_cache.emplace (); - if (per_cu->v.quick->compunit_symtab) - { - void **slot = htab_find_slot (visited.get (), - per_cu->v.quick->file_names, - INSERT); + htab_up visited (htab_create_alloc (10, + htab_hash_pointer, htab_eq_pointer, + NULL, xcalloc, xfree)); - *slot = per_cu->v.quick->file_names; - } - } + /* The rule is CUs specify all the files, including those used + by any TU, so there's no need to scan TUs here. We can + ignore file names coming from already-expanded CUs. */ - for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i) - { - int j; - struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); - struct quick_file_names *file_data; - void **slot; - - /* We only need to look at symtabs not already expanded. */ - if (per_cu->v.quick->compunit_symtab) - continue; + for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i) + { + struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (i); - file_data = dw2_get_file_names (per_cu); - if (file_data == NULL) - continue; + if (per_cu->v.quick->compunit_symtab) + { + void **slot = htab_find_slot (visited.get (), + per_cu->v.quick->file_names, + INSERT); - slot = htab_find_slot (visited.get (), file_data, INSERT); - if (*slot) - { - /* Already visited. */ - continue; + *slot = per_cu->v.quick->file_names; + } } - *slot = file_data; - for (j = 0; j < file_data->num_file_names; ++j) + for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i) { - const char *this_real_name; + int j; + struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); + struct quick_file_names *file_data; + void **slot; - if (need_fullname) - this_real_name = dw2_get_real_path (objfile, file_data, j); - else - this_real_name = NULL; - (*fun) (file_data->file_names[j], this_real_name, data); + /* We only need to look at symtabs not already expanded. */ + if (per_cu->v.quick->compunit_symtab) + continue; + + file_data = dw2_get_file_names (per_cu); + if (file_data == NULL) + continue; + + slot = htab_find_slot (visited.get (), file_data, INSERT); + if (*slot) + { + /* Already visited. */ + continue; + } + *slot = file_data; + + for (int j = 0; j < file_data->num_file_names; ++j) + { + const char *filename = file_data->file_names[j]; + dwarf2_per_objfile->filenames_cache->seen (filename); + } } } + + dwarf2_per_objfile->filenames_cache->traverse ([&] (const char *filename) + { + const char *this_real_name; + + if (need_fullname) + this_real_name = gdb_realpath (filename); + else + this_real_name = NULL; + (*fun) (filename, this_real_name, data); + }); } static int @@ -6645,7 +6710,6 @@ static void dwarf2_build_psymtabs_hard (struct objfile *objfile) { struct cleanup *back_to, *addrmap_cleanup; - struct obstack temp_obstack; int i; if (dwarf_read_debug) @@ -6668,8 +6732,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile) /* Create a temporary address map on a temporary obstack. We later copy this to the final obstack. */ - obstack_init (&temp_obstack); - make_cleanup_obstack_free (&temp_obstack); + auto_obstack temp_obstack; objfile->psymtabs_addrmap = addrmap_create_mutable (&temp_obstack); addrmap_cleanup = make_cleanup (psymtabs_addrmap_cleanup, objfile); @@ -9855,72 +9918,76 @@ create_dwo_cu_reader (const struct die_reader_specs *reader, hex_string (dwo_unit->signature)); } -/* Create the dwo_unit for the lone CU in DWO_FILE. +/* Create the dwo_units for the CUs in a DWO_FILE. Note: This function processes DWO files only, not DWP files. */ -static struct dwo_unit * -create_dwo_cu (struct dwo_file *dwo_file) +static void +create_cus_hash_table (struct dwo_file &dwo_file, dwarf2_section_info §ion, + htab_t &cus_htab) { struct objfile *objfile = dwarf2_per_objfile->objfile; - struct dwarf2_section_info *section = &dwo_file->sections.info; + const struct dwarf2_section_info *abbrev_section = &dwo_file.sections.abbrev; const gdb_byte *info_ptr, *end_ptr; - struct create_dwo_cu_data create_dwo_cu_data; - struct dwo_unit *dwo_unit; - dwarf2_read_section (objfile, section); - info_ptr = section->buffer; + dwarf2_read_section (objfile, §ion); + info_ptr = section.buffer; if (info_ptr == NULL) - return NULL; + return; if (dwarf_read_debug) { fprintf_unfiltered (gdb_stdlog, "Reading %s for %s:\n", - get_section_name (section), - get_section_file_name (section)); + get_section_name (§ion), + get_section_file_name (§ion)); } - create_dwo_cu_data.dwo_file = dwo_file; - dwo_unit = NULL; - - end_ptr = info_ptr + section->size; + end_ptr = info_ptr + section.size; while (info_ptr < end_ptr) { struct dwarf2_per_cu_data per_cu; + struct create_dwo_cu_data create_dwo_cu_data; + struct dwo_unit *dwo_unit; + void **slot; + sect_offset sect_off = (sect_offset) (info_ptr - section.buffer); memset (&create_dwo_cu_data.dwo_unit, 0, sizeof (create_dwo_cu_data.dwo_unit)); memset (&per_cu, 0, sizeof (per_cu)); per_cu.objfile = objfile; per_cu.is_debug_types = 0; - per_cu.sect_off = sect_offset (info_ptr - section->buffer); - per_cu.section = section; + per_cu.sect_off = sect_offset (info_ptr - section.buffer); + per_cu.section = §ion; + create_dwo_cu_data.dwo_file = &dwo_file; - init_cutu_and_read_dies_no_follow (&per_cu, dwo_file, - create_dwo_cu_reader, - &create_dwo_cu_data); + init_cutu_and_read_dies_no_follow ( + &per_cu, &dwo_file, create_dwo_cu_reader, &create_dwo_cu_data); + info_ptr += per_cu.length; + + // If the unit could not be parsed, skip it. + if (create_dwo_cu_data.dwo_unit.dwo_file == NULL) + continue; - if (create_dwo_cu_data.dwo_unit.dwo_file != NULL) + if (cus_htab == NULL) + cus_htab = allocate_dwo_unit_table (objfile); + + dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit); + *dwo_unit = create_dwo_cu_data.dwo_unit; + slot = htab_find_slot (cus_htab, dwo_unit, INSERT); + gdb_assert (slot != NULL); + if (*slot != NULL) { - /* If we've already found one, complain. We only support one - because having more than one requires hacking the dwo_name of - each to match, which is highly unlikely to happen. */ - if (dwo_unit != NULL) - { - complaint (&symfile_complaints, - _("Multiple CUs in DWO file %s [in module %s]"), - dwo_file->dwo_name, objfile_name (objfile)); - break; - } + const struct dwo_unit *dup_cu = (const struct dwo_unit *)*slot; + sect_offset dup_sect_off = dup_cu->sect_off; - dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit); - *dwo_unit = create_dwo_cu_data.dwo_unit; + complaint (&symfile_complaints, + _("debug cu entry at offset 0x%x is duplicate to" + " the entry at offset 0x%x, signature %s"), + to_underlying (sect_off), to_underlying (dup_sect_off), + hex_string (dwo_unit->signature)); } - - info_ptr += per_cu.length; + *slot = (void *)dwo_unit; } - - return dwo_unit; } /* DWP file .debug_{cu,tu}_index section format: @@ -10925,7 +10992,7 @@ open_and_init_dwo_file (struct dwarf2_per_cu_data *per_cu, bfd_map_over_sections (dwo_file->dbfd, dwarf2_locate_dwo_sections, &dwo_file->sections); - dwo_file->cu = create_dwo_cu (dwo_file); + create_cus_hash_table (*dwo_file, dwo_file->sections.info, dwo_file->cus); create_debug_types_hash_table (dwo_file, dwo_file->sections.types, dwo_file->tus); @@ -11292,10 +11359,14 @@ lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit, dwo_cutu = (struct dwo_unit *) htab_find (dwo_file->tus, &find_dwo_cutu); } - else if (!is_debug_types && dwo_file->cu) + else if (!is_debug_types && dwo_file->cus) { - if (signature == dwo_file->cu->signature) - dwo_cutu = dwo_file->cu; + struct dwo_unit find_dwo_cutu; + + memset (&find_dwo_cutu, 0, sizeof (find_dwo_cutu)); + find_dwo_cutu.signature = signature; + dwo_cutu = (struct dwo_unit *)htab_find (dwo_file->cus, + &find_dwo_cutu); } if (dwo_cutu != NULL) @@ -14263,15 +14334,12 @@ update_enumeration_type_from_children (struct die_info *die, struct type *type, struct dwarf2_cu *cu) { - struct obstack obstack; struct die_info *child_die; int unsigned_enum = 1; int flag_enum = 1; ULONGEST mask = 0; - struct cleanup *old_chain; - obstack_init (&obstack); - old_chain = make_cleanup_obstack_free (&obstack); + auto_obstack obstack; for (child_die = die->child; child_die != NULL && child_die->tag; @@ -14316,8 +14384,6 @@ update_enumeration_type_from_children (struct die_info *die, TYPE_UNSIGNED (type) = 1; if (flag_enum) TYPE_FLAG_ENUM (type) = 1; - - do_cleanups (old_chain); } /* Given a DW_AT_enumeration_type die, set its type. We do not @@ -17991,7 +18057,9 @@ dwarf2_string_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *c if (attr != NULL) { if (attr->form == DW_FORM_strp || attr->form == DW_FORM_line_strp - || attr->form == DW_FORM_string || attr->form == DW_FORM_GNU_strp_alt) + || attr->form == DW_FORM_string + || attr->form == DW_FORM_GNU_str_index + || attr->form == DW_FORM_GNU_strp_alt) str = DW_STRING (attr); else complaint (&symfile_complaints, @@ -23150,21 +23218,7 @@ free_stack_comp_unit (void *data) static void free_cached_comp_units (void *data) { - struct dwarf2_per_cu_data *per_cu, **last_chain; - - per_cu = dwarf2_per_objfile->read_in_chain; - last_chain = &dwarf2_per_objfile->read_in_chain; - while (per_cu != NULL) - { - struct dwarf2_per_cu_data *next_cu; - - next_cu = per_cu->cu->read_in_chain; - - free_heap_comp_unit (per_cu->cu); - *last_chain = next_cu; - - per_cu = next_cu; - } + dwarf2_per_objfile->free_cached_comp_units (); } /* Increase the age counter on each cached compilation unit, and free @@ -23246,16 +23300,7 @@ dwarf2_free_objfile (struct objfile *objfile) if (dwarf2_per_objfile == NULL) return; - /* Cached DIE trees use xmalloc and the comp_unit_obstack. */ - free_cached_comp_units (NULL); - - if (dwarf2_per_objfile->quick_file_names_table) - htab_delete (dwarf2_per_objfile->quick_file_names_table); - - if (dwarf2_per_objfile->line_header_hash) - htab_delete (dwarf2_per_objfile->line_header_hash); - - /* Everything else should be on the objfile obstack. */ + dwarf2_per_objfile->~dwarf2_per_objfile (); } /* A set of CU "per_cu" pointer, DIE offset, and GDB type pointer. @@ -24126,20 +24171,6 @@ recursively_write_psymbols (struct objfile *objfile, 1); } -/* Closes FILE on scope exit. */ -struct file_closer -{ - explicit file_closer (FILE *file) - : m_file (file) - {} - - ~file_closer () - { fclose (m_file); } - -private: - FILE *m_file; -}; - /* Create an index file for OBJFILE in the directory DIR. */ static void @@ -24161,7 +24192,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir) std::string filename (std::string (dir) + SLASH_STRING + lbasename (objfile_name (objfile)) + INDEX_SUFFIX); - FILE *out_file = gdb_fopen_cloexec (filename.c_str (), "wb"); + FILE *out_file = gdb_fopen_cloexec (filename.c_str (), "wb").release (); if (!out_file) error (_("Can't open `%s' for writing"), filename.c_str ()); @@ -24170,7 +24201,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir) still open. (Don't call anything here that might throw until file_closer is created.) */ gdb::unlinker unlink_file (filename.c_str ()); - file_closer close_out_file (out_file); + gdb_file_up close_out_file (out_file); mapped_symtab symtab; data_buf cu_list; diff --git a/gdb/elfread.c b/gdb/elfread.c index fba2026..ece704c 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -540,9 +540,6 @@ elf_rel_plt_read (minimal_symbol_reader &reader, asection *plt, *relplt, *got_plt; int plt_elf_idx; bfd_size_type reloc_count, reloc; - char *string_buffer = NULL; - size_t string_buffer_size = 0; - struct cleanup *back_to; struct gdbarch *gdbarch = get_objfile_arch (objfile); struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; size_t ptr_size = TYPE_LENGTH (ptr_type); @@ -576,7 +573,7 @@ elf_rel_plt_read (minimal_symbol_reader &reader, if (! bed->s->slurp_reloc_table (obfd, relplt, dyn_symbol_table, TRUE)) return; - back_to = make_cleanup (free_current_contents, &string_buffer); + std::string string_buffer; reloc_count = relplt->size / elf_section_data (relplt)->this_hdr.sh_entsize; for (reloc = 0; reloc < reloc_count; reloc++) @@ -584,11 +581,10 @@ elf_rel_plt_read (minimal_symbol_reader &reader, const char *name; struct minimal_symbol *msym; CORE_ADDR address; + const char *got_suffix = SYMBOL_GOT_PLT_SUFFIX; const size_t got_suffix_len = strlen (SYMBOL_GOT_PLT_SUFFIX); - size_t name_len; name = bfd_asymbol_name (*relplt->relocation[reloc].sym_ptr_ptr); - name_len = strlen (name); address = relplt->relocation[reloc].address; /* Does the pointer reside in the .got.plt section? */ @@ -601,24 +597,16 @@ elf_rel_plt_read (minimal_symbol_reader &reader, OBJFILE the symbol is undefined and the objfile having NAME defined may not yet have been loaded. */ - if (string_buffer_size < name_len + got_suffix_len + 1) - { - string_buffer_size = 2 * (name_len + got_suffix_len); - string_buffer = (char *) xrealloc (string_buffer, string_buffer_size); - } - memcpy (string_buffer, name, name_len); - memcpy (&string_buffer[name_len], SYMBOL_GOT_PLT_SUFFIX, - got_suffix_len + 1); + string_buffer.assign (name); + string_buffer.append (got_suffix, got_suffix + got_suffix_len); - msym = record_minimal_symbol (reader, string_buffer, - name_len + got_suffix_len, + msym = record_minimal_symbol (reader, string_buffer.c_str (), + string_buffer.size (), true, address, mst_slot_got_plt, got_plt, objfile); if (msym) SET_MSYMBOL_SIZE (msym, ptr_size); } - - do_cleanups (back_to); } /* The data pointer is htab_t for gnu_ifunc_record_cache_unchecked. */ @@ -407,7 +407,6 @@ exec_file_attach (const char *filename, int from_tty) static void exec_file_command (char *args, int from_tty) { - char **argv; char *filename; if (from_tty && target_has_execution @@ -417,13 +416,11 @@ exec_file_command (char *args, int from_tty) if (args) { - struct cleanup *cleanups; - /* Scan through the args and pick up the first non option arg as the filename. */ - argv = gdb_buildargv (args); - cleanups = make_cleanup_freeargv (argv); + gdb_argv built_argv (args); + char **argv = built_argv.get (); for (; (*argv != NULL) && (**argv == '-'); argv++) {; @@ -431,11 +428,8 @@ exec_file_command (char *args, int from_tty) if (*argv == NULL) error (_("No executable file name was specified")); - filename = tilde_expand (*argv); - make_cleanup (xfree, filename); - exec_file_attach (filename, from_tty); - - do_cleanups (cleanups); + gdb::unique_xmalloc_ptr<char> filename (tilde_expand (*argv)); + exec_file_attach (filename.get (), from_tty); } else exec_file_attach (NULL, from_tty); diff --git a/gdb/f-lang.c b/gdb/f-lang.c index b623f19..80bb65a 100644 --- a/gdb/f-lang.c +++ b/gdb/f-lang.c @@ -228,11 +228,14 @@ f_word_break_characters (void) /* Consider the modules separator :: as a valid symbol name character class. */ -static VEC (char_ptr) * -f_make_symbol_completion_list (const char *text, const char *word, - enum type_code code) +static void +f_collect_symbol_completion_matches (completion_tracker &tracker, + complete_symbol_mode mode, + const char *text, const char *word, + enum type_code code) { - return default_make_symbol_completion_list_break_on (text, word, ":", code); + default_collect_symbol_completion_matches_break_on (tracker, mode, + text, word, ":", code); } static const char *f_extensions[] = @@ -242,7 +245,7 @@ static const char *f_extensions[] = NULL }; -const struct language_defn f_language_defn = +extern const struct language_defn f_language_defn = { "fortran", "Fortran", @@ -282,7 +285,7 @@ const struct language_defn f_language_defn = 0, /* arrays are first-class (not c-style) */ 1, /* String lower bound */ f_word_break_characters, - f_make_symbol_completion_list, + f_collect_symbol_completion_matches, f_language_arch_info, default_print_array_index, default_pass_by_reference, @@ -367,6 +370,4 @@ void _initialize_f_language (void) { f_type_data = gdbarch_data_register_post_init (build_fortran_types); - - add_language (&f_language_defn); } diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c index ef5ad1e..6ba6a01 100644 --- a/gdb/fbsd-nat.c +++ b/gdb/fbsd-nat.c @@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "defs.h" +#include "byte-vector.h" #include "gdbcore.h" #include "inferior.h" #include "regcache.h" @@ -28,15 +29,20 @@ #include <sys/types.h> #include <sys/procfs.h> #include <sys/ptrace.h> +#include <sys/signal.h> #include <sys/sysctl.h> -#ifdef HAVE_KINFO_GETVMMAP #include <sys/user.h> +#ifdef HAVE_KINFO_GETVMMAP #include <libutil.h> +#else +#include "filestuff.h" #endif #include "elf-bfd.h" #include "fbsd-nat.h" +#include <list> + /* Return the name of a file that can be opened to get the symbols for the child process identified by PID. */ @@ -72,6 +78,14 @@ fbsd_pid_to_exec_file (struct target_ops *self, int pid) } #ifdef HAVE_KINFO_GETVMMAP +/* Deleter for std::unique_ptr that invokes free. */ + +template <typename T> +struct free_deleter +{ + void operator() (T *ptr) const { free (ptr); } +}; + /* Iterate over all the memory regions in the current inferior, calling FUNC for each memory region. OBFD is passed as the last argument to FUNC. */ @@ -81,20 +95,17 @@ fbsd_find_memory_regions (struct target_ops *self, find_memory_region_ftype func, void *obfd) { pid_t pid = ptid_get_pid (inferior_ptid); - struct kinfo_vmentry *vmentl, *kve; + struct kinfo_vmentry *kve; uint64_t size; - struct cleanup *cleanup; int i, nitems; - vmentl = kinfo_getvmmap (pid, &nitems); + std::unique_ptr<struct kinfo_vmentry, free_deleter<struct kinfo_vmentry>> + vmentl (kinfo_getvmmap (pid, &nitems)); if (vmentl == NULL) perror_with_name (_("Couldn't fetch VM map entries.")); - cleanup = make_cleanup (free, vmentl); - for (i = 0; i < nitems; i++) + for (i = 0, kve = vmentl.get (); i < nitems; i++, kve++) { - kve = &vmentl[i]; - /* Skip unreadable segments and those where MAP_NOCORE has been set. */ if (!(kve->kve_protection & KVME_PROT_READ) || kve->kve_flags & KVME_FLAG_NOCOREDUMP) @@ -125,7 +136,6 @@ fbsd_find_memory_regions (struct target_ops *self, kve->kve_protection & KVME_PROT_WRITE, kve->kve_protection & KVME_PROT_EXEC, 1, obfd); } - do_cleanups (cleanup); return 0; } #else @@ -159,26 +169,21 @@ fbsd_find_memory_regions (struct target_ops *self, find_memory_region_ftype func, void *obfd) { pid_t pid = ptid_get_pid (inferior_ptid); - char *mapfilename; - FILE *mapfile; unsigned long start, end, size; char protection[4]; int read, write, exec; - struct cleanup *cleanup; - mapfilename = xstrprintf ("/proc/%ld/map", (long) pid); - cleanup = make_cleanup (xfree, mapfilename); - mapfile = fopen (mapfilename, "r"); + std::string mapfilename = string_printf ("/proc/%ld/map", (long) pid); + gdb_file_up mapfile (fopen (mapfilename.c_str (), "r")); if (mapfile == NULL) - error (_("Couldn't open %s."), mapfilename); - make_cleanup_fclose (mapfile); + error (_("Couldn't open %s."), mapfilename.c_str ()); if (info_verbose) fprintf_filtered (gdb_stdout, - "Reading memory regions from %s\n", mapfilename); + "Reading memory regions from %s\n", mapfilename.c_str ()); /* Now iterate until end-of-file. */ - while (fbsd_read_mapping (mapfile, &start, &end, &protection[0])) + while (fbsd_read_mapping (mapfile.get (), &start, &end, &protection[0])) { size = end - start; @@ -201,7 +206,6 @@ fbsd_find_memory_regions (struct target_ops *self, func (start, size, read, write, exec, 1, obfd); } - do_cleanups (cleanup); return 0; } #endif @@ -216,6 +220,135 @@ static enum target_xfer_status (*super_xfer_partial) (struct target_ops *ops, ULONGEST len, ULONGEST *xfered_len); +#ifdef PT_LWPINFO +/* Return the size of siginfo for the current inferior. */ + +#ifdef __LP64__ +union sigval32 { + int sival_int; + uint32_t sival_ptr; +}; + +/* This structure matches the naming and layout of `siginfo_t' in + <sys/signal.h>. In particular, the `si_foo' macros defined in that + header can be used with both types to copy fields in the `_reason' + union. */ + +struct siginfo32 +{ + int si_signo; + int si_errno; + int si_code; + __pid_t si_pid; + __uid_t si_uid; + int si_status; + uint32_t si_addr; + union sigval32 si_value; + union + { + struct + { + int _trapno; + } _fault; + struct + { + int _timerid; + int _overrun; + } _timer; + struct + { + int _mqd; + } _mesgq; + struct + { + int32_t _band; + } _poll; + struct + { + int32_t __spare1__; + int __spare2__[7]; + } __spare__; + } _reason; +}; +#endif + +static size_t +fbsd_siginfo_size () +{ +#ifdef __LP64__ + struct gdbarch *gdbarch = get_frame_arch (get_current_frame ()); + + /* Is the inferior 32-bit? If so, use the 32-bit siginfo size. */ + if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32) + return sizeof (struct siginfo32); +#endif + return sizeof (siginfo_t); +} + +/* Convert a native 64-bit siginfo object to a 32-bit object. Note + that FreeBSD doesn't support writing to $_siginfo, so this only + needs to convert one way. */ + +static void +fbsd_convert_siginfo (siginfo_t *si) +{ +#ifdef __LP64__ + struct gdbarch *gdbarch = get_frame_arch (get_current_frame ()); + + /* Is the inferior 32-bit? If not, nothing to do. */ + if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word != 32) + return; + + struct siginfo32 si32; + + si32.si_signo = si->si_signo; + si32.si_errno = si->si_errno; + si32.si_code = si->si_code; + si32.si_pid = si->si_pid; + si32.si_uid = si->si_uid; + si32.si_status = si->si_status; + si32.si_addr = (uintptr_t) si->si_addr; + + /* If sival_ptr is being used instead of sival_int on a big-endian + platform, then sival_int will be zero since it holds the upper + 32-bits of the pointer value. */ +#if _BYTE_ORDER == _BIG_ENDIAN + if (si->si_value.sival_int == 0) + si32.si_value.sival_ptr = (uintptr_t) si->si_value.sival_ptr; + else + si32.si_value.sival_int = si->si_value.sival_int; +#else + si32.si_value.sival_int = si->si_value.sival_int; +#endif + + /* Always copy the spare fields and then possibly overwrite them for + signal-specific or code-specific fields. */ + si32._reason.__spare__.__spare1__ = si->_reason.__spare__.__spare1__; + for (int i = 0; i < 7; i++) + si32._reason.__spare__.__spare2__[i] = si->_reason.__spare__.__spare2__[i]; + switch (si->si_signo) { + case SIGILL: + case SIGFPE: + case SIGSEGV: + case SIGBUS: + si32.si_trapno = si->si_trapno; + break; + } + switch (si->si_code) { + case SI_TIMER: + si32.si_timerid = si->si_timerid; + si32.si_overrun = si->si_overrun; + break; + case SI_MESGQ: + si32.si_mqd = si->si_mqd; + break; + } + + memcpy(si, &si32, sizeof (si32)); +#endif +} +#endif + /* Implement the "to_xfer_partial target_ops" method. */ static enum target_xfer_status @@ -228,10 +361,42 @@ fbsd_xfer_partial (struct target_ops *ops, enum target_object object, switch (object) { +#ifdef PT_LWPINFO + case TARGET_OBJECT_SIGNAL_INFO: + { + struct ptrace_lwpinfo pl; + size_t siginfo_size; + + /* FreeBSD doesn't support writing to $_siginfo. */ + if (writebuf != NULL) + return TARGET_XFER_E_IO; + + if (inferior_ptid.lwp_p ()) + pid = inferior_ptid.lwp (); + + siginfo_size = fbsd_siginfo_size (); + if (offset > siginfo_size) + return TARGET_XFER_E_IO; + + if (ptrace (PT_LWPINFO, pid, (PTRACE_TYPE_ARG3) &pl, sizeof (pl)) == -1) + return TARGET_XFER_E_IO; + + if (!(pl.pl_flags & PL_FLAG_SI)) + return TARGET_XFER_E_IO; + + fbsd_convert_siginfo (&pl.pl_siginfo); + if (offset + len > siginfo_size) + len = siginfo_size - offset; + + memcpy (readbuf, ((gdb_byte *) &pl.pl_siginfo) + offset, len); + *xfered_len = len; + return TARGET_XFER_OK; + } +#endif case TARGET_OBJECT_AUXV: { - struct cleanup *cleanup = make_cleanup (null_cleanup, NULL); - unsigned char *buf; + gdb::byte_vector buf_storage; + gdb_byte *buf; size_t buflen; int mib[4]; @@ -249,8 +414,8 @@ fbsd_xfer_partial (struct target_ops *ops, enum target_object object, else { buflen = offset + len; - buf = XCNEWVEC (unsigned char, buflen); - cleanup = make_cleanup (xfree, buf); + buf_storage.resize (buflen); + buf = buf_storage.data (); } if (sysctl (mib, 4, buf, &buflen, NULL, 0) == 0) { @@ -264,11 +429,9 @@ fbsd_xfer_partial (struct target_ops *ops, enum target_object object, else buflen = 0; } - do_cleanups (cleanup); *xfered_len = buflen; return (buflen == 0) ? TARGET_XFER_EOF : TARGET_XFER_OK; } - do_cleanups (cleanup); return TARGET_XFER_E_IO; } default: @@ -462,8 +625,6 @@ fbsd_enable_proc_events (pid_t pid) static void fbsd_add_threads (pid_t pid) { - struct cleanup *cleanup; - lwpid_t *lwps; int i, nlwps; gdb_assert (!in_thread_list (pid_to_ptid (pid))); @@ -471,16 +632,16 @@ fbsd_add_threads (pid_t pid) if (nlwps == -1) perror_with_name (("ptrace")); - lwps = XCNEWVEC (lwpid_t, nlwps); - cleanup = make_cleanup (xfree, lwps); + gdb::unique_xmalloc_ptr<lwpid_t> lwps (XCNEWVEC (lwpid_t, nlwps)); - nlwps = ptrace (PT_GETLWPLIST, pid, (caddr_t) lwps, nlwps); + nlwps = ptrace (PT_GETLWPLIST, pid, (caddr_t) lwps.get (), nlwps); if (nlwps == -1) perror_with_name (("ptrace")); for (i = 0; i < nlwps; i++) { - ptid_t ptid = ptid_build (pid, lwps[i], 0); + lwpid_t lwp = lwps.get ()[i]; + ptid_t ptid = ptid_build (pid, lwp, 0); if (!in_thread_list (ptid)) { @@ -489,7 +650,7 @@ fbsd_add_threads (pid_t pid) /* Don't add exited threads. Note that this is only called when attaching to a multi-threaded process. */ - if (ptrace (PT_LWPINFO, lwps[i], (caddr_t) &pl, sizeof pl) == -1) + if (ptrace (PT_LWPINFO, lwp, (caddr_t) &pl, sizeof pl) == -1) perror_with_name (("ptrace")); if (pl.pl_flags & PL_FLAG_EXITED) continue; @@ -497,11 +658,10 @@ fbsd_add_threads (pid_t pid) if (debug_fbsd_lwp) fprintf_unfiltered (gdb_stdlog, "FLWP: adding thread for LWP %u\n", - lwps[i]); + lwp); add_thread (ptid); } } - do_cleanups (cleanup); } /* Implement the "to_update_thread_list" target_ops method. */ @@ -554,13 +714,7 @@ fbsd_update_thread_list (struct target_ops *ops) sake. FreeBSD versions newer than 9.1 contain both fixes. */ -struct fbsd_fork_info -{ - struct fbsd_fork_info *next; - ptid_t ptid; -}; - -static struct fbsd_fork_info *fbsd_pending_children; +static std::list<ptid_t> fbsd_pending_children; /* Record a new child process event that is reported before the corresponding fork event in the parent. */ @@ -568,11 +722,7 @@ static struct fbsd_fork_info *fbsd_pending_children; static void fbsd_remember_child (ptid_t pid) { - struct fbsd_fork_info *info = XCNEW (struct fbsd_fork_info); - - info->ptid = pid; - info->next = fbsd_pending_children; - fbsd_pending_children = info; + fbsd_pending_children.push_front (pid); } /* Check for a previously-recorded new child process event for PID. @@ -581,39 +731,26 @@ fbsd_remember_child (ptid_t pid) static ptid_t fbsd_is_child_pending (pid_t pid) { - struct fbsd_fork_info *info, *prev; - ptid_t ptid; - - prev = NULL; - for (info = fbsd_pending_children; info; prev = info, info = info->next) - { - if (ptid_get_pid (info->ptid) == pid) - { - if (prev == NULL) - fbsd_pending_children = info->next; - else - prev->next = info->next; - ptid = info->ptid; - xfree (info); - return ptid; - } - } + for (auto it = fbsd_pending_children.begin (); + it != fbsd_pending_children.end (); it++) + if (it->pid () == pid) + { + ptid_t ptid = *it; + fbsd_pending_children.erase (it); + return ptid; + } return null_ptid; } #ifndef PTRACE_VFORK -static struct fbsd_fork_info *fbsd_pending_vfork_done; +static std::forward_list<ptid_t> fbsd_pending_vfork_done; /* Record a pending vfork done event. */ static void fbsd_add_vfork_done (ptid_t pid) { - struct fbsd_fork_info *info = XCNEW (struct fbsd_fork_info); - - info->ptid = pid; - info->next = fbsd_pending_vfork_done; - fbsd_pending_vfork_done = info; + fbsd_pending_vfork_done.push_front (pid); } /* Check for a pending vfork done event for a specific PID. */ @@ -621,13 +758,10 @@ fbsd_add_vfork_done (ptid_t pid) static int fbsd_is_vfork_done_pending (pid_t pid) { - struct fbsd_fork_info *info; - - for (info = fbsd_pending_vfork_done; info != NULL; info = info->next) - { - if (ptid_get_pid (info->ptid) == pid) - return 1; - } + for (auto it = fbsd_pending_vfork_done.begin (); + it != fbsd_pending_vfork_done.end (); it++) + if (it->pid () == pid) + return 1; return 0; } @@ -637,15 +771,10 @@ fbsd_is_vfork_done_pending (pid_t pid) static ptid_t fbsd_next_vfork_done (void) { - struct fbsd_fork_info *info; - ptid_t ptid; - - if (fbsd_pending_vfork_done != NULL) + if (!fbsd_pending_vfork_done.empty ()) { - info = fbsd_pending_vfork_done; - fbsd_pending_vfork_done = info->next; - ptid = info->ptid; - xfree (info); + ptid_t ptid = fbsd_pending_vfork_done.front (); + fbsd_pending_vfork_done.pop_front (); return ptid; } return null_ptid; diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c index b834ce3..6f30197 100644 --- a/gdb/fbsd-tdep.c +++ b/gdb/fbsd-tdep.c @@ -30,6 +30,48 @@ #include "fbsd-tdep.h" +/* FreeBSD kernels 12.0 and later include a copy of the + 'ptrace_lwpinfo' structure returned by the PT_LWPINFO ptrace + operation in an ELF core note (NT_FREEBSD_PTLWPINFO) for each LWP. + The constants below define the offset of field members and flags in + this structure used by methods in this file. Note that the + 'ptrace_lwpinfo' struct in the note is preceded by a 4 byte integer + containing the size of the structure. */ + +#define LWPINFO_OFFSET 0x4 + +/* Offsets in ptrace_lwpinfo. */ +#define LWPINFO_PL_FLAGS 0x8 +#define LWPINFO64_PL_SIGINFO 0x30 +#define LWPINFO32_PL_SIGINFO 0x2c + +/* Flags in pl_flags. */ +#define PL_FLAG_SI 0x20 /* siginfo is valid */ + +/* Sizes of siginfo_t. */ +#define SIZE64_SIGINFO_T 80 +#define SIZE32_SIGINFO_T 64 + +static struct gdbarch_data *fbsd_gdbarch_data_handle; + +struct fbsd_gdbarch_data + { + struct type *siginfo_type; + }; + +static void * +init_fbsd_gdbarch_data (struct gdbarch *gdbarch) +{ + return GDBARCH_OBSTACK_ZALLOC (gdbarch, struct fbsd_gdbarch_data); +} + +static struct fbsd_gdbarch_data * +get_fbsd_gdbarch_data (struct gdbarch *gdbarch) +{ + return ((struct fbsd_gdbarch_data *) + gdbarch_data (gdbarch, fbsd_gdbarch_data_handle)); +} + /* This is how we want PTIDs from core files to be printed. */ static const char * @@ -55,7 +97,6 @@ fbsd_core_thread_name (struct gdbarch *gdbarch, struct thread_info *thr) static char buf[80]; struct bfd_section *section; bfd_size_type size; - char sectionstr[32]; if (ptid_get_lwp (thr->ptid) != 0) { @@ -66,9 +107,9 @@ fbsd_core_thread_name (struct gdbarch *gdbarch, struct thread_info *thr) structure. Rather than define the full structure here, just extract the null-terminated name from the start of the note. */ - xsnprintf (sectionstr, sizeof sectionstr, ".thrmisc/%ld", - ptid_get_lwp (thr->ptid)); - section = bfd_get_section_by_name (core_bfd, sectionstr); + thread_section_name section_name (".thrmisc", thr->ptid); + + section = bfd_get_section_by_name (core_bfd, section_name.c_str ()); if (section != NULL && bfd_section_size (core_bfd, section) > 0) { /* Truncate the name if it is longer than "buf". */ @@ -94,6 +135,51 @@ fbsd_core_thread_name (struct gdbarch *gdbarch, struct thread_info *thr) return NULL; } +/* Implement the "core_xfer_siginfo" gdbarch method. */ + +static LONGEST +fbsd_core_xfer_siginfo (struct gdbarch *gdbarch, gdb_byte *readbuf, + ULONGEST offset, ULONGEST len) +{ + size_t siginfo_size; + + if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32) + siginfo_size = SIZE32_SIGINFO_T; + else + siginfo_size = SIZE64_SIGINFO_T; + if (offset > siginfo_size) + return -1; + + thread_section_name section_name (".note.freebsdcore.lwpinfo", inferior_ptid); + asection *section = bfd_get_section_by_name (core_bfd, section_name.c_str ()); + if (section == NULL) + return -1; + + gdb_byte buf[4]; + if (!bfd_get_section_contents (core_bfd, section, buf, + LWPINFO_OFFSET + LWPINFO_PL_FLAGS, 4)) + return -1; + + int pl_flags = extract_signed_integer (buf, 4, gdbarch_byte_order (gdbarch)); + if (!(pl_flags & PL_FLAG_SI)) + return -1; + + if (offset + len > siginfo_size) + len = siginfo_size - offset; + + ULONGEST siginfo_offset; + if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32) + siginfo_offset = LWPINFO_OFFSET + LWPINFO32_PL_SIGINFO; + else + siginfo_offset = LWPINFO_OFFSET + LWPINFO64_PL_SIGINFO; + + if (!bfd_get_section_contents (core_bfd, section, readbuf, + siginfo_offset + offset, len)) + return -1; + + return len; +} + static int find_signalled_thread (struct thread_info *info, void *data) { @@ -314,6 +400,97 @@ fbsd_print_auxv_entry (struct gdbarch *gdbarch, struct ui_file *file, fprint_auxv_entry (file, name, description, format, type, val); } +/* Implement the "get_siginfo_type" gdbarch method. */ + +static struct type * +fbsd_get_siginfo_type (struct gdbarch *gdbarch) +{ + struct fbsd_gdbarch_data *fbsd_gdbarch_data; + struct type *int_type, *int32_type, *uint32_type, *long_type, *void_ptr_type; + struct type *uid_type, *pid_type; + struct type *sigval_type, *reason_type; + struct type *siginfo_type; + struct type *type; + + fbsd_gdbarch_data = get_fbsd_gdbarch_data (gdbarch); + if (fbsd_gdbarch_data->siginfo_type != NULL) + return fbsd_gdbarch_data->siginfo_type; + + int_type = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), + 0, "int"); + int32_type = arch_integer_type (gdbarch, 32, 0, "int32_t"); + uint32_type = arch_integer_type (gdbarch, 32, 1, "uint32_t"); + long_type = arch_integer_type (gdbarch, gdbarch_long_bit (gdbarch), + 0, "long"); + void_ptr_type = lookup_pointer_type (builtin_type (gdbarch)->builtin_void); + + /* union sigval */ + sigval_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); + TYPE_NAME (sigval_type) = xstrdup ("sigval"); + append_composite_type_field (sigval_type, "sival_int", int_type); + append_composite_type_field (sigval_type, "sival_ptr", void_ptr_type); + + /* __pid_t */ + pid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF, + TYPE_LENGTH (int32_type), "__pid_t"); + TYPE_TARGET_TYPE (pid_type) = int32_type; + TYPE_TARGET_STUB (pid_type) = 1; + + /* __uid_t */ + uid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF, + TYPE_LENGTH (uint32_type), "__uid_t"); + TYPE_TARGET_TYPE (uid_type) = uint32_type; + TYPE_TARGET_STUB (uid_type) = 1; + + /* _reason */ + reason_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); + + /* _fault */ + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); + append_composite_type_field (type, "si_trapno", int_type); + append_composite_type_field (reason_type, "_fault", type); + + /* _timer */ + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); + append_composite_type_field (type, "si_timerid", int_type); + append_composite_type_field (type, "si_overrun", int_type); + append_composite_type_field (reason_type, "_timer", type); + + /* _mesgq */ + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); + append_composite_type_field (type, "si_mqd", int_type); + append_composite_type_field (reason_type, "_mesgq", type); + + /* _poll */ + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); + append_composite_type_field (type, "si_band", long_type); + append_composite_type_field (reason_type, "_poll", type); + + /* __spare__ */ + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); + append_composite_type_field (type, "__spare1__", long_type); + append_composite_type_field (type, "__spare2__", + init_vector_type (int_type, 7)); + append_composite_type_field (reason_type, "__spare__", type); + + /* struct siginfo */ + siginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); + TYPE_NAME (siginfo_type) = xstrdup ("siginfo"); + append_composite_type_field (siginfo_type, "si_signo", int_type); + append_composite_type_field (siginfo_type, "si_errno", int_type); + append_composite_type_field (siginfo_type, "si_code", int_type); + append_composite_type_field (siginfo_type, "si_pid", pid_type); + append_composite_type_field (siginfo_type, "si_uid", uid_type); + append_composite_type_field (siginfo_type, "si_status", int_type); + append_composite_type_field (siginfo_type, "si_addr", void_ptr_type); + append_composite_type_field (siginfo_type, "si_value", sigval_type); + append_composite_type_field (siginfo_type, "_reason", reason_type); + + fbsd_gdbarch_data->siginfo_type = siginfo_type; + + return siginfo_type; +} + /* Implement the "get_syscall_number" gdbarch method. */ static LONGEST @@ -337,10 +514,22 @@ fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { set_gdbarch_core_pid_to_str (gdbarch, fbsd_core_pid_to_str); set_gdbarch_core_thread_name (gdbarch, fbsd_core_thread_name); + set_gdbarch_core_xfer_siginfo (gdbarch, fbsd_core_xfer_siginfo); set_gdbarch_make_corefile_notes (gdbarch, fbsd_make_corefile_notes); set_gdbarch_print_auxv_entry (gdbarch, fbsd_print_auxv_entry); + set_gdbarch_get_siginfo_type (gdbarch, fbsd_get_siginfo_type); /* `catch syscall' */ set_xml_syscall_file_name (gdbarch, "syscalls/freebsd.xml"); set_gdbarch_get_syscall_number (gdbarch, fbsd_get_syscall_number); } + +/* Provide a prototype to silence -Wmissing-prototypes. */ +extern initialize_file_ftype _initialize_fbsd_tdep; + +void +_initialize_fbsd_tdep (void) +{ + fbsd_gdbarch_data_handle = + gdbarch_data_register_post_init (init_fbsd_gdbarch_data); +} diff --git a/gdb/features/Makefile b/gdb/features/Makefile index 3bc8b5a..df24d74 100644 --- a/gdb/features/Makefile +++ b/gdb/features/Makefile @@ -47,21 +47,21 @@ WHICH = aarch64 \ arm/arm-with-iwmmxt arm/arm-with-vfpv2 arm/arm-with-vfpv3 \ arm/arm-with-neon \ i386/i386 i386/i386-linux \ - i386/i386-mmx i386/i386-mmx-linux \ + i386/i386-mmx-linux \ i386/amd64 i386/amd64-linux \ - i386/i386-avx i386/i386-avx-linux \ - i386/i386-mpx i386/i386-mpx-linux \ - i386/i386-avx-mpx i386/i386-avx-mpx-linux \ - i386/i386-avx-avx512 i386/i386-avx-avx512-linux \ - i386/i386-avx-mpx-avx512-pku i386/i386-avx-mpx-avx512-pku-linux \ - i386/amd64-avx i386/amd64-avx-linux \ - i386/amd64-mpx i386/amd64-mpx-linux \ - i386/amd64-avx-mpx i386/amd64-avx-mpx-linux \ - i386/amd64-avx-avx512 i386/amd64-avx-avx512-linux \ - i386/amd64-avx-mpx-avx512-pku i386/amd64-avx-mpx-avx512-pku-linux \ - i386/x32 i386/x32-linux \ - i386/x32-avx i386/x32-avx-linux \ - i386/x32-avx-avx512 i386/x32-avx-avx512-linux \ + i386/i386-avx-linux \ + i386/i386-mpx-linux \ + i386/i386-avx-mpx-linux \ + i386/i386-avx-avx512-linux \ + i386/i386-avx-mpx-avx512-pku-linux \ + i386/amd64-avx-linux \ + i386/amd64-mpx-linux \ + i386/amd64-avx-mpx-linux \ + i386/amd64-avx-avx512-linux \ + i386/amd64-avx-mpx-avx512-pku-linux \ + i386/x32-linux \ + i386/x32-avx-linux \ + i386/x32-avx-avx512-linux \ mips-linux mips-dsp-linux \ microblaze-with-stack-protect \ mips64-linux mips64-dsp-linux \ @@ -165,11 +165,8 @@ XMLTOC = \ i386/i386-avx-mpx.xml \ i386/i386.xml \ i386/x32-avx-linux.xml \ - i386/x32-avx.xml \ i386/x32-avx-avx512-linux.xml \ - i386/x32-avx-avx512.xml \ i386/x32-linux.xml \ - i386/x32.xml \ microblaze-with-stack-protect.xml \ microblaze.xml \ mips-dsp-linux.xml \ @@ -235,7 +232,7 @@ XMLTOC = \ tic6x-c64xp-linux.xml \ tic6x-c64xp.xml -CFILES = $(patsubst %.xml,%.c,$(XMLTOC)) +TDESC_CFILES = $(patsubst %.xml,%.c,$(XMLTOC)) GDB = false all: $(OUTPUTS) @@ -252,10 +249,38 @@ $(outdir)/%.dat: %.xml number-regs.xsl sort-regs.xsl gdbserver-regs.xsl $(XSLTPROC) gdbserver-regs.xsl - >> $(outdir)/$*.tmp sh ../../move-if-change $(outdir)/$*.tmp $(outdir)/$*.dat -cfiles: $(CFILES) -%.c: %.xml +FEATURE_XMLFILES = i386/32bit-core.xml \ + i386/32bit-sse.xml \ + i386/32bit-linux.xml \ + i386/32bit-avx.xml \ + i386/32bit-mpx.xml \ + i386/32bit-avx512.xml \ + i386/32bit-pkeys.xml + +FEATURE_CFILES = $(patsubst %.xml,%.c,$(FEATURE_XMLFILES)) + +cfiles: $(TDESC_CFILES) $(FEATURE_CFILES) + +$(TDESC_CFILES): %.c: %.xml + $(GDB) -nx -q -batch -ex 'maint print c-tdesc $<' > $@.tmp + sh ../../move-if-change $@.tmp $@ + +$(FEATURE_CFILES): %.c: %.xml.tmp $(GDB) -nx -q -batch \ - -ex "set tdesc filename $<" -ex 'maint print c-tdesc' > $@.tmp + -ex 'maint print c-tdesc $<' > $@.tmp + sh ../../move-if-change $@.tmp $@ + rm $< + +# %.xml is the XML file for each target description feature, and +# %.xml.tmp is the XML file target description which only includes +# one target description feature. + +%.xml.tmp: %.xml + echo "<?xml version=\"1.0\"?>" > $@.tmp + echo "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">" >> $@.tmp + echo "<target>" >> $@.tmp + echo " <xi:include href=\"$(notdir $<)\"/>" >> $@.tmp + echo "</target>" >> $@.tmp sh ../../move-if-change $@.tmp $@ # Other dependencies. @@ -263,7 +288,8 @@ $(outdir)/arm/arm-with-iwmmxt.dat: arm/arm-core.xml arm/xscale-iwmmxt.xml $(outdir)/i386/i386.dat: i386/32bit-core.xml i386/32bit-sse.xml $(outdir)/i386/i386-linux.dat: i386/32bit-core.xml i386/32bit-sse.xml \ i386/32bit-linux.xml -$(outdir)/i386/amd64.dat: i386/64bit-core.xml i386/64bit-sse.xml +$(outdir)/i386/amd64.dat: i386/64bit-core.xml i386/64bit-sse.xml \ + i386/64bit-segments.xml $(outdir)/i386/amd64-linux.dat: i386/64bit-core.xml i386/64bit-sse.xml \ i386/64bit-linux.xml i386/64bit-segments.xml $(outdir)/i386/i386-avx.dat: i386/32bit-core.xml i386/32bit-avx.xml @@ -289,7 +315,8 @@ $(outdir)/i386/i386-avx-mpx-avx512-pku-linux.dat: i386/32bit-core.xml \ i386/32bit-pkeys.xml i386/32bit-linux.xml $(outdir)/i386/i386-mmx.dat: i386/32bit-core.xml $(outdir)/i386/i386-mmx-linux.dat: i386/32bit-core.xml i386/32bit-linux.xml -$(outdir)/i386/amd64-avx.dat: i386/64bit-core.xml i386/64bit-avx.xml +$(outdir)/i386/amd64-avx.dat: i386/64bit-core.xml i386/64bit-avx.xml \ + i386/64bit-segments.xml $(outdir)/i386/amd64-avx-linux.dat: i386/64bit-core.xml i386/64bit-avx.xml \ i386/64bit-linux.xml i386/64bit-segments.xml $(outdir)/i386/amd64-mpx-linux.dat: i386/64bit-core.xml i386/64bit-avx.xml \ @@ -297,16 +324,16 @@ $(outdir)/i386/amd64-mpx-linux.dat: i386/64bit-core.xml i386/64bit-avx.xml \ $(outdir)/i386/amd64-avx-mpx-linux.dat: i386/64bit-core.xml \ i386/64bit-linux.xml i386/64bit-segments.xml i386/64bit-mpx.xml $(outdir)/i386/amd64-mpx.dat: i386/64bit-core.xml i386/64bit-avx.xml \ - i386/64bit-mpx.xml + i386/64bit-segments.xml i386/64bit-mpx.xml $(outdir)/i386/amd64-avx-mpx.dat: i386/64bit-core.xml \ - i386/64bit-mpx.xml + i386/64bit-segments.xml i386/64bit-mpx.xml $(outdir)/i386/amd64-avx-avx512.dat: i386/64bit-core.xml i386/64bit-avx.xml \ - i386/64bit-avx512.xml + i386/64bit-avx512.xml i386/64bit-segments.xml $(outdir)/i386/amd64-avx-avx512-linux.dat: i386/64bit-core.xml i386/64bit-avx.xml \ i386/64bit-avx512.xml i386/64bit-linux.xml $(outdir)/i386/amd64-avx-mpx-avx512-pku.dat: i386/64bit-core.xml \ i386/64bit-avx.xml i386/64bit-mpx.xml i386/64bit-avx512.xml \ - i386/64bit-pkeys.xml + i386/64bit-pkeys.xml i386/64bit-segments.xml $(outdir)/i386/amd64-avx-mpx-avx512-pku-linux.dat: i386/64bit-core.xml \ i386/64bit-avx.xml i386/64bit-mpx.xml i386/64bit-avx512.xml \ i386/64bit-linux.xml i386/64bit-segments.xml \ @@ -326,7 +353,7 @@ $(outdir)/i386/x32-avx-avx512-linux.dat: i386/x32-core.xml i386/64bit-avx.xml \ # 'all' doesn't build the C files, so don't delete them in 'clean' # either. clean-cfiles: - rm -f $(CFILES) + rm -f $(TDESC_CFILES) $(FEATURE_CFILES) clean: rm -f $(OUTPUTS) diff --git a/gdb/features/aarch64.c b/gdb/features/aarch64.c index e9eaed8..7411cac 100644 --- a/gdb/features/aarch64.c +++ b/gdb/features/aarch64.c @@ -10,13 +10,13 @@ static void initialize_tdesc_aarch64 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("aarch64")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.aarch64.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "cpsr_flags", 4); tdesc_add_flag (type, 0, "SP"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/arc-arcompact.c b/gdb/features/arc-arcompact.c index a527cc2..ea84a40 100644 --- a/gdb/features/arc-arcompact.c +++ b/gdb/features/arc-arcompact.c @@ -10,12 +10,10 @@ static void initialize_tdesc_arc_arcompact (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("ARC700")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.arc.core.arcompact"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int"); @@ -53,6 +51,8 @@ initialize_tdesc_arc_arcompact (void) tdesc_create_reg (feature, "pcl", 33, 1, "", 32, "code_ptr"); feature = tdesc_create_feature (result, "org.gnu.gdb.arc.aux-minimal"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "status32_type", 4); tdesc_add_flag (type, 0, "H"); tdesc_add_bitfield (type, "E", 1, 2); diff --git a/gdb/features/arc-v2.c b/gdb/features/arc-v2.c index b2bdfb5..1eefc24 100644 --- a/gdb/features/arc-v2.c +++ b/gdb/features/arc-v2.c @@ -10,12 +10,10 @@ static void initialize_tdesc_arc_v2 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("ARCv2")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.arc.core.v2"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int"); @@ -53,6 +51,8 @@ initialize_tdesc_arc_v2 (void) tdesc_create_reg (feature, "pcl", 33, 1, "", 32, "code_ptr"); feature = tdesc_create_feature (result, "org.gnu.gdb.arc.aux-minimal"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "status32_type", 4); tdesc_add_flag (type, 0, "H"); tdesc_add_bitfield (type, "E", 1, 4); diff --git a/gdb/features/arm/arm-with-iwmmxt.c b/gdb/features/arm/arm-with-iwmmxt.c index 1770e03..5f839a0 100644 --- a/gdb/features/arm/arm-with-iwmmxt.c +++ b/gdb/features/arm/arm-with-iwmmxt.c @@ -10,12 +10,10 @@ static void initialize_tdesc_arm_with_iwmmxt (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("iwmmxt")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.arm.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); @@ -36,6 +34,7 @@ initialize_tdesc_arm_with_iwmmxt (void) tdesc_create_reg (feature, "cpsr", 25, 1, NULL, 32, "int"); feature = tdesc_create_feature (result, "org.gnu.gdb.xscale.iwmmxt"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "uint8"); tdesc_create_vector (feature, "iwmmxt_v8u8", field_type, 8); @@ -45,6 +44,7 @@ initialize_tdesc_arm_with_iwmmxt (void) field_type = tdesc_named_type (feature, "uint32"); tdesc_create_vector (feature, "iwmmxt_v2u32", field_type, 2); + struct tdesc_type *type; type = tdesc_create_union (feature, "iwmmxt_vec64i"); field_type = tdesc_named_type (feature, "iwmmxt_v8u8"); tdesc_add_field (type, "u8", field_type); diff --git a/gdb/features/arm/arm-with-m-fpa-layout.c b/gdb/features/arm/arm-with-m-fpa-layout.c index f720614..99bebc3 100644 --- a/gdb/features/arm/arm-with-m-fpa-layout.c +++ b/gdb/features/arm/arm-with-m-fpa-layout.c @@ -10,10 +10,10 @@ static void initialize_tdesc_arm_with_m_fpa_layout (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("arm")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.arm.m-profile"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int"); diff --git a/gdb/features/arm/arm-with-m-vfp-d16.c b/gdb/features/arm/arm-with-m-vfp-d16.c index 069baac..ab91673 100644 --- a/gdb/features/arm/arm-with-m-vfp-d16.c +++ b/gdb/features/arm/arm-with-m-vfp-d16.c @@ -10,10 +10,10 @@ static void initialize_tdesc_arm_with_m_vfp_d16 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("arm")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.arm.m-profile"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int"); diff --git a/gdb/features/arm/arm-with-m.c b/gdb/features/arm/arm-with-m.c index 64d31bb..619fd72 100644 --- a/gdb/features/arm/arm-with-m.c +++ b/gdb/features/arm/arm-with-m.c @@ -10,10 +10,10 @@ static void initialize_tdesc_arm_with_m (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("arm")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.arm.m-profile"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int"); diff --git a/gdb/features/arm/arm-with-neon.c b/gdb/features/arm/arm-with-neon.c index d365c0f..682ad75 100644 --- a/gdb/features/arm/arm-with-neon.c +++ b/gdb/features/arm/arm-with-neon.c @@ -10,10 +10,10 @@ static void initialize_tdesc_arm_with_neon (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("arm")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.arm.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); diff --git a/gdb/features/arm/arm-with-vfpv2.c b/gdb/features/arm/arm-with-vfpv2.c index 0ebbfef..368256c 100644 --- a/gdb/features/arm/arm-with-vfpv2.c +++ b/gdb/features/arm/arm-with-vfpv2.c @@ -10,10 +10,10 @@ static void initialize_tdesc_arm_with_vfpv2 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("arm")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.arm.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); diff --git a/gdb/features/arm/arm-with-vfpv3.c b/gdb/features/arm/arm-with-vfpv3.c index e235dfa..ade7c95 100644 --- a/gdb/features/arm/arm-with-vfpv3.c +++ b/gdb/features/arm/arm-with-vfpv3.c @@ -10,10 +10,10 @@ static void initialize_tdesc_arm_with_vfpv3 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("arm")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.arm.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); diff --git a/gdb/features/i386/32bit-avx.c b/gdb/features/i386/32bit-avx.c new file mode 100644 index 0000000..0e71515 --- /dev/null +++ b/gdb/features/i386/32bit-avx.c @@ -0,0 +1,21 @@ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: 32bit-avx.xml */ + +#include "target-descriptions.h" + +static int +create_feature_i386_32bit_avx (struct target_desc *result, long regnum) +{ + struct tdesc_feature *feature; + + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx"); + tdesc_create_reg (feature, "ymm0h", regnum++, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm1h", regnum++, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm2h", regnum++, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm3h", regnum++, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm4h", regnum++, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm5h", regnum++, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm6h", regnum++, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm7h", regnum++, 1, NULL, 128, "uint128"); + return regnum; +} diff --git a/gdb/features/i386/32bit-avx512.c b/gdb/features/i386/32bit-avx512.c new file mode 100644 index 0000000..034f557 --- /dev/null +++ b/gdb/features/i386/32bit-avx512.c @@ -0,0 +1,33 @@ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: 32bit-avx512.xml */ + +#include "target-descriptions.h" + +static int +create_feature_i386_32bit_avx512 (struct target_desc *result, long regnum) +{ + struct tdesc_feature *feature; + + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx512"); + struct tdesc_type *field_type; + field_type = tdesc_named_type (feature, "uint128"); + tdesc_create_vector (feature, "v2ui128", field_type, 2); + + tdesc_create_reg (feature, "k0", regnum++, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k1", regnum++, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k2", regnum++, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k3", regnum++, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k4", regnum++, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k5", regnum++, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k6", regnum++, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k7", regnum++, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "zmm0h", regnum++, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm1h", regnum++, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm2h", regnum++, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm3h", regnum++, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm4h", regnum++, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm5h", regnum++, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm6h", regnum++, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm7h", regnum++, 1, NULL, 256, "v2ui128"); + return regnum; +} diff --git a/gdb/features/i386/32bit-core.c b/gdb/features/i386/32bit-core.c new file mode 100644 index 0000000..b43de4d --- /dev/null +++ b/gdb/features/i386/32bit-core.c @@ -0,0 +1,66 @@ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: 32bit-core.xml */ + +#include "target-descriptions.h" + +static int +create_feature_i386_32bit_core (struct target_desc *result, long regnum) +{ + struct tdesc_feature *feature; + + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; + type = tdesc_create_flags (feature, "i386_eflags", 4); + tdesc_add_flag (type, 0, "CF"); + tdesc_add_flag (type, 1, ""); + tdesc_add_flag (type, 2, "PF"); + tdesc_add_flag (type, 4, "AF"); + tdesc_add_flag (type, 6, "ZF"); + tdesc_add_flag (type, 7, "SF"); + tdesc_add_flag (type, 8, "TF"); + tdesc_add_flag (type, 9, "IF"); + tdesc_add_flag (type, 10, "DF"); + tdesc_add_flag (type, 11, "OF"); + tdesc_add_flag (type, 14, "NT"); + tdesc_add_flag (type, 16, "RF"); + tdesc_add_flag (type, 17, "VM"); + tdesc_add_flag (type, 18, "AC"); + tdesc_add_flag (type, 19, "VIF"); + tdesc_add_flag (type, 20, "VIP"); + tdesc_add_flag (type, 21, "ID"); + + tdesc_create_reg (feature, "eax", regnum++, 1, NULL, 32, "int32"); + tdesc_create_reg (feature, "ecx", regnum++, 1, NULL, 32, "int32"); + tdesc_create_reg (feature, "edx", regnum++, 1, NULL, 32, "int32"); + tdesc_create_reg (feature, "ebx", regnum++, 1, NULL, 32, "int32"); + tdesc_create_reg (feature, "esp", regnum++, 1, NULL, 32, "data_ptr"); + tdesc_create_reg (feature, "ebp", regnum++, 1, NULL, 32, "data_ptr"); + tdesc_create_reg (feature, "esi", regnum++, 1, NULL, 32, "int32"); + tdesc_create_reg (feature, "edi", regnum++, 1, NULL, 32, "int32"); + tdesc_create_reg (feature, "eip", regnum++, 1, NULL, 32, "code_ptr"); + tdesc_create_reg (feature, "eflags", regnum++, 1, NULL, 32, "i386_eflags"); + tdesc_create_reg (feature, "cs", regnum++, 1, NULL, 32, "int32"); + tdesc_create_reg (feature, "ss", regnum++, 1, NULL, 32, "int32"); + tdesc_create_reg (feature, "ds", regnum++, 1, NULL, 32, "int32"); + tdesc_create_reg (feature, "es", regnum++, 1, NULL, 32, "int32"); + tdesc_create_reg (feature, "fs", regnum++, 1, NULL, 32, "int32"); + tdesc_create_reg (feature, "gs", regnum++, 1, NULL, 32, "int32"); + tdesc_create_reg (feature, "st0", regnum++, 1, NULL, 80, "i387_ext"); + tdesc_create_reg (feature, "st1", regnum++, 1, NULL, 80, "i387_ext"); + tdesc_create_reg (feature, "st2", regnum++, 1, NULL, 80, "i387_ext"); + tdesc_create_reg (feature, "st3", regnum++, 1, NULL, 80, "i387_ext"); + tdesc_create_reg (feature, "st4", regnum++, 1, NULL, 80, "i387_ext"); + tdesc_create_reg (feature, "st5", regnum++, 1, NULL, 80, "i387_ext"); + tdesc_create_reg (feature, "st6", regnum++, 1, NULL, 80, "i387_ext"); + tdesc_create_reg (feature, "st7", regnum++, 1, NULL, 80, "i387_ext"); + tdesc_create_reg (feature, "fctrl", regnum++, 1, "float", 32, "int"); + tdesc_create_reg (feature, "fstat", regnum++, 1, "float", 32, "int"); + tdesc_create_reg (feature, "ftag", regnum++, 1, "float", 32, "int"); + tdesc_create_reg (feature, "fiseg", regnum++, 1, "float", 32, "int"); + tdesc_create_reg (feature, "fioff", regnum++, 1, "float", 32, "int"); + tdesc_create_reg (feature, "foseg", regnum++, 1, "float", 32, "int"); + tdesc_create_reg (feature, "fooff", regnum++, 1, "float", 32, "int"); + tdesc_create_reg (feature, "fop", regnum++, 1, "float", 32, "int"); + return regnum; +} diff --git a/gdb/features/i386/32bit-linux.c b/gdb/features/i386/32bit-linux.c new file mode 100644 index 0000000..1b50882 --- /dev/null +++ b/gdb/features/i386/32bit-linux.c @@ -0,0 +1,15 @@ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: 32bit-linux.xml */ + +#include "target-descriptions.h" + +static int +create_feature_i386_32bit_linux (struct target_desc *result, long regnum) +{ + struct tdesc_feature *feature; + + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.linux"); + regnum = 41; + tdesc_create_reg (feature, "orig_eax", regnum++, 1, NULL, 32, "int"); + return regnum; +} diff --git a/gdb/features/i386/32bit-mpx.c b/gdb/features/i386/32bit-mpx.c new file mode 100644 index 0000000..6ed3b2e --- /dev/null +++ b/gdb/features/i386/32bit-mpx.c @@ -0,0 +1,51 @@ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: 32bit-mpx.xml */ + +#include "target-descriptions.h" + +static int +create_feature_i386_32bit_mpx (struct target_desc *result, long regnum) +{ + struct tdesc_feature *feature; + + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.mpx"); + struct tdesc_type *field_type; + struct tdesc_type *type; + type = tdesc_create_struct (feature, "br128"); + field_type = tdesc_named_type (feature, "uint64"); + tdesc_add_field (type, "lbound", field_type); + field_type = tdesc_named_type (feature, "uint64"); + tdesc_add_field (type, "ubound_raw", field_type); + + type = tdesc_create_struct (feature, "_bndstatus"); + tdesc_set_struct_size (type, 8); + tdesc_add_bitfield (type, "bde", 2, 31); + tdesc_add_bitfield (type, "error", 0, 1); + + type = tdesc_create_union (feature, "status"); + field_type = tdesc_named_type (feature, "data_ptr"); + tdesc_add_field (type, "raw", field_type); + field_type = tdesc_named_type (feature, "_bndstatus"); + tdesc_add_field (type, "status", field_type); + + type = tdesc_create_struct (feature, "_bndcfgu"); + tdesc_set_struct_size (type, 8); + tdesc_add_bitfield (type, "base", 12, 31); + tdesc_add_bitfield (type, "reserved", 2, 11); + tdesc_add_bitfield (type, "preserved", 1, 1); + tdesc_add_bitfield (type, "enabled", 0, 0); + + type = tdesc_create_union (feature, "cfgu"); + field_type = tdesc_named_type (feature, "data_ptr"); + tdesc_add_field (type, "raw", field_type); + field_type = tdesc_named_type (feature, "_bndcfgu"); + tdesc_add_field (type, "config", field_type); + + tdesc_create_reg (feature, "bnd0raw", regnum++, 1, NULL, 128, "br128"); + tdesc_create_reg (feature, "bnd1raw", regnum++, 1, NULL, 128, "br128"); + tdesc_create_reg (feature, "bnd2raw", regnum++, 1, NULL, 128, "br128"); + tdesc_create_reg (feature, "bnd3raw", regnum++, 1, NULL, 128, "br128"); + tdesc_create_reg (feature, "bndcfgu", regnum++, 1, NULL, 64, "cfgu"); + tdesc_create_reg (feature, "bndstatus", regnum++, 1, NULL, 64, "status"); + return regnum; +} diff --git a/gdb/features/i386/32bit-pkeys.c b/gdb/features/i386/32bit-pkeys.c new file mode 100644 index 0000000..24a40aa3 --- /dev/null +++ b/gdb/features/i386/32bit-pkeys.c @@ -0,0 +1,14 @@ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: 32bit-pkeys.xml */ + +#include "target-descriptions.h" + +static int +create_feature_i386_32bit_pkeys (struct target_desc *result, long regnum) +{ + struct tdesc_feature *feature; + + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.pkeys"); + tdesc_create_reg (feature, "pkru", regnum++, 1, NULL, 32, "uint32"); + return regnum; +} diff --git a/gdb/features/i386/32bit-sse.c b/gdb/features/i386/32bit-sse.c new file mode 100644 index 0000000..c0684fb --- /dev/null +++ b/gdb/features/i386/32bit-sse.c @@ -0,0 +1,75 @@ +/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: + Original: 32bit-sse.xml */ + +#include "target-descriptions.h" + +static int +create_feature_i386_32bit_sse (struct target_desc *result, long regnum) +{ + struct tdesc_feature *feature; + + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.sse"); + struct tdesc_type *field_type; + field_type = tdesc_named_type (feature, "ieee_single"); + tdesc_create_vector (feature, "v4f", field_type, 4); + + field_type = tdesc_named_type (feature, "ieee_double"); + tdesc_create_vector (feature, "v2d", field_type, 2); + + field_type = tdesc_named_type (feature, "int8"); + tdesc_create_vector (feature, "v16i8", field_type, 16); + + field_type = tdesc_named_type (feature, "int16"); + tdesc_create_vector (feature, "v8i16", field_type, 8); + + field_type = tdesc_named_type (feature, "int32"); + tdesc_create_vector (feature, "v4i32", field_type, 4); + + field_type = tdesc_named_type (feature, "int64"); + tdesc_create_vector (feature, "v2i64", field_type, 2); + + struct tdesc_type *type; + type = tdesc_create_union (feature, "vec128"); + field_type = tdesc_named_type (feature, "v4f"); + tdesc_add_field (type, "v4_float", field_type); + field_type = tdesc_named_type (feature, "v2d"); + tdesc_add_field (type, "v2_double", field_type); + field_type = tdesc_named_type (feature, "v16i8"); + tdesc_add_field (type, "v16_int8", field_type); + field_type = tdesc_named_type (feature, "v8i16"); + tdesc_add_field (type, "v8_int16", field_type); + field_type = tdesc_named_type (feature, "v4i32"); + tdesc_add_field (type, "v4_int32", field_type); + field_type = tdesc_named_type (feature, "v2i64"); + tdesc_add_field (type, "v2_int64", field_type); + field_type = tdesc_named_type (feature, "uint128"); + tdesc_add_field (type, "uint128", field_type); + + type = tdesc_create_flags (feature, "i386_mxcsr", 4); + tdesc_add_flag (type, 0, "IE"); + tdesc_add_flag (type, 1, "DE"); + tdesc_add_flag (type, 2, "ZE"); + tdesc_add_flag (type, 3, "OE"); + tdesc_add_flag (type, 4, "UE"); + tdesc_add_flag (type, 5, "PE"); + tdesc_add_flag (type, 6, "DAZ"); + tdesc_add_flag (type, 7, "IM"); + tdesc_add_flag (type, 8, "DM"); + tdesc_add_flag (type, 9, "ZM"); + tdesc_add_flag (type, 10, "OM"); + tdesc_add_flag (type, 11, "UM"); + tdesc_add_flag (type, 12, "PM"); + tdesc_add_flag (type, 15, "FZ"); + + regnum = 32; + tdesc_create_reg (feature, "xmm0", regnum++, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm1", regnum++, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm2", regnum++, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm3", regnum++, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm4", regnum++, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm5", regnum++, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm6", regnum++, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm7", regnum++, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "mxcsr", regnum++, 1, "vector", 32, "i386_mxcsr"); + return regnum; +} diff --git a/gdb/features/i386/amd64-avx-avx512-linux.c b/gdb/features/i386/amd64-avx-avx512-linux.c index 6129ab1..de58f06 100644 --- a/gdb/features/i386/amd64-avx-avx512-linux.c +++ b/gdb/features/i386/amd64-avx-avx512-linux.c @@ -10,15 +10,15 @@ static void initialize_tdesc_amd64_avx_avx512_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386:x86-64")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); @@ -282,7 +282,7 @@ initialize_tdesc_amd64_avx_avx512_linux (void) tdesc_create_reg (feature, "zmm28h", 144, 1, NULL, 256, "v2ui128"); tdesc_create_reg (feature, "zmm29h", 145, 1, NULL, 256, "v2ui128"); tdesc_create_reg (feature, "zmm30h", 146, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm31h", 146, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm31h", 147, 1, NULL, 256, "v2ui128"); tdesc_amd64_avx_avx512_linux = result; } diff --git a/gdb/features/i386/amd64-avx-avx512.c b/gdb/features/i386/amd64-avx-avx512.c index 8a185c1..354d826 100644 --- a/gdb/features/i386/amd64-avx-avx512.c +++ b/gdb/features/i386/amd64-avx-avx512.c @@ -10,13 +10,13 @@ static void initialize_tdesc_amd64_avx_avx512 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386:x86-64")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); @@ -146,23 +146,27 @@ initialize_tdesc_amd64_avx_avx512 (void) tdesc_create_reg (feature, "xmm15", 55, 1, NULL, 128, "vec128"); tdesc_create_reg (feature, "mxcsr", 56, 1, "vector", 32, "i386_mxcsr"); + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.segments"); + tdesc_create_reg (feature, "fs_base", 57, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "gs_base", 58, 1, NULL, 64, "int"); + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx"); - tdesc_create_reg (feature, "ymm0h", 57, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm1h", 58, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm2h", 59, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm3h", 60, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm4h", 61, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm5h", 62, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm6h", 63, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm7h", 64, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm8h", 65, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm9h", 66, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm10h", 67, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm11h", 68, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm12h", 69, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm13h", 70, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm14h", 71, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm15h", 72, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm0h", 59, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm1h", 60, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm2h", 61, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm3h", 62, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm4h", 63, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm5h", 64, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm6h", 65, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm7h", 66, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm8h", 67, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm9h", 68, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm10h", 69, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm11h", 70, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm12h", 71, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm13h", 72, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm14h", 73, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm15h", 74, 1, NULL, 128, "uint128"); feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx512"); field_type = tdesc_named_type (feature, "ieee_single"); @@ -202,78 +206,78 @@ initialize_tdesc_amd64_avx_avx512 (void) field_type = tdesc_named_type (feature, "uint128"); tdesc_create_vector (feature, "v2ui128", field_type, 2); - tdesc_create_reg (feature, "xmm16", 73, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm17", 74, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm18", 75, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm19", 76, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm20", 77, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm21", 78, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm22", 79, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm23", 80, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm24", 81, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm25", 82, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm26", 83, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm27", 84, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm28", 85, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm29", 86, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm30", 87, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm31", 88, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "ymm16h", 89, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm17h", 90, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm18h", 91, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm19h", 92, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm20h", 93, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm21h", 94, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm22h", 95, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm23h", 96, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm24h", 97, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm25h", 98, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm26h", 99, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm27h", 100, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm28h", 101, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm29h", 102, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm30h", 103, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm31h", 104, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "k0", 105, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k1", 106, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k2", 107, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k3", 108, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k4", 109, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k5", 110, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k6", 111, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k7", 112, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "zmm0h", 113, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm1h", 114, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm2h", 115, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm3h", 116, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm4h", 117, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm5h", 118, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm6h", 119, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm7h", 120, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm8h", 121, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm9h", 122, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm10h", 123, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm11h", 124, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm12h", 125, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm13h", 126, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm14h", 127, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm15h", 128, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm16h", 129, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm17h", 130, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm18h", 131, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm19h", 132, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm20h", 133, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm21h", 134, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm22h", 135, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm23h", 136, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm24h", 137, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm25h", 138, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm26h", 139, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm27h", 140, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm28h", 141, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm29h", 142, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm30h", 143, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm31h", 144, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "xmm16", 75, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm17", 76, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm18", 77, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm19", 78, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm20", 79, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm21", 80, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm22", 81, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm23", 82, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm24", 83, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm25", 84, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm26", 85, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm27", 86, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm28", 87, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm29", 88, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm30", 89, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm31", 90, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "ymm16h", 91, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm17h", 92, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm18h", 93, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm19h", 94, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm20h", 95, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm21h", 96, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm22h", 97, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm23h", 98, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm24h", 99, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm25h", 100, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm26h", 101, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm27h", 102, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm28h", 103, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm29h", 104, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm30h", 105, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm31h", 106, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "k0", 107, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k1", 108, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k2", 109, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k3", 110, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k4", 111, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k5", 112, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k6", 113, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k7", 114, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "zmm0h", 115, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm1h", 116, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm2h", 117, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm3h", 118, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm4h", 119, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm5h", 120, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm6h", 121, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm7h", 122, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm8h", 123, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm9h", 124, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm10h", 125, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm11h", 126, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm12h", 127, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm13h", 128, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm14h", 129, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm15h", 130, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm16h", 131, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm17h", 132, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm18h", 133, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm19h", 134, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm20h", 135, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm21h", 136, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm22h", 137, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm23h", 138, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm24h", 139, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm25h", 140, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm26h", 141, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm27h", 142, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm28h", 143, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm29h", 144, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm30h", 145, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm31h", 146, 1, NULL, 256, "v2ui128"); tdesc_amd64_avx_avx512 = result; } diff --git a/gdb/features/i386/amd64-avx-avx512.xml b/gdb/features/i386/amd64-avx-avx512.xml index a458743..fdf8136 100644 --- a/gdb/features/i386/amd64-avx-avx512.xml +++ b/gdb/features/i386/amd64-avx-avx512.xml @@ -12,6 +12,7 @@ <architecture>i386:x86-64</architecture> <xi:include href="64bit-core.xml"/> <xi:include href="64bit-sse.xml"/> + <xi:include href="64bit-segments.xml"/> <xi:include href="64bit-avx.xml"/> <xi:include href="64bit-avx512.xml"/> </target> diff --git a/gdb/features/i386/amd64-avx-linux.c b/gdb/features/i386/amd64-avx-linux.c index 1d56dbf..00dfd3c 100644 --- a/gdb/features/i386/amd64-avx-linux.c +++ b/gdb/features/i386/amd64-avx-linux.c @@ -10,15 +10,15 @@ static void initialize_tdesc_amd64_avx_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386:x86-64")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/amd64-avx-mpx-avx512-pku-linux.c b/gdb/features/i386/amd64-avx-mpx-avx512-pku-linux.c index 248eff7..7fd016f 100644 --- a/gdb/features/i386/amd64-avx-mpx-avx512-pku-linux.c +++ b/gdb/features/i386/amd64-avx-mpx-avx512-pku-linux.c @@ -10,15 +10,15 @@ static void initialize_tdesc_amd64_avx_mpx_avx512_pku_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386:x86-64")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); @@ -323,7 +323,7 @@ initialize_tdesc_amd64_avx_mpx_avx512_pku_linux (void) tdesc_create_reg (feature, "zmm31h", 153, 1, NULL, 256, "v2ui128"); feature = tdesc_create_feature (result, "org.gnu.gdb.i386.pkeys"); - tdesc_create_reg (feature, "pkru", 152, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "pkru", 154, 1, NULL, 32, "uint32"); tdesc_amd64_avx_mpx_avx512_pku_linux = result; } diff --git a/gdb/features/i386/amd64-avx-mpx-avx512-pku.c b/gdb/features/i386/amd64-avx-mpx-avx512-pku.c index dfe7d77..bade64d 100644 --- a/gdb/features/i386/amd64-avx-mpx-avx512-pku.c +++ b/gdb/features/i386/amd64-avx-mpx-avx512-pku.c @@ -10,13 +10,13 @@ static void initialize_tdesc_amd64_avx_mpx_avx512_pku (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386:x86-64")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); @@ -146,23 +146,27 @@ initialize_tdesc_amd64_avx_mpx_avx512_pku (void) tdesc_create_reg (feature, "xmm15", 55, 1, NULL, 128, "vec128"); tdesc_create_reg (feature, "mxcsr", 56, 1, "vector", 32, "i386_mxcsr"); + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.segments"); + tdesc_create_reg (feature, "fs_base", 57, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "gs_base", 58, 1, NULL, 64, "int"); + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx"); - tdesc_create_reg (feature, "ymm0h", 57, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm1h", 58, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm2h", 59, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm3h", 60, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm4h", 61, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm5h", 62, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm6h", 63, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm7h", 64, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm8h", 65, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm9h", 66, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm10h", 67, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm11h", 68, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm12h", 69, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm13h", 70, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm14h", 71, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm15h", 72, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm0h", 59, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm1h", 60, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm2h", 61, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm3h", 62, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm4h", 63, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm5h", 64, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm6h", 65, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm7h", 66, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm8h", 67, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm9h", 68, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm10h", 69, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm11h", 70, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm12h", 71, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm13h", 72, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm14h", 73, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm15h", 74, 1, NULL, 128, "uint128"); feature = tdesc_create_feature (result, "org.gnu.gdb.i386.mpx"); type = tdesc_create_struct (feature, "br128"); @@ -195,12 +199,12 @@ initialize_tdesc_amd64_avx_mpx_avx512_pku (void) field_type = tdesc_named_type (feature, "_bndcfgu"); tdesc_add_field (type, "config", field_type); - tdesc_create_reg (feature, "bnd0raw", 73, 1, NULL, 128, "br128"); - tdesc_create_reg (feature, "bnd1raw", 74, 1, NULL, 128, "br128"); - tdesc_create_reg (feature, "bnd2raw", 75, 1, NULL, 128, "br128"); - tdesc_create_reg (feature, "bnd3raw", 76, 1, NULL, 128, "br128"); - tdesc_create_reg (feature, "bndcfgu", 77, 1, NULL, 64, "cfgu"); - tdesc_create_reg (feature, "bndstatus", 78, 1, NULL, 64, "status"); + tdesc_create_reg (feature, "bnd0raw", 75, 1, NULL, 128, "br128"); + tdesc_create_reg (feature, "bnd1raw", 76, 1, NULL, 128, "br128"); + tdesc_create_reg (feature, "bnd2raw", 77, 1, NULL, 128, "br128"); + tdesc_create_reg (feature, "bnd3raw", 78, 1, NULL, 128, "br128"); + tdesc_create_reg (feature, "bndcfgu", 79, 1, NULL, 64, "cfgu"); + tdesc_create_reg (feature, "bndstatus", 80, 1, NULL, 64, "status"); feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx512"); field_type = tdesc_named_type (feature, "ieee_single"); @@ -240,81 +244,81 @@ initialize_tdesc_amd64_avx_mpx_avx512_pku (void) field_type = tdesc_named_type (feature, "uint128"); tdesc_create_vector (feature, "v2ui128", field_type, 2); - tdesc_create_reg (feature, "xmm16", 79, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm17", 80, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm18", 81, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm19", 82, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm20", 83, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm21", 84, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm22", 85, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm23", 86, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm24", 87, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm25", 88, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm26", 89, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm27", 90, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm28", 91, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm29", 92, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm30", 93, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm31", 94, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "ymm16h", 95, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm17h", 96, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm18h", 97, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm19h", 98, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm20h", 99, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm21h", 100, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm22h", 101, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm23h", 102, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm24h", 103, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm25h", 104, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm26h", 105, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm27h", 106, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm28h", 107, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm29h", 108, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm30h", 109, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm31h", 110, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "k0", 111, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k1", 112, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k2", 113, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k3", 114, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k4", 115, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k5", 116, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k6", 117, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k7", 118, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "zmm0h", 119, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm1h", 120, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm2h", 121, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm3h", 122, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm4h", 123, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm5h", 124, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm6h", 125, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm7h", 126, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm8h", 127, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm9h", 128, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm10h", 129, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm11h", 130, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm12h", 131, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm13h", 132, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm14h", 133, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm15h", 134, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm16h", 135, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm17h", 136, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm18h", 137, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm19h", 138, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm20h", 139, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm21h", 140, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm22h", 141, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm23h", 142, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm24h", 143, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm25h", 144, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm26h", 145, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm27h", 146, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm28h", 147, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm29h", 148, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm30h", 149, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm31h", 150, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "xmm16", 81, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm17", 82, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm18", 83, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm19", 84, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm20", 85, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm21", 86, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm22", 87, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm23", 88, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm24", 89, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm25", 90, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm26", 91, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm27", 92, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm28", 93, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm29", 94, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm30", 95, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "xmm31", 96, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "ymm16h", 97, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm17h", 98, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm18h", 99, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm19h", 100, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm20h", 101, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm21h", 102, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm22h", 103, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm23h", 104, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm24h", 105, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm25h", 106, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm26h", 107, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm27h", 108, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm28h", 109, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm29h", 110, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm30h", 111, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm31h", 112, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "k0", 113, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k1", 114, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k2", 115, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k3", 116, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k4", 117, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k5", 118, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k6", 119, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "k7", 120, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "zmm0h", 121, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm1h", 122, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm2h", 123, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm3h", 124, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm4h", 125, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm5h", 126, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm6h", 127, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm7h", 128, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm8h", 129, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm9h", 130, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm10h", 131, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm11h", 132, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm12h", 133, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm13h", 134, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm14h", 135, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm15h", 136, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm16h", 137, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm17h", 138, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm18h", 139, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm19h", 140, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm20h", 141, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm21h", 142, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm22h", 143, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm23h", 144, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm24h", 145, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm25h", 146, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm26h", 147, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm27h", 148, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm28h", 149, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm29h", 150, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm30h", 151, 1, NULL, 256, "v2ui128"); + tdesc_create_reg (feature, "zmm31h", 152, 1, NULL, 256, "v2ui128"); feature = tdesc_create_feature (result, "org.gnu.gdb.i386.pkeys"); - tdesc_create_reg (feature, "pkru", 151, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "pkru", 153, 1, NULL, 32, "uint32"); tdesc_amd64_avx_mpx_avx512_pku = result; } diff --git a/gdb/features/i386/amd64-avx-mpx-avx512-pku.xml b/gdb/features/i386/amd64-avx-mpx-avx512-pku.xml index e769108..d8203e3 100644 --- a/gdb/features/i386/amd64-avx-mpx-avx512-pku.xml +++ b/gdb/features/i386/amd64-avx-mpx-avx512-pku.xml @@ -12,6 +12,7 @@ <architecture>i386:x86-64</architecture> <xi:include href="64bit-core.xml"/> <xi:include href="64bit-sse.xml"/> + <xi:include href="64bit-segments.xml"/> <xi:include href="64bit-avx.xml"/> <xi:include href="64bit-mpx.xml"/> <xi:include href="64bit-avx512.xml"/> diff --git a/gdb/features/i386/amd64-avx-mpx-linux.c b/gdb/features/i386/amd64-avx-mpx-linux.c index 26c1339..5fe1127 100644 --- a/gdb/features/i386/amd64-avx-mpx-linux.c +++ b/gdb/features/i386/amd64-avx-mpx-linux.c @@ -10,15 +10,15 @@ static void initialize_tdesc_amd64_avx_mpx_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386:x86-64")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/amd64-avx-mpx.c b/gdb/features/i386/amd64-avx-mpx.c index ab56f42..5dced15 100644 --- a/gdb/features/i386/amd64-avx-mpx.c +++ b/gdb/features/i386/amd64-avx-mpx.c @@ -10,13 +10,13 @@ static void initialize_tdesc_amd64_avx_mpx (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386:x86-64")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); @@ -146,23 +146,27 @@ initialize_tdesc_amd64_avx_mpx (void) tdesc_create_reg (feature, "xmm15", 55, 1, NULL, 128, "vec128"); tdesc_create_reg (feature, "mxcsr", 56, 1, "vector", 32, "i386_mxcsr"); + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.segments"); + tdesc_create_reg (feature, "fs_base", 57, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "gs_base", 58, 1, NULL, 64, "int"); + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx"); - tdesc_create_reg (feature, "ymm0h", 57, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm1h", 58, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm2h", 59, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm3h", 60, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm4h", 61, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm5h", 62, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm6h", 63, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm7h", 64, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm8h", 65, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm9h", 66, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm10h", 67, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm11h", 68, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm12h", 69, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm13h", 70, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm14h", 71, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm15h", 72, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm0h", 59, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm1h", 60, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm2h", 61, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm3h", 62, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm4h", 63, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm5h", 64, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm6h", 65, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm7h", 66, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm8h", 67, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm9h", 68, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm10h", 69, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm11h", 70, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm12h", 71, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm13h", 72, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm14h", 73, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm15h", 74, 1, NULL, 128, "uint128"); feature = tdesc_create_feature (result, "org.gnu.gdb.i386.mpx"); type = tdesc_create_struct (feature, "br128"); @@ -195,12 +199,12 @@ initialize_tdesc_amd64_avx_mpx (void) field_type = tdesc_named_type (feature, "_bndcfgu"); tdesc_add_field (type, "config", field_type); - tdesc_create_reg (feature, "bnd0raw", 73, 1, NULL, 128, "br128"); - tdesc_create_reg (feature, "bnd1raw", 74, 1, NULL, 128, "br128"); - tdesc_create_reg (feature, "bnd2raw", 75, 1, NULL, 128, "br128"); - tdesc_create_reg (feature, "bnd3raw", 76, 1, NULL, 128, "br128"); - tdesc_create_reg (feature, "bndcfgu", 77, 1, NULL, 64, "cfgu"); - tdesc_create_reg (feature, "bndstatus", 78, 1, NULL, 64, "status"); + tdesc_create_reg (feature, "bnd0raw", 75, 1, NULL, 128, "br128"); + tdesc_create_reg (feature, "bnd1raw", 76, 1, NULL, 128, "br128"); + tdesc_create_reg (feature, "bnd2raw", 77, 1, NULL, 128, "br128"); + tdesc_create_reg (feature, "bnd3raw", 78, 1, NULL, 128, "br128"); + tdesc_create_reg (feature, "bndcfgu", 79, 1, NULL, 64, "cfgu"); + tdesc_create_reg (feature, "bndstatus", 80, 1, NULL, 64, "status"); tdesc_amd64_avx_mpx = result; } diff --git a/gdb/features/i386/amd64-avx-mpx.xml b/gdb/features/i386/amd64-avx-mpx.xml index 0001dc8..001cc58 100644 --- a/gdb/features/i386/amd64-avx-mpx.xml +++ b/gdb/features/i386/amd64-avx-mpx.xml @@ -12,6 +12,7 @@ <architecture>i386:x86-64</architecture> <xi:include href="64bit-core.xml"/> <xi:include href="64bit-sse.xml"/> + <xi:include href="64bit-segments.xml"/> <xi:include href="64bit-avx.xml"/> <xi:include href="64bit-mpx.xml"/> </target> diff --git a/gdb/features/i386/amd64-avx.c b/gdb/features/i386/amd64-avx.c index 42bd69a..016689a 100644 --- a/gdb/features/i386/amd64-avx.c +++ b/gdb/features/i386/amd64-avx.c @@ -10,13 +10,13 @@ static void initialize_tdesc_amd64_avx (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386:x86-64")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); @@ -146,23 +146,27 @@ initialize_tdesc_amd64_avx (void) tdesc_create_reg (feature, "xmm15", 55, 1, NULL, 128, "vec128"); tdesc_create_reg (feature, "mxcsr", 56, 1, "vector", 32, "i386_mxcsr"); + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.segments"); + tdesc_create_reg (feature, "fs_base", 57, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "gs_base", 58, 1, NULL, 64, "int"); + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx"); - tdesc_create_reg (feature, "ymm0h", 57, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm1h", 58, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm2h", 59, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm3h", 60, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm4h", 61, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm5h", 62, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm6h", 63, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm7h", 64, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm8h", 65, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm9h", 66, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm10h", 67, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm11h", 68, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm12h", 69, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm13h", 70, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm14h", 71, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm15h", 72, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm0h", 59, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm1h", 60, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm2h", 61, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm3h", 62, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm4h", 63, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm5h", 64, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm6h", 65, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm7h", 66, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm8h", 67, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm9h", 68, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm10h", 69, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm11h", 70, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm12h", 71, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm13h", 72, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm14h", 73, 1, NULL, 128, "uint128"); + tdesc_create_reg (feature, "ymm15h", 74, 1, NULL, 128, "uint128"); tdesc_amd64_avx = result; } diff --git a/gdb/features/i386/amd64-avx.xml b/gdb/features/i386/amd64-avx.xml index d3b63b8..a0fec55 100644 --- a/gdb/features/i386/amd64-avx.xml +++ b/gdb/features/i386/amd64-avx.xml @@ -12,5 +12,6 @@ <architecture>i386:x86-64</architecture> <xi:include href="64bit-core.xml"/> <xi:include href="64bit-sse.xml"/> + <xi:include href="64bit-segments.xml"/> <xi:include href="64bit-avx.xml"/> </target> diff --git a/gdb/features/i386/amd64-linux.c b/gdb/features/i386/amd64-linux.c index 0e921ba9..58c4405 100644 --- a/gdb/features/i386/amd64-linux.c +++ b/gdb/features/i386/amd64-linux.c @@ -10,15 +10,15 @@ static void initialize_tdesc_amd64_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386:x86-64")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/amd64-mpx-linux.c b/gdb/features/i386/amd64-mpx-linux.c index e26a74a..dcf92f9 100644 --- a/gdb/features/i386/amd64-mpx-linux.c +++ b/gdb/features/i386/amd64-mpx-linux.c @@ -10,15 +10,15 @@ static void initialize_tdesc_amd64_mpx_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386:x86-64")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/amd64-mpx.c b/gdb/features/i386/amd64-mpx.c index 41f0e78..ed7767d 100644 --- a/gdb/features/i386/amd64-mpx.c +++ b/gdb/features/i386/amd64-mpx.c @@ -10,13 +10,13 @@ static void initialize_tdesc_amd64_mpx (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386:x86-64")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); @@ -146,6 +146,10 @@ initialize_tdesc_amd64_mpx (void) tdesc_create_reg (feature, "xmm15", 55, 1, NULL, 128, "vec128"); tdesc_create_reg (feature, "mxcsr", 56, 1, "vector", 32, "i386_mxcsr"); + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.segments"); + tdesc_create_reg (feature, "fs_base", 57, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "gs_base", 58, 1, NULL, 64, "int"); + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.mpx"); type = tdesc_create_struct (feature, "br128"); field_type = tdesc_named_type (feature, "uint64"); @@ -177,12 +181,12 @@ initialize_tdesc_amd64_mpx (void) field_type = tdesc_named_type (feature, "_bndcfgu"); tdesc_add_field (type, "config", field_type); - tdesc_create_reg (feature, "bnd0raw", 57, 1, NULL, 128, "br128"); - tdesc_create_reg (feature, "bnd1raw", 58, 1, NULL, 128, "br128"); - tdesc_create_reg (feature, "bnd2raw", 59, 1, NULL, 128, "br128"); - tdesc_create_reg (feature, "bnd3raw", 60, 1, NULL, 128, "br128"); - tdesc_create_reg (feature, "bndcfgu", 61, 1, NULL, 64, "cfgu"); - tdesc_create_reg (feature, "bndstatus", 62, 1, NULL, 64, "status"); + tdesc_create_reg (feature, "bnd0raw", 59, 1, NULL, 128, "br128"); + tdesc_create_reg (feature, "bnd1raw", 60, 1, NULL, 128, "br128"); + tdesc_create_reg (feature, "bnd2raw", 61, 1, NULL, 128, "br128"); + tdesc_create_reg (feature, "bnd3raw", 62, 1, NULL, 128, "br128"); + tdesc_create_reg (feature, "bndcfgu", 63, 1, NULL, 64, "cfgu"); + tdesc_create_reg (feature, "bndstatus", 64, 1, NULL, 64, "status"); tdesc_amd64_mpx = result; } diff --git a/gdb/features/i386/amd64-mpx.xml b/gdb/features/i386/amd64-mpx.xml index 7692006..7e0253d 100644 --- a/gdb/features/i386/amd64-mpx.xml +++ b/gdb/features/i386/amd64-mpx.xml @@ -12,5 +12,6 @@ <architecture>i386:x86-64</architecture> <xi:include href="64bit-core.xml"/> <xi:include href="64bit-sse.xml"/> + <xi:include href="64bit-segments.xml"/> <xi:include href="64bit-mpx.xml"/> </target> diff --git a/gdb/features/i386/amd64.c b/gdb/features/i386/amd64.c index b875a9b..4ad79cb 100644 --- a/gdb/features/i386/amd64.c +++ b/gdb/features/i386/amd64.c @@ -10,13 +10,13 @@ static void initialize_tdesc_amd64 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386:x86-64")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); @@ -146,5 +146,9 @@ initialize_tdesc_amd64 (void) tdesc_create_reg (feature, "xmm15", 55, 1, NULL, 128, "vec128"); tdesc_create_reg (feature, "mxcsr", 56, 1, "vector", 32, "i386_mxcsr"); + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.segments"); + tdesc_create_reg (feature, "fs_base", 57, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "gs_base", 58, 1, NULL, 64, "int"); + tdesc_amd64 = result; } diff --git a/gdb/features/i386/amd64.xml b/gdb/features/i386/amd64.xml index d11c07e..1962a2a 100644 --- a/gdb/features/i386/amd64.xml +++ b/gdb/features/i386/amd64.xml @@ -12,4 +12,5 @@ <architecture>i386:x86-64</architecture> <xi:include href="64bit-core.xml"/> <xi:include href="64bit-sse.xml"/> + <xi:include href="64bit-segments.xml"/> </target> diff --git a/gdb/features/i386/i386-avx-avx512-linux.c b/gdb/features/i386/i386-avx-avx512-linux.c index 81149d5..545149d 100644 --- a/gdb/features/i386/i386-avx-avx512-linux.c +++ b/gdb/features/i386/i386-avx-avx512-linux.c @@ -10,15 +10,15 @@ static void initialize_tdesc_i386_avx_avx512_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/i386-avx-avx512.c b/gdb/features/i386/i386-avx-avx512.c index 1075ca0..585a0ac 100644 --- a/gdb/features/i386/i386-avx-avx512.c +++ b/gdb/features/i386/i386-avx-avx512.c @@ -10,13 +10,13 @@ static void initialize_tdesc_i386_avx_avx512 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/i386-avx-linux.c b/gdb/features/i386/i386-avx-linux.c index 4a8c6b5..3ef087d 100644 --- a/gdb/features/i386/i386-avx-linux.c +++ b/gdb/features/i386/i386-avx-linux.c @@ -10,15 +10,15 @@ static void initialize_tdesc_i386_avx_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/i386-avx-mpx-avx512-pku-linux.c b/gdb/features/i386/i386-avx-mpx-avx512-pku-linux.c index f90c834..e6eebf1 100644 --- a/gdb/features/i386/i386-avx-mpx-avx512-pku-linux.c +++ b/gdb/features/i386/i386-avx-mpx-avx512-pku-linux.c @@ -10,15 +10,15 @@ static void initialize_tdesc_i386_avx_mpx_avx512_pku_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/i386-avx-mpx-avx512-pku.c b/gdb/features/i386/i386-avx-mpx-avx512-pku.c index 08d9b4b..d7dd3bb 100644 --- a/gdb/features/i386/i386-avx-mpx-avx512-pku.c +++ b/gdb/features/i386/i386-avx-mpx-avx512-pku.c @@ -10,13 +10,13 @@ static void initialize_tdesc_i386_avx_mpx_avx512_pku (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/i386-avx-mpx-linux.c b/gdb/features/i386/i386-avx-mpx-linux.c index 4b27bfc..f62c487 100644 --- a/gdb/features/i386/i386-avx-mpx-linux.c +++ b/gdb/features/i386/i386-avx-mpx-linux.c @@ -10,15 +10,15 @@ static void initialize_tdesc_i386_avx_mpx_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/i386-avx-mpx.c b/gdb/features/i386/i386-avx-mpx.c index b27b40a..f479bda 100644 --- a/gdb/features/i386/i386-avx-mpx.c +++ b/gdb/features/i386/i386-avx-mpx.c @@ -10,13 +10,13 @@ static void initialize_tdesc_i386_avx_mpx (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/i386-avx.c b/gdb/features/i386/i386-avx.c index 1cb0f9e..f888335 100644 --- a/gdb/features/i386/i386-avx.c +++ b/gdb/features/i386/i386-avx.c @@ -10,13 +10,13 @@ static void initialize_tdesc_i386_avx (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/i386-linux.c b/gdb/features/i386/i386-linux.c index c7796c3..0394842 100644 --- a/gdb/features/i386/i386-linux.c +++ b/gdb/features/i386/i386-linux.c @@ -10,15 +10,15 @@ static void initialize_tdesc_i386_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/i386-mmx-linux.c b/gdb/features/i386/i386-mmx-linux.c index e53b55f..1577972 100644 --- a/gdb/features/i386/i386-mmx-linux.c +++ b/gdb/features/i386/i386-mmx-linux.c @@ -10,15 +10,15 @@ static void initialize_tdesc_i386_mmx_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/i386-mmx.c b/gdb/features/i386/i386-mmx.c index 74f67ed..02aee89 100644 --- a/gdb/features/i386/i386-mmx.c +++ b/gdb/features/i386/i386-mmx.c @@ -10,13 +10,13 @@ static void initialize_tdesc_i386_mmx (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/i386-mpx-linux.c b/gdb/features/i386/i386-mpx-linux.c index 43ea192..6dea8e0 100644 --- a/gdb/features/i386/i386-mpx-linux.c +++ b/gdb/features/i386/i386-mpx-linux.c @@ -10,15 +10,15 @@ static void initialize_tdesc_i386_mpx_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/i386-mpx.c b/gdb/features/i386/i386-mpx.c index e832d2e..d08441b 100644 --- a/gdb/features/i386/i386-mpx.c +++ b/gdb/features/i386/i386-mpx.c @@ -10,13 +10,13 @@ static void initialize_tdesc_i386_mpx (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/i386.c b/gdb/features/i386/i386.c index ede73fc..eb9a266 100644 --- a/gdb/features/i386/i386.c +++ b/gdb/features/i386/i386.c @@ -10,13 +10,13 @@ static void initialize_tdesc_i386 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/x32-avx-avx512-linux.c b/gdb/features/i386/x32-avx-avx512-linux.c index 0467d87..c023a10 100644 --- a/gdb/features/i386/x32-avx-avx512-linux.c +++ b/gdb/features/i386/x32-avx-avx512-linux.c @@ -10,15 +10,15 @@ static void initialize_tdesc_x32_avx_avx512_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386:x64-32")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/x32-avx-avx512.c b/gdb/features/i386/x32-avx-avx512.c deleted file mode 100644 index a7a2d52..0000000 --- a/gdb/features/i386/x32-avx-avx512.c +++ /dev/null @@ -1,279 +0,0 @@ -/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: - Original: x32-avx-avx512.xml */ - -#include "defs.h" -#include "osabi.h" -#include "target-descriptions.h" - -struct target_desc *tdesc_x32_avx_avx512; -static void -initialize_tdesc_x32_avx_avx512 (void) -{ - struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - - set_tdesc_architecture (result, bfd_scan_arch ("i386:x64-32")); - - feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); - type = tdesc_create_flags (feature, "i386_eflags", 4); - tdesc_add_flag (type, 0, "CF"); - tdesc_add_flag (type, 1, ""); - tdesc_add_flag (type, 2, "PF"); - tdesc_add_flag (type, 4, "AF"); - tdesc_add_flag (type, 6, "ZF"); - tdesc_add_flag (type, 7, "SF"); - tdesc_add_flag (type, 8, "TF"); - tdesc_add_flag (type, 9, "IF"); - tdesc_add_flag (type, 10, "DF"); - tdesc_add_flag (type, 11, "OF"); - tdesc_add_flag (type, 14, "NT"); - tdesc_add_flag (type, 16, "RF"); - tdesc_add_flag (type, 17, "VM"); - tdesc_add_flag (type, 18, "AC"); - tdesc_add_flag (type, 19, "VIF"); - tdesc_add_flag (type, 20, "VIP"); - tdesc_add_flag (type, 21, "ID"); - - tdesc_create_reg (feature, "rax", 0, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rbx", 1, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rcx", 2, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rdx", 3, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rsi", 4, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rdi", 5, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rbp", 6, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rsp", 7, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r8", 8, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r9", 9, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r10", 10, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r11", 11, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r12", 12, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r13", 13, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r14", 14, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r15", 15, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rip", 16, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "eflags", 17, 1, NULL, 32, "i386_eflags"); - tdesc_create_reg (feature, "cs", 18, 1, NULL, 32, "int32"); - tdesc_create_reg (feature, "ss", 19, 1, NULL, 32, "int32"); - tdesc_create_reg (feature, "ds", 20, 1, NULL, 32, "int32"); - tdesc_create_reg (feature, "es", 21, 1, NULL, 32, "int32"); - tdesc_create_reg (feature, "fs", 22, 1, NULL, 32, "int32"); - tdesc_create_reg (feature, "gs", 23, 1, NULL, 32, "int32"); - tdesc_create_reg (feature, "st0", 24, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st1", 25, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st2", 26, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st3", 27, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st4", 28, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st5", 29, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st6", 30, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st7", 31, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "fctrl", 32, 1, "float", 32, "int"); - tdesc_create_reg (feature, "fstat", 33, 1, "float", 32, "int"); - tdesc_create_reg (feature, "ftag", 34, 1, "float", 32, "int"); - tdesc_create_reg (feature, "fiseg", 35, 1, "float", 32, "int"); - tdesc_create_reg (feature, "fioff", 36, 1, "float", 32, "int"); - tdesc_create_reg (feature, "foseg", 37, 1, "float", 32, "int"); - tdesc_create_reg (feature, "fooff", 38, 1, "float", 32, "int"); - tdesc_create_reg (feature, "fop", 39, 1, "float", 32, "int"); - - feature = tdesc_create_feature (result, "org.gnu.gdb.i386.sse"); - field_type = tdesc_named_type (feature, "ieee_single"); - tdesc_create_vector (feature, "v4f", field_type, 4); - - field_type = tdesc_named_type (feature, "ieee_double"); - tdesc_create_vector (feature, "v2d", field_type, 2); - - field_type = tdesc_named_type (feature, "int8"); - tdesc_create_vector (feature, "v16i8", field_type, 16); - - field_type = tdesc_named_type (feature, "int16"); - tdesc_create_vector (feature, "v8i16", field_type, 8); - - field_type = tdesc_named_type (feature, "int32"); - tdesc_create_vector (feature, "v4i32", field_type, 4); - - field_type = tdesc_named_type (feature, "int64"); - tdesc_create_vector (feature, "v2i64", field_type, 2); - - type = tdesc_create_union (feature, "vec128"); - field_type = tdesc_named_type (feature, "v4f"); - tdesc_add_field (type, "v4_float", field_type); - field_type = tdesc_named_type (feature, "v2d"); - tdesc_add_field (type, "v2_double", field_type); - field_type = tdesc_named_type (feature, "v16i8"); - tdesc_add_field (type, "v16_int8", field_type); - field_type = tdesc_named_type (feature, "v8i16"); - tdesc_add_field (type, "v8_int16", field_type); - field_type = tdesc_named_type (feature, "v4i32"); - tdesc_add_field (type, "v4_int32", field_type); - field_type = tdesc_named_type (feature, "v2i64"); - tdesc_add_field (type, "v2_int64", field_type); - field_type = tdesc_named_type (feature, "uint128"); - tdesc_add_field (type, "uint128", field_type); - - type = tdesc_create_flags (feature, "i386_mxcsr", 4); - tdesc_add_flag (type, 0, "IE"); - tdesc_add_flag (type, 1, "DE"); - tdesc_add_flag (type, 2, "ZE"); - tdesc_add_flag (type, 3, "OE"); - tdesc_add_flag (type, 4, "UE"); - tdesc_add_flag (type, 5, "PE"); - tdesc_add_flag (type, 6, "DAZ"); - tdesc_add_flag (type, 7, "IM"); - tdesc_add_flag (type, 8, "DM"); - tdesc_add_flag (type, 9, "ZM"); - tdesc_add_flag (type, 10, "OM"); - tdesc_add_flag (type, 11, "UM"); - tdesc_add_flag (type, 12, "PM"); - tdesc_add_flag (type, 15, "FZ"); - - tdesc_create_reg (feature, "xmm0", 40, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm1", 41, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm2", 42, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm3", 43, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm4", 44, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm5", 45, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm6", 46, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm7", 47, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm8", 48, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm9", 49, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm10", 50, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm11", 51, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm12", 52, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm13", 53, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm14", 54, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm15", 55, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "mxcsr", 56, 1, "vector", 32, "i386_mxcsr"); - - feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx"); - tdesc_create_reg (feature, "ymm0h", 57, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm1h", 58, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm2h", 59, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm3h", 60, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm4h", 61, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm5h", 62, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm6h", 63, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm7h", 64, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm8h", 65, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm9h", 66, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm10h", 67, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm11h", 68, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm12h", 69, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm13h", 70, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm14h", 71, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm15h", 72, 1, NULL, 128, "uint128"); - - feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx512"); - field_type = tdesc_named_type (feature, "ieee_single"); - tdesc_create_vector (feature, "v4f", field_type, 4); - - field_type = tdesc_named_type (feature, "ieee_double"); - tdesc_create_vector (feature, "v2d", field_type, 2); - - field_type = tdesc_named_type (feature, "int8"); - tdesc_create_vector (feature, "v16i8", field_type, 16); - - field_type = tdesc_named_type (feature, "int16"); - tdesc_create_vector (feature, "v8i16", field_type, 8); - - field_type = tdesc_named_type (feature, "int32"); - tdesc_create_vector (feature, "v4i32", field_type, 4); - - field_type = tdesc_named_type (feature, "int64"); - tdesc_create_vector (feature, "v2i64", field_type, 2); - - type = tdesc_create_union (feature, "vec128"); - field_type = tdesc_named_type (feature, "v4f"); - tdesc_add_field (type, "v4_float", field_type); - field_type = tdesc_named_type (feature, "v2d"); - tdesc_add_field (type, "v2_double", field_type); - field_type = tdesc_named_type (feature, "v16i8"); - tdesc_add_field (type, "v16_int8", field_type); - field_type = tdesc_named_type (feature, "v8i16"); - tdesc_add_field (type, "v8_int16", field_type); - field_type = tdesc_named_type (feature, "v4i32"); - tdesc_add_field (type, "v4_int32", field_type); - field_type = tdesc_named_type (feature, "v2i64"); - tdesc_add_field (type, "v2_int64", field_type); - field_type = tdesc_named_type (feature, "uint128"); - tdesc_add_field (type, "uint128", field_type); - - field_type = tdesc_named_type (feature, "uint128"); - tdesc_create_vector (feature, "v2ui128", field_type, 2); - - tdesc_create_reg (feature, "xmm16", 73, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm17", 74, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm18", 75, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm19", 76, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm20", 77, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm21", 78, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm22", 79, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm23", 80, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm24", 81, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm25", 82, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm26", 83, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm27", 84, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm28", 85, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm29", 86, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm30", 87, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm31", 88, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "ymm16h", 89, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm17h", 90, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm18h", 91, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm19h", 92, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm20h", 93, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm21h", 94, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm22h", 95, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm23h", 96, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm24h", 97, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm25h", 98, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm26h", 99, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm27h", 100, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm28h", 101, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm29h", 102, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm30h", 103, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm31h", 104, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "k0", 105, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k1", 106, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k2", 107, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k3", 108, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k4", 109, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k5", 110, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k6", 111, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "k7", 112, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "zmm0h", 113, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm1h", 114, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm2h", 115, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm3h", 116, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm4h", 117, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm5h", 118, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm6h", 119, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm7h", 120, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm8h", 121, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm9h", 122, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm10h", 123, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm11h", 124, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm12h", 125, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm13h", 126, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm14h", 127, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm15h", 128, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm16h", 129, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm17h", 130, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm18h", 131, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm19h", 132, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm20h", 133, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm21h", 134, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm22h", 135, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm23h", 136, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm24h", 137, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm25h", 138, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm26h", 139, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm27h", 140, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm28h", 141, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm29h", 142, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm30h", 143, 1, NULL, 256, "v2ui128"); - tdesc_create_reg (feature, "zmm31h", 144, 1, NULL, 256, "v2ui128"); - - tdesc_x32_avx_avx512 = result; -} diff --git a/gdb/features/i386/x32-avx-avx512.xml b/gdb/features/i386/x32-avx-avx512.xml deleted file mode 100644 index eb69dfe..0000000 --- a/gdb/features/i386/x32-avx-avx512.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0"?> -<!-- Copyright (C) 2014-2017 Free Software Foundation, Inc. - - Copying and distribution of this file, with or without modification, - are permitted in any medium without royalty provided the copyright - notice and this notice are preserved. --> - -<!-- X32 with AVX, AVX512 --> - -<!DOCTYPE target SYSTEM "gdb-target.dtd"> -<target> - <architecture>i386:x64-32</architecture> - <xi:include href="x32-core.xml"/> - <xi:include href="64bit-sse.xml"/> - <xi:include href="64bit-avx.xml"/> - <xi:include href="64bit-avx512.xml"/> -</target> diff --git a/gdb/features/i386/x32-avx-linux.c b/gdb/features/i386/x32-avx-linux.c index 8406815..211d138 100644 --- a/gdb/features/i386/x32-avx-linux.c +++ b/gdb/features/i386/x32-avx-linux.c @@ -10,15 +10,15 @@ static void initialize_tdesc_x32_avx_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386:x64-32")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/x32-avx.c b/gdb/features/i386/x32-avx.c deleted file mode 100644 index 7f62e8f..0000000 --- a/gdb/features/i386/x32-avx.c +++ /dev/null @@ -1,168 +0,0 @@ -/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: - Original: x32-avx.xml */ - -#include "defs.h" -#include "osabi.h" -#include "target-descriptions.h" - -struct target_desc *tdesc_x32_avx; -static void -initialize_tdesc_x32_avx (void) -{ - struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - - set_tdesc_architecture (result, bfd_scan_arch ("i386:x64-32")); - - feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); - type = tdesc_create_flags (feature, "i386_eflags", 4); - tdesc_add_flag (type, 0, "CF"); - tdesc_add_flag (type, 1, ""); - tdesc_add_flag (type, 2, "PF"); - tdesc_add_flag (type, 4, "AF"); - tdesc_add_flag (type, 6, "ZF"); - tdesc_add_flag (type, 7, "SF"); - tdesc_add_flag (type, 8, "TF"); - tdesc_add_flag (type, 9, "IF"); - tdesc_add_flag (type, 10, "DF"); - tdesc_add_flag (type, 11, "OF"); - tdesc_add_flag (type, 14, "NT"); - tdesc_add_flag (type, 16, "RF"); - tdesc_add_flag (type, 17, "VM"); - tdesc_add_flag (type, 18, "AC"); - tdesc_add_flag (type, 19, "VIF"); - tdesc_add_flag (type, 20, "VIP"); - tdesc_add_flag (type, 21, "ID"); - - tdesc_create_reg (feature, "rax", 0, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rbx", 1, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rcx", 2, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rdx", 3, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rsi", 4, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rdi", 5, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rbp", 6, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rsp", 7, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r8", 8, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r9", 9, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r10", 10, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r11", 11, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r12", 12, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r13", 13, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r14", 14, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r15", 15, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rip", 16, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "eflags", 17, 1, NULL, 32, "i386_eflags"); - tdesc_create_reg (feature, "cs", 18, 1, NULL, 32, "int32"); - tdesc_create_reg (feature, "ss", 19, 1, NULL, 32, "int32"); - tdesc_create_reg (feature, "ds", 20, 1, NULL, 32, "int32"); - tdesc_create_reg (feature, "es", 21, 1, NULL, 32, "int32"); - tdesc_create_reg (feature, "fs", 22, 1, NULL, 32, "int32"); - tdesc_create_reg (feature, "gs", 23, 1, NULL, 32, "int32"); - tdesc_create_reg (feature, "st0", 24, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st1", 25, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st2", 26, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st3", 27, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st4", 28, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st5", 29, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st6", 30, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st7", 31, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "fctrl", 32, 1, "float", 32, "int"); - tdesc_create_reg (feature, "fstat", 33, 1, "float", 32, "int"); - tdesc_create_reg (feature, "ftag", 34, 1, "float", 32, "int"); - tdesc_create_reg (feature, "fiseg", 35, 1, "float", 32, "int"); - tdesc_create_reg (feature, "fioff", 36, 1, "float", 32, "int"); - tdesc_create_reg (feature, "foseg", 37, 1, "float", 32, "int"); - tdesc_create_reg (feature, "fooff", 38, 1, "float", 32, "int"); - tdesc_create_reg (feature, "fop", 39, 1, "float", 32, "int"); - - feature = tdesc_create_feature (result, "org.gnu.gdb.i386.sse"); - field_type = tdesc_named_type (feature, "ieee_single"); - tdesc_create_vector (feature, "v4f", field_type, 4); - - field_type = tdesc_named_type (feature, "ieee_double"); - tdesc_create_vector (feature, "v2d", field_type, 2); - - field_type = tdesc_named_type (feature, "int8"); - tdesc_create_vector (feature, "v16i8", field_type, 16); - - field_type = tdesc_named_type (feature, "int16"); - tdesc_create_vector (feature, "v8i16", field_type, 8); - - field_type = tdesc_named_type (feature, "int32"); - tdesc_create_vector (feature, "v4i32", field_type, 4); - - field_type = tdesc_named_type (feature, "int64"); - tdesc_create_vector (feature, "v2i64", field_type, 2); - - type = tdesc_create_union (feature, "vec128"); - field_type = tdesc_named_type (feature, "v4f"); - tdesc_add_field (type, "v4_float", field_type); - field_type = tdesc_named_type (feature, "v2d"); - tdesc_add_field (type, "v2_double", field_type); - field_type = tdesc_named_type (feature, "v16i8"); - tdesc_add_field (type, "v16_int8", field_type); - field_type = tdesc_named_type (feature, "v8i16"); - tdesc_add_field (type, "v8_int16", field_type); - field_type = tdesc_named_type (feature, "v4i32"); - tdesc_add_field (type, "v4_int32", field_type); - field_type = tdesc_named_type (feature, "v2i64"); - tdesc_add_field (type, "v2_int64", field_type); - field_type = tdesc_named_type (feature, "uint128"); - tdesc_add_field (type, "uint128", field_type); - - type = tdesc_create_flags (feature, "i386_mxcsr", 4); - tdesc_add_flag (type, 0, "IE"); - tdesc_add_flag (type, 1, "DE"); - tdesc_add_flag (type, 2, "ZE"); - tdesc_add_flag (type, 3, "OE"); - tdesc_add_flag (type, 4, "UE"); - tdesc_add_flag (type, 5, "PE"); - tdesc_add_flag (type, 6, "DAZ"); - tdesc_add_flag (type, 7, "IM"); - tdesc_add_flag (type, 8, "DM"); - tdesc_add_flag (type, 9, "ZM"); - tdesc_add_flag (type, 10, "OM"); - tdesc_add_flag (type, 11, "UM"); - tdesc_add_flag (type, 12, "PM"); - tdesc_add_flag (type, 15, "FZ"); - - tdesc_create_reg (feature, "xmm0", 40, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm1", 41, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm2", 42, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm3", 43, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm4", 44, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm5", 45, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm6", 46, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm7", 47, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm8", 48, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm9", 49, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm10", 50, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm11", 51, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm12", 52, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm13", 53, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm14", 54, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm15", 55, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "mxcsr", 56, 1, "vector", 32, "i386_mxcsr"); - - feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx"); - tdesc_create_reg (feature, "ymm0h", 57, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm1h", 58, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm2h", 59, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm3h", 60, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm4h", 61, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm5h", 62, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm6h", 63, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm7h", 64, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm8h", 65, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm9h", 66, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm10h", 67, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm11h", 68, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm12h", 69, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm13h", 70, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm14h", 71, 1, NULL, 128, "uint128"); - tdesc_create_reg (feature, "ymm15h", 72, 1, NULL, 128, "uint128"); - - tdesc_x32_avx = result; -} diff --git a/gdb/features/i386/x32-avx.xml b/gdb/features/i386/x32-avx.xml deleted file mode 100644 index d2047ea..0000000 --- a/gdb/features/i386/x32-avx.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0"?> -<!-- Copyright (C) 2012-2017 Free Software Foundation, Inc. - - Copying and distribution of this file, with or without modification, - are permitted in any medium without royalty provided the copyright - notice and this notice are preserved. --> - -<!-- X32 with AVX --> - -<!DOCTYPE target SYSTEM "gdb-target.dtd"> -<target> - <architecture>i386:x64-32</architecture> - <xi:include href="x32-core.xml"/> - <xi:include href="64bit-sse.xml"/> - <xi:include href="64bit-avx.xml"/> -</target> diff --git a/gdb/features/i386/x32-linux.c b/gdb/features/i386/x32-linux.c index ae49549..05d502b 100644 --- a/gdb/features/i386/x32-linux.c +++ b/gdb/features/i386/x32-linux.c @@ -10,15 +10,15 @@ static void initialize_tdesc_x32_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("i386:x64-32")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); + struct tdesc_type *field_type; + struct tdesc_type *type; type = tdesc_create_flags (feature, "i386_eflags", 4); tdesc_add_flag (type, 0, "CF"); tdesc_add_flag (type, 1, ""); diff --git a/gdb/features/i386/x32.c b/gdb/features/i386/x32.c deleted file mode 100644 index 6005d99..0000000 --- a/gdb/features/i386/x32.c +++ /dev/null @@ -1,150 +0,0 @@ -/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: - Original: x32.xml */ - -#include "defs.h" -#include "osabi.h" -#include "target-descriptions.h" - -struct target_desc *tdesc_x32; -static void -initialize_tdesc_x32 (void) -{ - struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - - set_tdesc_architecture (result, bfd_scan_arch ("i386:x64-32")); - - feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core"); - type = tdesc_create_flags (feature, "i386_eflags", 4); - tdesc_add_flag (type, 0, "CF"); - tdesc_add_flag (type, 1, ""); - tdesc_add_flag (type, 2, "PF"); - tdesc_add_flag (type, 4, "AF"); - tdesc_add_flag (type, 6, "ZF"); - tdesc_add_flag (type, 7, "SF"); - tdesc_add_flag (type, 8, "TF"); - tdesc_add_flag (type, 9, "IF"); - tdesc_add_flag (type, 10, "DF"); - tdesc_add_flag (type, 11, "OF"); - tdesc_add_flag (type, 14, "NT"); - tdesc_add_flag (type, 16, "RF"); - tdesc_add_flag (type, 17, "VM"); - tdesc_add_flag (type, 18, "AC"); - tdesc_add_flag (type, 19, "VIF"); - tdesc_add_flag (type, 20, "VIP"); - tdesc_add_flag (type, 21, "ID"); - - tdesc_create_reg (feature, "rax", 0, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rbx", 1, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rcx", 2, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rdx", 3, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rsi", 4, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rdi", 5, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rbp", 6, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rsp", 7, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r8", 8, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r9", 9, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r10", 10, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r11", 11, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r12", 12, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r13", 13, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r14", 14, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "r15", 15, 1, NULL, 64, "int64"); - tdesc_create_reg (feature, "rip", 16, 1, NULL, 64, "uint64"); - tdesc_create_reg (feature, "eflags", 17, 1, NULL, 32, "i386_eflags"); - tdesc_create_reg (feature, "cs", 18, 1, NULL, 32, "int32"); - tdesc_create_reg (feature, "ss", 19, 1, NULL, 32, "int32"); - tdesc_create_reg (feature, "ds", 20, 1, NULL, 32, "int32"); - tdesc_create_reg (feature, "es", 21, 1, NULL, 32, "int32"); - tdesc_create_reg (feature, "fs", 22, 1, NULL, 32, "int32"); - tdesc_create_reg (feature, "gs", 23, 1, NULL, 32, "int32"); - tdesc_create_reg (feature, "st0", 24, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st1", 25, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st2", 26, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st3", 27, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st4", 28, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st5", 29, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st6", 30, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "st7", 31, 1, NULL, 80, "i387_ext"); - tdesc_create_reg (feature, "fctrl", 32, 1, "float", 32, "int"); - tdesc_create_reg (feature, "fstat", 33, 1, "float", 32, "int"); - tdesc_create_reg (feature, "ftag", 34, 1, "float", 32, "int"); - tdesc_create_reg (feature, "fiseg", 35, 1, "float", 32, "int"); - tdesc_create_reg (feature, "fioff", 36, 1, "float", 32, "int"); - tdesc_create_reg (feature, "foseg", 37, 1, "float", 32, "int"); - tdesc_create_reg (feature, "fooff", 38, 1, "float", 32, "int"); - tdesc_create_reg (feature, "fop", 39, 1, "float", 32, "int"); - - feature = tdesc_create_feature (result, "org.gnu.gdb.i386.sse"); - field_type = tdesc_named_type (feature, "ieee_single"); - tdesc_create_vector (feature, "v4f", field_type, 4); - - field_type = tdesc_named_type (feature, "ieee_double"); - tdesc_create_vector (feature, "v2d", field_type, 2); - - field_type = tdesc_named_type (feature, "int8"); - tdesc_create_vector (feature, "v16i8", field_type, 16); - - field_type = tdesc_named_type (feature, "int16"); - tdesc_create_vector (feature, "v8i16", field_type, 8); - - field_type = tdesc_named_type (feature, "int32"); - tdesc_create_vector (feature, "v4i32", field_type, 4); - - field_type = tdesc_named_type (feature, "int64"); - tdesc_create_vector (feature, "v2i64", field_type, 2); - - type = tdesc_create_union (feature, "vec128"); - field_type = tdesc_named_type (feature, "v4f"); - tdesc_add_field (type, "v4_float", field_type); - field_type = tdesc_named_type (feature, "v2d"); - tdesc_add_field (type, "v2_double", field_type); - field_type = tdesc_named_type (feature, "v16i8"); - tdesc_add_field (type, "v16_int8", field_type); - field_type = tdesc_named_type (feature, "v8i16"); - tdesc_add_field (type, "v8_int16", field_type); - field_type = tdesc_named_type (feature, "v4i32"); - tdesc_add_field (type, "v4_int32", field_type); - field_type = tdesc_named_type (feature, "v2i64"); - tdesc_add_field (type, "v2_int64", field_type); - field_type = tdesc_named_type (feature, "uint128"); - tdesc_add_field (type, "uint128", field_type); - - type = tdesc_create_flags (feature, "i386_mxcsr", 4); - tdesc_add_flag (type, 0, "IE"); - tdesc_add_flag (type, 1, "DE"); - tdesc_add_flag (type, 2, "ZE"); - tdesc_add_flag (type, 3, "OE"); - tdesc_add_flag (type, 4, "UE"); - tdesc_add_flag (type, 5, "PE"); - tdesc_add_flag (type, 6, "DAZ"); - tdesc_add_flag (type, 7, "IM"); - tdesc_add_flag (type, 8, "DM"); - tdesc_add_flag (type, 9, "ZM"); - tdesc_add_flag (type, 10, "OM"); - tdesc_add_flag (type, 11, "UM"); - tdesc_add_flag (type, 12, "PM"); - tdesc_add_flag (type, 15, "FZ"); - - tdesc_create_reg (feature, "xmm0", 40, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm1", 41, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm2", 42, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm3", 43, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm4", 44, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm5", 45, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm6", 46, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm7", 47, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm8", 48, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm9", 49, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm10", 50, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm11", 51, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm12", 52, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm13", 53, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm14", 54, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "xmm15", 55, 1, NULL, 128, "vec128"); - tdesc_create_reg (feature, "mxcsr", 56, 1, "vector", 32, "i386_mxcsr"); - - tdesc_x32 = result; -} diff --git a/gdb/features/i386/x32.xml b/gdb/features/i386/x32.xml deleted file mode 100644 index 5d19bcf..0000000 --- a/gdb/features/i386/x32.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0"?> -<!-- Copyright (C) 2012-2017 Free Software Foundation, Inc. - - Copying and distribution of this file, with or without modification, - are permitted in any medium without royalty provided the copyright - notice and this notice are preserved. --> - -<!-- X32 --> - -<!DOCTYPE target SYSTEM "gdb-target.dtd"> -<target> - <architecture>i386:x64-32</architecture> - <xi:include href="x32-core.xml"/> - <xi:include href="64bit-sse.xml"/> -</target> diff --git a/gdb/features/mips-dsp-linux.c b/gdb/features/mips-dsp-linux.c index 80ceb22..26e9c6b 100644 --- a/gdb/features/mips-dsp-linux.c +++ b/gdb/features/mips-dsp-linux.c @@ -10,12 +10,12 @@ static void initialize_tdesc_mips_dsp_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("mips")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.mips.cpu"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int"); diff --git a/gdb/features/mips-linux.c b/gdb/features/mips-linux.c index c990119..c9ad3ca 100644 --- a/gdb/features/mips-linux.c +++ b/gdb/features/mips-linux.c @@ -10,12 +10,12 @@ static void initialize_tdesc_mips_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("mips")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.mips.cpu"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int"); diff --git a/gdb/features/mips64-dsp-linux.c b/gdb/features/mips64-dsp-linux.c index bc09078..05317b7 100644 --- a/gdb/features/mips64-dsp-linux.c +++ b/gdb/features/mips64-dsp-linux.c @@ -10,10 +10,10 @@ static void initialize_tdesc_mips64_dsp_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("mips")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.mips.cpu"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "int"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "int"); diff --git a/gdb/features/mips64-linux.c b/gdb/features/mips64-linux.c index 2ecda9b..4814152 100644 --- a/gdb/features/mips64-linux.c +++ b/gdb/features/mips64-linux.c @@ -10,10 +10,10 @@ static void initialize_tdesc_mips64_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("mips")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.mips.cpu"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "int"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "int"); diff --git a/gdb/features/nds32.c b/gdb/features/nds32.c index 21f63f5..89b246b 100644 --- a/gdb/features/nds32.c +++ b/gdb/features/nds32.c @@ -10,10 +10,10 @@ static void initialize_tdesc_nds32 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("n1h")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.nds32.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int"); diff --git a/gdb/features/nios2-linux.c b/gdb/features/nios2-linux.c index 3288f79..0368567 100644 --- a/gdb/features/nios2-linux.c +++ b/gdb/features/nios2-linux.c @@ -10,12 +10,12 @@ static void initialize_tdesc_nios2_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("nios2")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.nios2.cpu"); tdesc_create_reg (feature, "zero", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "at", 1, 1, NULL, 32, "uint32"); diff --git a/gdb/features/nios2.c b/gdb/features/nios2.c index 0cedc12..705f499 100644 --- a/gdb/features/nios2.c +++ b/gdb/features/nios2.c @@ -10,10 +10,10 @@ static void initialize_tdesc_nios2 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("nios2")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.nios2.cpu"); tdesc_create_reg (feature, "zero", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "at", 1, 1, NULL, 32, "uint32"); diff --git a/gdb/features/rs6000/powerpc-32.c b/gdb/features/rs6000/powerpc-32.c index 5ee5d9c..39f5b14 100644 --- a/gdb/features/rs6000/powerpc-32.c +++ b/gdb/features/rs6000/powerpc-32.c @@ -10,10 +10,10 @@ static void initialize_tdesc_powerpc_32 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); diff --git a/gdb/features/rs6000/powerpc-32l.c b/gdb/features/rs6000/powerpc-32l.c index 971fd4b..8089c04 100644 --- a/gdb/features/rs6000/powerpc-32l.c +++ b/gdb/features/rs6000/powerpc-32l.c @@ -10,10 +10,10 @@ static void initialize_tdesc_powerpc_32l (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); diff --git a/gdb/features/rs6000/powerpc-64.c b/gdb/features/rs6000/powerpc-64.c index 160d122..a9760a3 100644 --- a/gdb/features/rs6000/powerpc-64.c +++ b/gdb/features/rs6000/powerpc-64.c @@ -10,10 +10,10 @@ static void initialize_tdesc_powerpc_64 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common64")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64"); diff --git a/gdb/features/rs6000/powerpc-64l.c b/gdb/features/rs6000/powerpc-64l.c index 16a766e..408794e 100644 --- a/gdb/features/rs6000/powerpc-64l.c +++ b/gdb/features/rs6000/powerpc-64l.c @@ -10,10 +10,10 @@ static void initialize_tdesc_powerpc_64l (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common64")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64"); diff --git a/gdb/features/rs6000/powerpc-7400.c b/gdb/features/rs6000/powerpc-7400.c index 69d20c4..32b6995 100644 --- a/gdb/features/rs6000/powerpc-7400.c +++ b/gdb/features/rs6000/powerpc-7400.c @@ -11,8 +11,6 @@ initialize_tdesc_powerpc_7400 (void) { struct target_desc *result = allocate_target_description (); struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); @@ -140,6 +138,7 @@ initialize_tdesc_powerpc_7400 (void) tdesc_create_reg (feature, "ear", 118, 1, NULL, 32, "int"); feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "ieee_single"); tdesc_create_vector (feature, "v4f", field_type, 4); @@ -152,6 +151,7 @@ initialize_tdesc_powerpc_7400 (void) field_type = tdesc_named_type (feature, "int8"); tdesc_create_vector (feature, "v16i8", field_type, 16); + struct tdesc_type *type; type = tdesc_create_union (feature, "vec128"); field_type = tdesc_named_type (feature, "uint128"); tdesc_add_field (type, "uint128", field_type); diff --git a/gdb/features/rs6000/powerpc-altivec32.c b/gdb/features/rs6000/powerpc-altivec32.c index 285e87d..e97132e 100644 --- a/gdb/features/rs6000/powerpc-altivec32.c +++ b/gdb/features/rs6000/powerpc-altivec32.c @@ -10,12 +10,10 @@ static void initialize_tdesc_powerpc_altivec32 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); @@ -92,6 +90,7 @@ initialize_tdesc_powerpc_altivec32 (void) tdesc_create_reg (feature, "fpscr", 70, 1, "float", 32, "int"); feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "ieee_single"); tdesc_create_vector (feature, "v4f", field_type, 4); @@ -104,6 +103,7 @@ initialize_tdesc_powerpc_altivec32 (void) field_type = tdesc_named_type (feature, "int8"); tdesc_create_vector (feature, "v16i8", field_type, 16); + struct tdesc_type *type; type = tdesc_create_union (feature, "vec128"); field_type = tdesc_named_type (feature, "uint128"); tdesc_add_field (type, "uint128", field_type); diff --git a/gdb/features/rs6000/powerpc-altivec32l.c b/gdb/features/rs6000/powerpc-altivec32l.c index 447ed47..a9445d9 100644 --- a/gdb/features/rs6000/powerpc-altivec32l.c +++ b/gdb/features/rs6000/powerpc-altivec32l.c @@ -10,12 +10,10 @@ static void initialize_tdesc_powerpc_altivec32l (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); @@ -96,6 +94,7 @@ initialize_tdesc_powerpc_altivec32l (void) tdesc_create_reg (feature, "trap", 72, 1, NULL, 32, "int"); feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "ieee_single"); tdesc_create_vector (feature, "v4f", field_type, 4); @@ -108,6 +107,7 @@ initialize_tdesc_powerpc_altivec32l (void) field_type = tdesc_named_type (feature, "int8"); tdesc_create_vector (feature, "v16i8", field_type, 16); + struct tdesc_type *type; type = tdesc_create_union (feature, "vec128"); field_type = tdesc_named_type (feature, "uint128"); tdesc_add_field (type, "uint128", field_type); diff --git a/gdb/features/rs6000/powerpc-altivec64.c b/gdb/features/rs6000/powerpc-altivec64.c index 1e9a61d..3b626a9 100644 --- a/gdb/features/rs6000/powerpc-altivec64.c +++ b/gdb/features/rs6000/powerpc-altivec64.c @@ -10,12 +10,10 @@ static void initialize_tdesc_powerpc_altivec64 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common64")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64"); @@ -92,6 +90,7 @@ initialize_tdesc_powerpc_altivec64 (void) tdesc_create_reg (feature, "fpscr", 70, 1, "float", 32, "int"); feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "ieee_single"); tdesc_create_vector (feature, "v4f", field_type, 4); @@ -104,6 +103,7 @@ initialize_tdesc_powerpc_altivec64 (void) field_type = tdesc_named_type (feature, "int8"); tdesc_create_vector (feature, "v16i8", field_type, 16); + struct tdesc_type *type; type = tdesc_create_union (feature, "vec128"); field_type = tdesc_named_type (feature, "uint128"); tdesc_add_field (type, "uint128", field_type); diff --git a/gdb/features/rs6000/powerpc-altivec64l.c b/gdb/features/rs6000/powerpc-altivec64l.c index 10ecd8a..cca5353 100644 --- a/gdb/features/rs6000/powerpc-altivec64l.c +++ b/gdb/features/rs6000/powerpc-altivec64l.c @@ -10,12 +10,10 @@ static void initialize_tdesc_powerpc_altivec64l (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common64")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64"); @@ -96,6 +94,7 @@ initialize_tdesc_powerpc_altivec64l (void) tdesc_create_reg (feature, "trap", 72, 1, NULL, 64, "int"); feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "ieee_single"); tdesc_create_vector (feature, "v4f", field_type, 4); @@ -108,6 +107,7 @@ initialize_tdesc_powerpc_altivec64l (void) field_type = tdesc_named_type (feature, "int8"); tdesc_create_vector (feature, "v16i8", field_type, 16); + struct tdesc_type *type; type = tdesc_create_union (feature, "vec128"); field_type = tdesc_named_type (feature, "uint128"); tdesc_add_field (type, "uint128", field_type); diff --git a/gdb/features/rs6000/powerpc-cell32l.c b/gdb/features/rs6000/powerpc-cell32l.c index 7d33dc2..c615b8d 100644 --- a/gdb/features/rs6000/powerpc-cell32l.c +++ b/gdb/features/rs6000/powerpc-cell32l.c @@ -10,14 +10,12 @@ static void initialize_tdesc_powerpc_cell32l (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common")); tdesc_add_compatible (result, bfd_scan_arch ("spu:256K")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); @@ -98,6 +96,7 @@ initialize_tdesc_powerpc_cell32l (void) tdesc_create_reg (feature, "trap", 72, 1, NULL, 32, "int"); feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "ieee_single"); tdesc_create_vector (feature, "v4f", field_type, 4); @@ -110,6 +109,7 @@ initialize_tdesc_powerpc_cell32l (void) field_type = tdesc_named_type (feature, "int8"); tdesc_create_vector (feature, "v16i8", field_type, 16); + struct tdesc_type *type; type = tdesc_create_union (feature, "vec128"); field_type = tdesc_named_type (feature, "uint128"); tdesc_add_field (type, "uint128", field_type); diff --git a/gdb/features/rs6000/powerpc-cell64l.c b/gdb/features/rs6000/powerpc-cell64l.c index 6054c26..5040e5e 100644 --- a/gdb/features/rs6000/powerpc-cell64l.c +++ b/gdb/features/rs6000/powerpc-cell64l.c @@ -10,14 +10,12 @@ static void initialize_tdesc_powerpc_cell64l (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common64")); tdesc_add_compatible (result, bfd_scan_arch ("spu:256K")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64"); @@ -98,6 +96,7 @@ initialize_tdesc_powerpc_cell64l (void) tdesc_create_reg (feature, "trap", 72, 1, NULL, 64, "int"); feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "ieee_single"); tdesc_create_vector (feature, "v4f", field_type, 4); @@ -110,6 +109,7 @@ initialize_tdesc_powerpc_cell64l (void) field_type = tdesc_named_type (feature, "int8"); tdesc_create_vector (feature, "v16i8", field_type, 16); + struct tdesc_type *type; type = tdesc_create_union (feature, "vec128"); field_type = tdesc_named_type (feature, "uint128"); tdesc_add_field (type, "uint128", field_type); diff --git a/gdb/features/rs6000/powerpc-e500.c b/gdb/features/rs6000/powerpc-e500.c index aaca3a7..4466bc7 100644 --- a/gdb/features/rs6000/powerpc-e500.c +++ b/gdb/features/rs6000/powerpc-e500.c @@ -10,10 +10,10 @@ static void initialize_tdesc_powerpc_e500 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:e500")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); diff --git a/gdb/features/rs6000/powerpc-e500l.c b/gdb/features/rs6000/powerpc-e500l.c index de03862..61acbf3 100644 --- a/gdb/features/rs6000/powerpc-e500l.c +++ b/gdb/features/rs6000/powerpc-e500l.c @@ -10,10 +10,10 @@ static void initialize_tdesc_powerpc_e500l (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:e500")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); diff --git a/gdb/features/rs6000/powerpc-isa205-32l.c b/gdb/features/rs6000/powerpc-isa205-32l.c index 1b5bd6d..de6548f 100644 --- a/gdb/features/rs6000/powerpc-isa205-32l.c +++ b/gdb/features/rs6000/powerpc-isa205-32l.c @@ -10,10 +10,10 @@ static void initialize_tdesc_powerpc_isa205_32l (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); diff --git a/gdb/features/rs6000/powerpc-isa205-64l.c b/gdb/features/rs6000/powerpc-isa205-64l.c index 31bfc87..cd3b2c1 100644 --- a/gdb/features/rs6000/powerpc-isa205-64l.c +++ b/gdb/features/rs6000/powerpc-isa205-64l.c @@ -10,10 +10,10 @@ static void initialize_tdesc_powerpc_isa205_64l (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common64")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64"); diff --git a/gdb/features/rs6000/powerpc-isa205-altivec32l.c b/gdb/features/rs6000/powerpc-isa205-altivec32l.c index 6c216ce..943d02d 100644 --- a/gdb/features/rs6000/powerpc-isa205-altivec32l.c +++ b/gdb/features/rs6000/powerpc-isa205-altivec32l.c @@ -10,12 +10,10 @@ static void initialize_tdesc_powerpc_isa205_altivec32l (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); @@ -96,6 +94,7 @@ initialize_tdesc_powerpc_isa205_altivec32l (void) tdesc_create_reg (feature, "trap", 72, 1, NULL, 32, "int"); feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "ieee_single"); tdesc_create_vector (feature, "v4f", field_type, 4); @@ -108,6 +107,7 @@ initialize_tdesc_powerpc_isa205_altivec32l (void) field_type = tdesc_named_type (feature, "int8"); tdesc_create_vector (feature, "v16i8", field_type, 16); + struct tdesc_type *type; type = tdesc_create_union (feature, "vec128"); field_type = tdesc_named_type (feature, "uint128"); tdesc_add_field (type, "uint128", field_type); diff --git a/gdb/features/rs6000/powerpc-isa205-altivec64l.c b/gdb/features/rs6000/powerpc-isa205-altivec64l.c index 2c206aa..d454bac 100644 --- a/gdb/features/rs6000/powerpc-isa205-altivec64l.c +++ b/gdb/features/rs6000/powerpc-isa205-altivec64l.c @@ -10,12 +10,10 @@ static void initialize_tdesc_powerpc_isa205_altivec64l (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common64")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64"); @@ -96,6 +94,7 @@ initialize_tdesc_powerpc_isa205_altivec64l (void) tdesc_create_reg (feature, "trap", 72, 1, NULL, 64, "int"); feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "ieee_single"); tdesc_create_vector (feature, "v4f", field_type, 4); @@ -108,6 +107,7 @@ initialize_tdesc_powerpc_isa205_altivec64l (void) field_type = tdesc_named_type (feature, "int8"); tdesc_create_vector (feature, "v16i8", field_type, 16); + struct tdesc_type *type; type = tdesc_create_union (feature, "vec128"); field_type = tdesc_named_type (feature, "uint128"); tdesc_add_field (type, "uint128", field_type); diff --git a/gdb/features/rs6000/powerpc-isa205-vsx32l.c b/gdb/features/rs6000/powerpc-isa205-vsx32l.c index 4659ce1..09fd5ce 100644 --- a/gdb/features/rs6000/powerpc-isa205-vsx32l.c +++ b/gdb/features/rs6000/powerpc-isa205-vsx32l.c @@ -10,12 +10,10 @@ static void initialize_tdesc_powerpc_isa205_vsx32l (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); @@ -96,6 +94,7 @@ initialize_tdesc_powerpc_isa205_vsx32l (void) tdesc_create_reg (feature, "trap", 72, 1, NULL, 32, "int"); feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "ieee_single"); tdesc_create_vector (feature, "v4f", field_type, 4); @@ -108,6 +107,7 @@ initialize_tdesc_powerpc_isa205_vsx32l (void) field_type = tdesc_named_type (feature, "int8"); tdesc_create_vector (feature, "v16i8", field_type, 16); + struct tdesc_type *type; type = tdesc_create_union (feature, "vec128"); field_type = tdesc_named_type (feature, "uint128"); tdesc_add_field (type, "uint128", field_type); diff --git a/gdb/features/rs6000/powerpc-isa205-vsx64l.c b/gdb/features/rs6000/powerpc-isa205-vsx64l.c index 64b12b9..d295ab7 100644 --- a/gdb/features/rs6000/powerpc-isa205-vsx64l.c +++ b/gdb/features/rs6000/powerpc-isa205-vsx64l.c @@ -10,12 +10,10 @@ static void initialize_tdesc_powerpc_isa205_vsx64l (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common64")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64"); @@ -96,6 +94,7 @@ initialize_tdesc_powerpc_isa205_vsx64l (void) tdesc_create_reg (feature, "trap", 72, 1, NULL, 64, "int"); feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "ieee_single"); tdesc_create_vector (feature, "v4f", field_type, 4); @@ -108,6 +107,7 @@ initialize_tdesc_powerpc_isa205_vsx64l (void) field_type = tdesc_named_type (feature, "int8"); tdesc_create_vector (feature, "v16i8", field_type, 16); + struct tdesc_type *type; type = tdesc_create_union (feature, "vec128"); field_type = tdesc_named_type (feature, "uint128"); tdesc_add_field (type, "uint128", field_type); diff --git a/gdb/features/rs6000/powerpc-vsx32.c b/gdb/features/rs6000/powerpc-vsx32.c index ba1fcb6..8cf7562 100644 --- a/gdb/features/rs6000/powerpc-vsx32.c +++ b/gdb/features/rs6000/powerpc-vsx32.c @@ -10,12 +10,10 @@ static void initialize_tdesc_powerpc_vsx32 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); @@ -92,6 +90,7 @@ initialize_tdesc_powerpc_vsx32 (void) tdesc_create_reg (feature, "fpscr", 70, 1, "float", 32, "int"); feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "ieee_single"); tdesc_create_vector (feature, "v4f", field_type, 4); @@ -104,6 +103,7 @@ initialize_tdesc_powerpc_vsx32 (void) field_type = tdesc_named_type (feature, "int8"); tdesc_create_vector (feature, "v16i8", field_type, 16); + struct tdesc_type *type; type = tdesc_create_union (feature, "vec128"); field_type = tdesc_named_type (feature, "uint128"); tdesc_add_field (type, "uint128", field_type); diff --git a/gdb/features/rs6000/powerpc-vsx32l.c b/gdb/features/rs6000/powerpc-vsx32l.c index 013e392..e8c1881 100644 --- a/gdb/features/rs6000/powerpc-vsx32l.c +++ b/gdb/features/rs6000/powerpc-vsx32l.c @@ -10,12 +10,10 @@ static void initialize_tdesc_powerpc_vsx32l (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); @@ -96,6 +94,7 @@ initialize_tdesc_powerpc_vsx32l (void) tdesc_create_reg (feature, "trap", 72, 1, NULL, 32, "int"); feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "ieee_single"); tdesc_create_vector (feature, "v4f", field_type, 4); @@ -108,6 +107,7 @@ initialize_tdesc_powerpc_vsx32l (void) field_type = tdesc_named_type (feature, "int8"); tdesc_create_vector (feature, "v16i8", field_type, 16); + struct tdesc_type *type; type = tdesc_create_union (feature, "vec128"); field_type = tdesc_named_type (feature, "uint128"); tdesc_add_field (type, "uint128", field_type); diff --git a/gdb/features/rs6000/powerpc-vsx64.c b/gdb/features/rs6000/powerpc-vsx64.c index ca02323..30953c5 100644 --- a/gdb/features/rs6000/powerpc-vsx64.c +++ b/gdb/features/rs6000/powerpc-vsx64.c @@ -10,12 +10,10 @@ static void initialize_tdesc_powerpc_vsx64 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common64")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64"); @@ -92,6 +90,7 @@ initialize_tdesc_powerpc_vsx64 (void) tdesc_create_reg (feature, "fpscr", 70, 1, "float", 32, "int"); feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "ieee_single"); tdesc_create_vector (feature, "v4f", field_type, 4); @@ -104,6 +103,7 @@ initialize_tdesc_powerpc_vsx64 (void) field_type = tdesc_named_type (feature, "int8"); tdesc_create_vector (feature, "v16i8", field_type, 16); + struct tdesc_type *type; type = tdesc_create_union (feature, "vec128"); field_type = tdesc_named_type (feature, "uint128"); tdesc_add_field (type, "uint128", field_type); diff --git a/gdb/features/rs6000/powerpc-vsx64l.c b/gdb/features/rs6000/powerpc-vsx64l.c index 31bb224..5f12650 100644 --- a/gdb/features/rs6000/powerpc-vsx64l.c +++ b/gdb/features/rs6000/powerpc-vsx64l.c @@ -10,12 +10,10 @@ static void initialize_tdesc_powerpc_vsx64l (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common64")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64"); @@ -96,6 +94,7 @@ initialize_tdesc_powerpc_vsx64l (void) tdesc_create_reg (feature, "trap", 72, 1, NULL, 64, "int"); feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "ieee_single"); tdesc_create_vector (feature, "v4f", field_type, 4); @@ -108,6 +107,7 @@ initialize_tdesc_powerpc_vsx64l (void) field_type = tdesc_named_type (feature, "int8"); tdesc_create_vector (feature, "v16i8", field_type, 16); + struct tdesc_type *type; type = tdesc_create_union (feature, "vec128"); field_type = tdesc_named_type (feature, "uint128"); tdesc_add_field (type, "uint128", field_type); diff --git a/gdb/features/rs6000/rs6000.c b/gdb/features/rs6000/rs6000.c index d4e93a5..709b5da 100644 --- a/gdb/features/rs6000/rs6000.c +++ b/gdb/features/rs6000/rs6000.c @@ -10,10 +10,10 @@ static void initialize_tdesc_rs6000 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("rs6000:6000")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int"); tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int"); diff --git a/gdb/features/s390-linux32.c b/gdb/features/s390-linux32.c index 6d13094..01c136c 100644 --- a/gdb/features/s390-linux32.c +++ b/gdb/features/s390-linux32.c @@ -10,10 +10,10 @@ static void initialize_tdesc_s390_linux32 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("s390:31-bit")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.s390.core"); tdesc_create_reg (feature, "pswm", 0, 1, "psw", 32, "uint32"); tdesc_create_reg (feature, "pswa", 1, 1, "psw", 32, "uint32"); diff --git a/gdb/features/s390-linux32v1.c b/gdb/features/s390-linux32v1.c index f773fc1..65a4a50 100644 --- a/gdb/features/s390-linux32v1.c +++ b/gdb/features/s390-linux32v1.c @@ -10,10 +10,10 @@ static void initialize_tdesc_s390_linux32v1 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("s390:31-bit")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.s390.core"); tdesc_create_reg (feature, "pswm", 0, 1, "psw", 32, "uint32"); tdesc_create_reg (feature, "pswa", 1, 1, "psw", 32, "uint32"); diff --git a/gdb/features/s390-linux32v2.c b/gdb/features/s390-linux32v2.c index 2317752..b5d25ec 100644 --- a/gdb/features/s390-linux32v2.c +++ b/gdb/features/s390-linux32v2.c @@ -10,10 +10,10 @@ static void initialize_tdesc_s390_linux32v2 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("s390:31-bit")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.s390.core"); tdesc_create_reg (feature, "pswm", 0, 1, "psw", 32, "uint32"); tdesc_create_reg (feature, "pswa", 1, 1, "psw", 32, "uint32"); diff --git a/gdb/features/s390-linux64.c b/gdb/features/s390-linux64.c index 3c7145b..531d3a1 100644 --- a/gdb/features/s390-linux64.c +++ b/gdb/features/s390-linux64.c @@ -10,10 +10,10 @@ static void initialize_tdesc_s390_linux64 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("s390:31-bit")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.s390.core"); tdesc_create_reg (feature, "pswm", 0, 1, "psw", 32, "uint32"); tdesc_create_reg (feature, "pswa", 1, 1, "psw", 32, "uint32"); diff --git a/gdb/features/s390-linux64v1.c b/gdb/features/s390-linux64v1.c index 72bd894..d75deca 100644 --- a/gdb/features/s390-linux64v1.c +++ b/gdb/features/s390-linux64v1.c @@ -10,10 +10,10 @@ static void initialize_tdesc_s390_linux64v1 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("s390:31-bit")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.s390.core"); tdesc_create_reg (feature, "pswm", 0, 1, "psw", 32, "uint32"); tdesc_create_reg (feature, "pswa", 1, 1, "psw", 32, "uint32"); diff --git a/gdb/features/s390-linux64v2.c b/gdb/features/s390-linux64v2.c index a1757da..bd10ee8 100644 --- a/gdb/features/s390-linux64v2.c +++ b/gdb/features/s390-linux64v2.c @@ -10,10 +10,10 @@ static void initialize_tdesc_s390_linux64v2 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("s390:31-bit")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.s390.core"); tdesc_create_reg (feature, "pswm", 0, 1, "psw", 32, "uint32"); tdesc_create_reg (feature, "pswa", 1, 1, "psw", 32, "uint32"); diff --git a/gdb/features/s390-te-linux64.c b/gdb/features/s390-te-linux64.c index 0a3aedf..fe2020a 100644 --- a/gdb/features/s390-te-linux64.c +++ b/gdb/features/s390-te-linux64.c @@ -10,10 +10,10 @@ static void initialize_tdesc_s390_te_linux64 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("s390:31-bit")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.s390.core"); tdesc_create_reg (feature, "pswm", 0, 1, "psw", 32, "uint32"); tdesc_create_reg (feature, "pswa", 1, 1, "psw", 32, "uint32"); diff --git a/gdb/features/s390-tevx-linux64.c b/gdb/features/s390-tevx-linux64.c index 5bc3eec..d9b18d3 100644 --- a/gdb/features/s390-tevx-linux64.c +++ b/gdb/features/s390-tevx-linux64.c @@ -10,12 +10,10 @@ static void initialize_tdesc_s390_tevx_linux64 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("s390:31-bit")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.s390.core"); tdesc_create_reg (feature, "pswm", 0, 1, "psw", 32, "uint32"); tdesc_create_reg (feature, "pswa", 1, 1, "psw", 32, "uint32"); @@ -117,6 +115,7 @@ initialize_tdesc_s390_tevx_linux64 (void) tdesc_create_reg (feature, "tr15", 89, 1, "tdb", 64, "uint64"); feature = tdesc_create_feature (result, "org.gnu.gdb.s390.vx"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "ieee_single"); tdesc_create_vector (feature, "v4f", field_type, 4); @@ -135,6 +134,7 @@ initialize_tdesc_s390_tevx_linux64 (void) field_type = tdesc_named_type (feature, "int64"); tdesc_create_vector (feature, "v2i64", field_type, 2); + struct tdesc_type *type; type = tdesc_create_union (feature, "vec128"); field_type = tdesc_named_type (feature, "v4f"); tdesc_add_field (type, "v4_float", field_type); diff --git a/gdb/features/s390-vx-linux64.c b/gdb/features/s390-vx-linux64.c index c3ffa16..b2138dd 100644 --- a/gdb/features/s390-vx-linux64.c +++ b/gdb/features/s390-vx-linux64.c @@ -10,12 +10,10 @@ static void initialize_tdesc_s390_vx_linux64 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("s390:31-bit")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.s390.core"); tdesc_create_reg (feature, "pswm", 0, 1, "psw", 32, "uint32"); tdesc_create_reg (feature, "pswa", 1, 1, "psw", 32, "uint32"); @@ -95,6 +93,7 @@ initialize_tdesc_s390_vx_linux64 (void) tdesc_create_reg (feature, "system_call", 69, 1, "system", 32, "uint32"); feature = tdesc_create_feature (result, "org.gnu.gdb.s390.vx"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "ieee_single"); tdesc_create_vector (feature, "v4f", field_type, 4); @@ -113,6 +112,7 @@ initialize_tdesc_s390_vx_linux64 (void) field_type = tdesc_named_type (feature, "int64"); tdesc_create_vector (feature, "v2i64", field_type, 2); + struct tdesc_type *type; type = tdesc_create_union (feature, "vec128"); field_type = tdesc_named_type (feature, "v4f"); tdesc_add_field (type, "v4_float", field_type); diff --git a/gdb/features/s390x-linux64.c b/gdb/features/s390x-linux64.c index 04502c6..9d48ea3 100644 --- a/gdb/features/s390x-linux64.c +++ b/gdb/features/s390x-linux64.c @@ -10,10 +10,10 @@ static void initialize_tdesc_s390x_linux64 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("s390:64-bit")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.s390.core"); tdesc_create_reg (feature, "pswm", 0, 1, "psw", 64, "uint64"); tdesc_create_reg (feature, "pswa", 1, 1, "psw", 64, "uint64"); diff --git a/gdb/features/s390x-linux64v1.c b/gdb/features/s390x-linux64v1.c index 05bfd53..b95f1c4 100644 --- a/gdb/features/s390x-linux64v1.c +++ b/gdb/features/s390x-linux64v1.c @@ -10,10 +10,10 @@ static void initialize_tdesc_s390x_linux64v1 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("s390:64-bit")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.s390.core"); tdesc_create_reg (feature, "pswm", 0, 1, "psw", 64, "uint64"); tdesc_create_reg (feature, "pswa", 1, 1, "psw", 64, "uint64"); diff --git a/gdb/features/s390x-linux64v2.c b/gdb/features/s390x-linux64v2.c index 4108cc0..9aab89f 100644 --- a/gdb/features/s390x-linux64v2.c +++ b/gdb/features/s390x-linux64v2.c @@ -10,10 +10,10 @@ static void initialize_tdesc_s390x_linux64v2 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("s390:64-bit")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.s390.core"); tdesc_create_reg (feature, "pswm", 0, 1, "psw", 64, "uint64"); tdesc_create_reg (feature, "pswa", 1, 1, "psw", 64, "uint64"); diff --git a/gdb/features/s390x-te-linux64.c b/gdb/features/s390x-te-linux64.c index f75d900..babd3bd 100644 --- a/gdb/features/s390x-te-linux64.c +++ b/gdb/features/s390x-te-linux64.c @@ -10,10 +10,10 @@ static void initialize_tdesc_s390x_te_linux64 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("s390:64-bit")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.s390.core"); tdesc_create_reg (feature, "pswm", 0, 1, "psw", 64, "uint64"); tdesc_create_reg (feature, "pswa", 1, 1, "psw", 64, "uint64"); diff --git a/gdb/features/s390x-tevx-linux64.c b/gdb/features/s390x-tevx-linux64.c index 327cd23..02afd3a 100644 --- a/gdb/features/s390x-tevx-linux64.c +++ b/gdb/features/s390x-tevx-linux64.c @@ -10,12 +10,10 @@ static void initialize_tdesc_s390x_tevx_linux64 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("s390:64-bit")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.s390.core"); tdesc_create_reg (feature, "pswm", 0, 1, "psw", 64, "uint64"); tdesc_create_reg (feature, "pswa", 1, 1, "psw", 64, "uint64"); @@ -101,6 +99,7 @@ initialize_tdesc_s390x_tevx_linux64 (void) tdesc_create_reg (feature, "tr15", 73, 1, "tdb", 64, "uint64"); feature = tdesc_create_feature (result, "org.gnu.gdb.s390.vx"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "ieee_single"); tdesc_create_vector (feature, "v4f", field_type, 4); @@ -119,6 +118,7 @@ initialize_tdesc_s390x_tevx_linux64 (void) field_type = tdesc_named_type (feature, "int64"); tdesc_create_vector (feature, "v2i64", field_type, 2); + struct tdesc_type *type; type = tdesc_create_union (feature, "vec128"); field_type = tdesc_named_type (feature, "v4f"); tdesc_add_field (type, "v4_float", field_type); diff --git a/gdb/features/s390x-vx-linux64.c b/gdb/features/s390x-vx-linux64.c index e66da70..120db53 100644 --- a/gdb/features/s390x-vx-linux64.c +++ b/gdb/features/s390x-vx-linux64.c @@ -10,12 +10,10 @@ static void initialize_tdesc_s390x_vx_linux64 (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - struct tdesc_type *field_type; - struct tdesc_type *type; - set_tdesc_architecture (result, bfd_scan_arch ("s390:64-bit")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.s390.core"); tdesc_create_reg (feature, "pswm", 0, 1, "psw", 64, "uint64"); tdesc_create_reg (feature, "pswa", 1, 1, "psw", 64, "uint64"); @@ -79,6 +77,7 @@ initialize_tdesc_s390x_vx_linux64 (void) tdesc_create_reg (feature, "system_call", 53, 1, "system", 32, "uint32"); feature = tdesc_create_feature (result, "org.gnu.gdb.s390.vx"); + struct tdesc_type *field_type; field_type = tdesc_named_type (feature, "ieee_single"); tdesc_create_vector (feature, "v4f", field_type, 4); @@ -97,6 +96,7 @@ initialize_tdesc_s390x_vx_linux64 (void) field_type = tdesc_named_type (feature, "int64"); tdesc_create_vector (feature, "v2i64", field_type, 2); + struct tdesc_type *type; type = tdesc_create_union (feature, "vec128"); field_type = tdesc_named_type (feature, "v4f"); tdesc_add_field (type, "v4_float", field_type); diff --git a/gdb/features/tic6x-c62x-linux.c b/gdb/features/tic6x-c62x-linux.c index 8dd426d..86b905d 100644 --- a/gdb/features/tic6x-c62x-linux.c +++ b/gdb/features/tic6x-c62x-linux.c @@ -10,12 +10,12 @@ static void initialize_tdesc_tic6x_c62x_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("tic6x")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.tic6x.core"); tdesc_create_reg (feature, "A0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "A1", 1, 1, NULL, 32, "uint32"); diff --git a/gdb/features/tic6x-c62x.c b/gdb/features/tic6x-c62x.c index 2089aaf..7dbf615 100644 --- a/gdb/features/tic6x-c62x.c +++ b/gdb/features/tic6x-c62x.c @@ -10,10 +10,10 @@ static void initialize_tdesc_tic6x_c62x (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("tic6x")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.tic6x.core"); tdesc_create_reg (feature, "A0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "A1", 1, 1, NULL, 32, "uint32"); diff --git a/gdb/features/tic6x-c64x-linux.c b/gdb/features/tic6x-c64x-linux.c index 2752358..b52048f 100644 --- a/gdb/features/tic6x-c64x-linux.c +++ b/gdb/features/tic6x-c64x-linux.c @@ -10,12 +10,12 @@ static void initialize_tdesc_tic6x_c64x_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("tic6x")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.tic6x.core"); tdesc_create_reg (feature, "A0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "A1", 1, 1, NULL, 32, "uint32"); diff --git a/gdb/features/tic6x-c64x.c b/gdb/features/tic6x-c64x.c index 0feda24..618f802 100644 --- a/gdb/features/tic6x-c64x.c +++ b/gdb/features/tic6x-c64x.c @@ -10,10 +10,10 @@ static void initialize_tdesc_tic6x_c64x (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("tic6x")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.tic6x.core"); tdesc_create_reg (feature, "A0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "A1", 1, 1, NULL, 32, "uint32"); diff --git a/gdb/features/tic6x-c64xp-linux.c b/gdb/features/tic6x-c64xp-linux.c index c1bee4c..ca8c505 100644 --- a/gdb/features/tic6x-c64xp-linux.c +++ b/gdb/features/tic6x-c64xp-linux.c @@ -10,12 +10,12 @@ static void initialize_tdesc_tic6x_c64xp_linux (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("tic6x")); set_tdesc_osabi (result, osabi_from_tdesc_string ("GNU/Linux")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.tic6x.core"); tdesc_create_reg (feature, "A0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "A1", 1, 1, NULL, 32, "uint32"); diff --git a/gdb/features/tic6x-c64xp.c b/gdb/features/tic6x-c64xp.c index 160b854..4ca5125 100644 --- a/gdb/features/tic6x-c64xp.c +++ b/gdb/features/tic6x-c64xp.c @@ -10,10 +10,10 @@ static void initialize_tdesc_tic6x_c64xp (void) { struct target_desc *result = allocate_target_description (); - struct tdesc_feature *feature; - set_tdesc_architecture (result, bfd_scan_arch ("tic6x")); + struct tdesc_feature *feature; + feature = tdesc_create_feature (result, "org.gnu.gdb.tic6x.core"); tdesc_create_reg (feature, "A0", 0, 1, NULL, 32, "uint32"); tdesc_create_reg (feature, "A1", 1, 1, NULL, 32, "uint32"); diff --git a/gdb/filename-seen-cache.c b/gdb/filename-seen-cache.c new file mode 100644 index 0000000..6282105 --- /dev/null +++ b/gdb/filename-seen-cache.c @@ -0,0 +1,66 @@ +/* Filename-seen cache for the GNU debugger, GDB. + + Copyright (C) 1986-2017 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "defs.h" +#include "filename-seen-cache.h" +#include "filenames.h" + + /* Initial size of the table. It automagically grows from here. */ +#define INITIAL_FILENAME_SEEN_CACHE_SIZE 100 + +/* filename_seen_cache constructor. */ + +filename_seen_cache::filename_seen_cache () +{ + m_tab = htab_create_alloc (INITIAL_FILENAME_SEEN_CACHE_SIZE, + filename_hash, filename_eq, + NULL, xcalloc, xfree); +} + +/* See filename-seen-cache.h. */ + +void +filename_seen_cache::clear () +{ + htab_empty (m_tab); +} + +/* See filename-seen-cache.h. */ + +filename_seen_cache::~filename_seen_cache () +{ + htab_delete (m_tab); +} + +/* See filename-seen-cache.h. */ + +bool +filename_seen_cache::seen (const char *file) +{ + void **slot; + + /* Is FILE in tab? */ + slot = htab_find_slot (m_tab, file, INSERT); + if (*slot != NULL) + return true; + + /* No; add it to tab. */ + *slot = (char *) file; + return false; +} diff --git a/gdb/filename-seen-cache.h b/gdb/filename-seen-cache.h new file mode 100644 index 0000000..dd9cf7a --- /dev/null +++ b/gdb/filename-seen-cache.h @@ -0,0 +1,63 @@ +/* Filename-seen cache for the GNU debugger, GDB. + + Copyright (C) 1986-2017 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "defs.h" +#include "common/function-view.h" + +/* Cache to watch for file names already seen. */ + +class filename_seen_cache +{ +public: + filename_seen_cache (); + ~filename_seen_cache (); + + /* Disable copy. */ + filename_seen_cache (const filename_seen_cache &) = delete; + void operator= (const filename_seen_cache &) = delete; + + /* Empty the cache, but do not delete it. */ + void clear (); + + /* If FILE is not already in the table of files in CACHE, add it and + return false; otherwise return true. + + NOTE: We don't manage space for FILE, we assume FILE lives as + long as the caller needs. */ + bool seen (const char *file); + + /* Traverse all cache entries, calling CALLBACK on each. The + filename is passed as argument to CALLBACK. */ + void traverse (gdb::function_view<void (const char *filename)> callback) + { + auto erased_cb = [] (void **slot, void *info) -> int + { + auto filename = (const char *) *slot; + auto restored_cb = (decltype (callback) *) info; + (*restored_cb) (filename); + return 1; + }; + + htab_traverse_noresize (m_tab, erased_cb, &callback); + } + +private: + /* Table of files seen so far. */ + htab_t m_tab; +}; diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c index 4d21349..3a75013 100644 --- a/gdb/frame-unwind.c +++ b/gdb/frame-unwind.c @@ -106,8 +106,11 @@ frame_unwind_try_unwinder (struct frame_info *this_frame, void **this_cache, { res = unwinder->sniffer (unwinder, this_frame, this_cache); } - CATCH (ex, RETURN_MASK_ERROR) + CATCH (ex, RETURN_MASK_ALL) { + /* Catch all exceptions, caused by either interrupt or error. + Reset *THIS_CACHE. */ + *this_cache = NULL; if (ex.error == NOT_AVAILABLE_ERROR) { /* This usually means that not even the PC is available, @@ -128,6 +131,8 @@ frame_unwind_try_unwinder (struct frame_info *this_frame, void **this_cache, } else { + /* Don't set *THIS_CACHE to NULL here, because sniffer has to do + so. */ do_cleanups (old_cleanup); return 0; } diff --git a/gdb/frame-unwind.h b/gdb/frame-unwind.h index 4588cef..8226b6d 100644 --- a/gdb/frame-unwind.h +++ b/gdb/frame-unwind.h @@ -46,7 +46,8 @@ struct value; the PC and attributes) and if SELF is the applicable unwinder, return non-zero. Possibly also initialize THIS_PROLOGUE_CACHE; but only if returning 1. Initializing THIS_PROLOGUE_CACHE in other - cases (0 return, or exception) is invalid. */ + cases (0 return) is invalid. In case of exception, the caller has + to set *THIS_PROLOGUE_CACHE to NULL. */ typedef int (frame_sniffer_ftype) (const struct frame_unwind *self, struct frame_info *this_frame, diff --git a/gdb/gcore.c b/gdb/gcore.c index c32d2ff..50aff2c 100644 --- a/gdb/gcore.c +++ b/gdb/gcore.c @@ -36,6 +36,7 @@ #include "readline/tilde.h" #include <algorithm> #include "common/gdb_unlinker.h" +#include "byte-vector.h" /* The largest amount of memory to read from the target at once. We must throttle it to limit the amount of memory used by GDB during @@ -548,8 +549,6 @@ gcore_copy_callback (bfd *obfd, asection *osec, void *ignored) { bfd_size_type size, total_size = bfd_section_size (obfd, osec); file_ptr offset = 0; - struct cleanup *old_chain = NULL; - gdb_byte *memhunk; /* Read-only sections are marked; we don't have to copy their contents. */ if ((bfd_get_section_flags (obfd, osec) & SEC_LOAD) == 0) @@ -560,8 +559,7 @@ gcore_copy_callback (bfd *obfd, asection *osec, void *ignored) return; size = std::min (total_size, (bfd_size_type) MAX_COPY_BYTES); - memhunk = (gdb_byte *) xmalloc (size); - old_chain = make_cleanup (xfree, memhunk); + gdb::byte_vector memhunk (size); while (total_size > 0) { @@ -569,7 +567,7 @@ gcore_copy_callback (bfd *obfd, asection *osec, void *ignored) size = total_size; if (target_read_memory (bfd_section_vma (obfd, osec) + offset, - memhunk, size) != 0) + memhunk.data (), size) != 0) { warning (_("Memory read failed for corefile " "section, %s bytes at %s."), @@ -577,7 +575,8 @@ gcore_copy_callback (bfd *obfd, asection *osec, void *ignored) paddress (target_gdbarch (), bfd_section_vma (obfd, osec))); break; } - if (!bfd_set_section_contents (obfd, osec, memhunk, offset, size)) + if (!bfd_set_section_contents (obfd, osec, memhunk.data (), + offset, size)) { warning (_("Failed to write corefile contents (%s)."), bfd_errmsg (bfd_get_error ())); @@ -587,8 +586,6 @@ gcore_copy_callback (bfd *obfd, asection *osec, void *ignored) total_size -= size; offset += size; } - - do_cleanups (old_chain); /* Frees MEMHUNK. */ } static int diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c index 2230127..c0dc191 100644 --- a/gdb/gdb_bfd.c +++ b/gdb/gdb_bfd.c @@ -976,18 +976,15 @@ print_one_bfd (void **slot, void *data) static void maintenance_info_bfds (char *arg, int from_tty) { - struct cleanup *cleanup; struct ui_out *uiout = current_uiout; - cleanup = make_cleanup_ui_out_table_begin_end (uiout, 3, -1, "bfds"); + ui_out_emit_table table_emitter (uiout, 3, -1, "bfds"); uiout->table_header (10, ui_left, "refcount", "Refcount"); uiout->table_header (18, ui_left, "addr", "Address"); uiout->table_header (40, ui_left, "filename", "Filename"); uiout->table_body (); htab_traverse (all_bfds, print_one_bfd, uiout); - - do_cleanups (cleanup); } /* -Wmissing-prototypes */ diff --git a/gdb/gdb_obstack.h b/gdb/gdb_obstack.h index 3f34d96..b241c82 100644 --- a/gdb/gdb_obstack.h +++ b/gdb/gdb_obstack.h @@ -63,4 +63,19 @@ extern char *obconcat (struct obstack *obstackp, ...) ATTRIBUTE_SENTINEL; extern char *obstack_strdup (struct obstack *obstackp, const char *string); +/* An obstack that frees itself on scope exit. */ +struct auto_obstack : obstack +{ + auto_obstack () + { obstack_init (this); } + + ~auto_obstack () + { obstack_free (this, NULL); } + + /* Free all memory in the obstack but leave it valid for further + allocation. */ + void clear () + { obstack_free (this, obstack_base (this)); } +}; + #endif diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index e5efdfb..24521b5 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -287,6 +287,7 @@ struct gdbarch gdbarch_core_xfer_shared_libraries_aix_ftype *core_xfer_shared_libraries_aix; gdbarch_core_pid_to_str_ftype *core_pid_to_str; gdbarch_core_thread_name_ftype *core_thread_name; + gdbarch_core_xfer_siginfo_ftype *core_xfer_siginfo; const char * gcore_bfd_target; int vtable_function_descriptors; int vbit_in_delta; @@ -646,6 +647,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of core_xfer_shared_libraries_aix, has predicate. */ /* Skip verify of core_pid_to_str, has predicate. */ /* Skip verify of core_thread_name, has predicate. */ + /* Skip verify of core_xfer_siginfo, has predicate. */ /* Skip verify of gcore_bfd_target, has predicate. */ /* Skip verify of vtable_function_descriptors, invalid_p == 0 */ /* Skip verify of vbit_in_delta, invalid_p == 0 */ @@ -884,6 +886,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: core_xfer_shared_libraries_aix = <%s>\n", host_address_to_string (gdbarch->core_xfer_shared_libraries_aix)); fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_core_xfer_siginfo_p() = %d\n", + gdbarch_core_xfer_siginfo_p (gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: core_xfer_siginfo = <%s>\n", + host_address_to_string (gdbarch->core_xfer_siginfo)); + fprintf_unfiltered (file, "gdbarch_dump: decr_pc_after_break = %s\n", core_addr_to_string_nz (gdbarch->decr_pc_after_break)); fprintf_unfiltered (file, @@ -3797,6 +3805,30 @@ set_gdbarch_core_thread_name (struct gdbarch *gdbarch, } int +gdbarch_core_xfer_siginfo_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->core_xfer_siginfo != NULL; +} + +LONGEST +gdbarch_core_xfer_siginfo (struct gdbarch *gdbarch, gdb_byte *readbuf, ULONGEST offset, ULONGEST len) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->core_xfer_siginfo != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_core_xfer_siginfo called\n"); + return gdbarch->core_xfer_siginfo (gdbarch, readbuf, offset, len); +} + +void +set_gdbarch_core_xfer_siginfo (struct gdbarch *gdbarch, + gdbarch_core_xfer_siginfo_ftype core_xfer_siginfo) +{ + gdbarch->core_xfer_siginfo = core_xfer_siginfo; +} + +int gdbarch_gcore_bfd_target_p (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index ab7561f..ceb867f 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -933,6 +933,16 @@ typedef const char * (gdbarch_core_thread_name_ftype) (struct gdbarch *gdbarch, extern const char * gdbarch_core_thread_name (struct gdbarch *gdbarch, struct thread_info *thr); extern void set_gdbarch_core_thread_name (struct gdbarch *gdbarch, gdbarch_core_thread_name_ftype *core_thread_name); +/* Read offset OFFSET of TARGET_OBJECT_SIGNAL_INFO signal information + from core file into buffer READBUF with length LEN. Return the number + of bytes read (zero indicates EOF, a negative value indicates failure). */ + +extern int gdbarch_core_xfer_siginfo_p (struct gdbarch *gdbarch); + +typedef LONGEST (gdbarch_core_xfer_siginfo_ftype) (struct gdbarch *gdbarch, gdb_byte *readbuf, ULONGEST offset, ULONGEST len); +extern LONGEST gdbarch_core_xfer_siginfo (struct gdbarch *gdbarch, gdb_byte *readbuf, ULONGEST offset, ULONGEST len); +extern void set_gdbarch_core_xfer_siginfo (struct gdbarch *gdbarch, gdbarch_core_xfer_siginfo_ftype *core_xfer_siginfo); + /* BFD target to use when generating a core file. */ extern int gdbarch_gcore_bfd_target_p (struct gdbarch *gdbarch); @@ -1637,7 +1647,21 @@ struct gdbarch_info bfd *abfd; /* Use default: NULL (ZERO). */ - void *tdep_info; + union + { + /* Architecture-specific information. The generic form for targets + that have extra requirements. */ + struct gdbarch_tdep_info *tdep_info; + + /* Architecture-specific target description data. Numerous targets + need only this, so give them an easy way to hold it. */ + struct tdesc_arch_data *tdesc_data; + + /* SPU file system ID. This is a single integer, so using the + generic form would only complicate code. Other targets may + reuse this member if suitable. */ + int *id; + }; /* Use default: GDB_OSABI_UNINITIALIZED (-1). */ enum gdb_osabi osabi; diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index 22f5715..36451b1 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -755,6 +755,11 @@ M;const char *;core_pid_to_str;ptid_t ptid;ptid # How the core target extracts the name of a thread from a core file. M;const char *;core_thread_name;struct thread_info *thr;thr +# Read offset OFFSET of TARGET_OBJECT_SIGNAL_INFO signal information +# from core file into buffer READBUF with length LEN. Return the number +# of bytes read (zero indicates EOF, a negative value indicates failure). +M;LONGEST;core_xfer_siginfo;gdb_byte *readbuf, ULONGEST offset, ULONGEST len; readbuf, offset, len + # BFD target to use when generating a core file. V;const char *;gcore_bfd_target;;;0;0;;;pstring (gdbarch->gcore_bfd_target) @@ -1469,7 +1474,21 @@ struct gdbarch_info bfd *abfd; /* Use default: NULL (ZERO). */ - void *tdep_info; + union + { + /* Architecture-specific information. The generic form for targets + that have extra requirements. */ + struct gdbarch_tdep_info *tdep_info; + + /* Architecture-specific target description data. Numerous targets + need only this, so give them an easy way to hold it. */ + struct tdesc_arch_data *tdesc_data; + + /* SPU file system ID. This is a single integer, so using the + generic form would only complicate code. Other targets may + reuse this member if suitable. */ + int *id; + }; /* Use default: GDB_OSABI_UNINITIALIZED (-1). */ enum gdb_osabi osabi; diff --git a/gdb/gdbcmd.h b/gdb/gdbcmd.h index fbd0cb9..14c7f4e 100644 --- a/gdb/gdbcmd.h +++ b/gdb/gdbcmd.h @@ -95,6 +95,10 @@ extern struct cmd_list_element *maintenanceinfolist; extern struct cmd_list_element *maintenanceprintlist; +/* Chain containing all defined "maintenance check" subcommands. */ + +extern struct cmd_list_element *maintenancechecklist; + /* Chain containing all defined "maintenance set" subcommands. */ extern struct cmd_list_element *maintenance_set_cmdlist; diff --git a/gdb/gdbcore.h b/gdb/gdbcore.h index e3eed03..87f3dcd 100644 --- a/gdb/gdbcore.h +++ b/gdb/gdbcore.h @@ -226,6 +226,51 @@ struct core_fns }; +/* Build either a single-thread or multi-threaded section name for + PTID. + + If ptid's lwp member is zero, we want to do the single-threaded + thing: look for a section named NAME (as passed to the + constructor). If ptid's lwp member is non-zero, we'll want do the + multi-threaded thing: look for a section named "NAME/LWP", where + LWP is the shortest ASCII decimal representation of ptid's lwp + member. */ + +class thread_section_name +{ +public: + /* NAME is the single-threaded section name. If PTID represents an + LWP, then the build section name is "NAME/LWP", otherwise it's + just "NAME" unmodified. */ + thread_section_name (const char *name, ptid_t ptid) + { + if (ptid.lwp_p ()) + { + m_storage = string_printf ("%s/%ld", name, ptid.lwp ()); + m_section_name = m_storage.c_str (); + } + else + m_section_name = name; + } + + /* Return the computed section name. The result is valid as long as + this thread_section_name object is live. */ + const char *c_str () const + { return m_section_name; } + + /* Disable copy. */ + thread_section_name (const thread_section_name &) = delete; + void operator= (const thread_section_name &) = delete; + +private: + /* Either a pointer into M_STORAGE, or a pointer to the name passed + as parameter to the constructor. */ + const char *m_section_name; + /* If we need to build a new section name, this is where we store + it. */ + std::string m_storage; +}; + /* NOTE: cagney/2004-04-05: Replaced by "regset.h" and regset_from_core_section(). */ extern void deprecated_add_core_fns (struct core_fns *cf); diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 63b54f6..0059b913 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,52 @@ +2017-08-09 Yao Qi <yao.qi@linaro.org> + + * configure.srv (srv_i386_regobj): Remove i386-avx.o, + i386-avx-avx512.o, i386-avx-mpx-avx512-pku.o, i386-mpx.o, + i386-avx-mpx.o and i386-mmx.o. + (srv_amd64_regobj): Remove amd64-avx.o, amd64-avx-avx512.o, + amd64-avx-mpx-avx512-pku.o, amd64-mpx.o and amd64-avx-mpx.o. + (srv_i386_xmlfiles): Remove i386/i386-avx.xml, + i386/i386-avx-avx512.xml, i386/i386-avx-mpx-avx512-pku.xml, + i386/i386-mpx.xml, i386/i386-avx-mpx.xml and i386/i386-mmx.xml. + (srv_amd64_xmlfile):i386/amd64-avx.xml, i386/amd64-avx-avx512.xml, + i386/amd64-avx-mpx-avx512-pku.xml, i386/amd64-mpx.xml, + i386/amd64-avx-mpx.xml. + +2017-08-09 Yao Qi <yao.qi@linaro.org> + + * configure.srv (srv_amd64_regobj): Remove x32.o, x32-avx.o + and x32-avx-avx512.o. + (srv_amd64_xmlfiles): Remove i386/x32.xml, i386/x32-avx.xml + i386/x32-avx-avx512.xml. + +2017-07-26 Simon Marchi <simon.marchi@ericsson.com> + + * tracepoint.h (enum class fast_tpoint_collect_result): New + enumeration. + (fast_tracepoint_collecting): Change return type to + fast_tpoint_collect_result. + * tracepoint.c (fast_tracepoint_collecting): Likewise. + * linux-low.h: Include tracepoint.h. + (struct lwp_info) <collecting_fast_tracepoint>: Change type to + fast_tpoint_collect_result. + * linux-low.c (handle_tracepoints): Adjust. + (linux_fast_tracepoint_collecting): Change return type to + fast_tpoint_collect_result. + (maybe_move_out_of_jump_pad, linux_wait_for_event_filtered, + linux_wait_1, stuck_in_jump_pad_callback, + lwp_signal_can_be_delivered, linux_resume_one_lwp_throw, + proceed_one_lwp): Adjust to type change. + +2017-07-10 Yao Qi <yao.qi@linaro.org> + + * linux-x86-low.c (x86_linux_read_description): Re-indent the code. + +2017-06-29 Yao Qi <yao.qi@linaro.org> + + * tdesc.h (struct target_desc) [IN_PROCESS_AGENT] <expedite_regs>: + Remove. + [IN_PROCESS_AGENT] <xmltarget>: Likewise. + 2017-06-20 Simon Marchi <simon.marchi@ericsson.com> * Makefile.in (IPA_OBJS): Sort and format one item per line. diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv index 43f90c9..789a16b 100644 --- a/gdb/gdbserver/configure.srv +++ b/gdb/gdbserver/configure.srv @@ -24,19 +24,20 @@ # Default hostio_last_error implementation srv_hostio_err_objs="hostio-errno.o" -srv_i386_regobj="i386.o i386-avx.o i386-avx-avx512.o i386-avx-mpx-avx512-pku.o i386-mpx.o i386-avx-mpx.o i386-mmx.o" +srv_i386_regobj="i386.o" srv_i386_linux_regobj="i386-linux.o i386-avx-linux.o i386-avx-avx512-linux.o i386-avx-mpx-avx512-pku-linux.o i386-mpx-linux.o i386-avx-mpx-linux.o i386-mmx-linux.o" -srv_amd64_regobj="amd64.o amd64-avx.o amd64-avx-avx512.o amd64-avx-mpx-avx512-pku.o amd64-mpx.o amd64-avx-mpx.o x32.o x32-avx.o x32-avx-avx512.o" +srv_amd64_regobj="amd64.o" srv_amd64_linux_regobj="amd64-linux.o amd64-avx-linux.o amd64-avx-avx512-linux.o amd64-avx-mpx-avx512-pku-linux.o amd64-mpx-linux.o amd64-avx-mpx-linux.o x32-linux.o x32-avx-linux.o x32-avx-avx512-linux.o" ipa_i386_linux_regobj="i386-linux-ipa.o i386-avx-linux-ipa.o i386-avx-mpx-linux-ipa.o i386-avx-avx512-linux-ipa.o i386-avx-mpx-avx512-pku-linux-ipa.o i386-mpx-linux-ipa.o i386-mmx-linux-ipa.o" ipa_amd64_linux_regobj="amd64-linux-ipa.o amd64-avx-linux-ipa.o amd64-avx-mpx-linux-ipa.o amd64-avx-avx512-linux-ipa.o amd64-avx-mpx-avx512-pku-linux-ipa.o amd64-mpx-linux-ipa.o" +ipa_x32_linux_regobj="x32-linux-ipa.o x32-avx-linux-ipa.o x32-avx-avx512-linux-ipa.o" ipa_ppc_linux_regobj="powerpc-32l-ipa.o powerpc-altivec32l-ipa.o powerpc-cell32l-ipa.o powerpc-vsx32l-ipa.o powerpc-isa205-32l-ipa.o powerpc-isa205-altivec32l-ipa.o powerpc-isa205-vsx32l-ipa.o powerpc-e500l-ipa.o powerpc-64l-ipa.o powerpc-altivec64l-ipa.o powerpc-cell64l-ipa.o powerpc-vsx64l-ipa.o powerpc-isa205-64l-ipa.o powerpc-isa205-altivec64l-ipa.o powerpc-isa205-vsx64l-ipa.o" srv_i386_32bit_xmlfiles="i386/32bit-core.xml i386/32bit-sse.xml i386/32bit-avx.xml i386/32bit-avx512.xml i386/32bit-mpx.xml i386/32bit-pkeys.xml" srv_i386_64bit_xmlfiles="i386/64bit-core.xml i386/64bit-segments.xml i386/64bit-sse.xml i386/64bit-avx.xml i386/64bit-avx512.xml i386/x32-core.xml i386/64bit-mpx.xml i386/64bit-pkeys.xml" -srv_i386_xmlfiles="i386/i386.xml i386/i386-avx.xml i386/i386-avx-avx512.xml i386/i386-avx-mpx-avx512-pku.xml i386/i386-mpx.xml i386/i386-avx-mpx.xml i386/i386-mmx.xml $srv_i386_32bit_xmlfiles" -srv_amd64_xmlfiles="i386/amd64.xml i386/amd64-avx.xml i386/amd64-avx-avx512.xml i386/amd64-avx-mpx-avx512-pku.xml i386/x32.xml i386/x32-avx.xml i386/x32-avx-avx512.xml i386/amd64-mpx.xml i386/amd64-avx-mpx.xml $srv_i386_64bit_xmlfiles" +srv_i386_xmlfiles="i386/i386.xml $srv_i386_32bit_xmlfiles" +srv_amd64_xmlfiles="i386/amd64.xml $srv_i386_64bit_xmlfiles" srv_i386_linux_xmlfiles="i386/i386-linux.xml i386/i386-avx-linux.xml i386/i386-avx-avx512-linux.xml i386/i386-avx-mpx-avx512-pku-linux.xml i386/i386-mmx-linux.xml i386/32bit-linux.xml i386/i386-mpx-linux.xml i386/i386-avx-mpx-linux.xml $srv_i386_32bit_xmlfiles" srv_amd64_linux_xmlfiles="i386/amd64-linux.xml i386/amd64-avx-linux.xml i386/amd64-avx-avx512.xml i386/amd64-avx-mpx-avx512-pku-linux.xml i386/64bit-linux.xml i386/amd64-mpx-linux.xml i386/amd64-avx-mpx-linux.xml i386/x32-linux.xml i386/x32-avx-linux.xml i386/x32-avx-avx512-linux.xml $srv_i386_64bit_xmlfiles" diff --git a/gdb/gdbserver/linux-amd64-ipa.c b/gdb/gdbserver/linux-amd64-ipa.c index 67f36c2..683339b 100644 --- a/gdb/gdbserver/linux-amd64-ipa.c +++ b/gdb/gdbserver/linux-amd64-ipa.c @@ -181,8 +181,8 @@ get_ipa_tdesc (int idx) return tdesc_x32_linux; case X86_TDESC_AVX: return tdesc_x32_avx_linux; - case X86_TDESC_AVX512: - return tdesc_x32_avx512_linux; + case X86_TDESC_AVX_AVX512: + return tdesc_x32_avx_avx512_linux; default: break; } @@ -279,7 +279,7 @@ initialize_low_tracepoint (void) #if defined __ILP32__ init_registers_x32_linux (); init_registers_x32_avx_linux (); - init_registers_x32_avx512_linux (); + init_registers_x32_avx_avx512_linux (); #else init_registers_amd64_linux (); init_registers_amd64_avx_linux (); diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 3d7cfe3..fd46d85 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -2082,7 +2082,9 @@ handle_tracepoints (struct lwp_info *lwp) lwp_suspended_decr (lwp); gdb_assert (lwp->suspended == 0); - gdb_assert (!stabilizing_threads || lwp->collecting_fast_tracepoint); + gdb_assert (!stabilizing_threads + || (lwp->collecting_fast_tracepoint + != fast_tpoint_collect_result::not_collecting)); if (tpoint_related_event) { @@ -2094,10 +2096,10 @@ handle_tracepoints (struct lwp_info *lwp) return 0; } -/* Convenience wrapper. Returns true if LWP is presently collecting a - fast tracepoint. */ +/* Convenience wrapper. Returns information about LWP's fast tracepoint + collection status. */ -static int +static fast_tpoint_collect_result linux_fast_tracepoint_collecting (struct lwp_info *lwp, struct fast_tpoint_collect_status *status) { @@ -2105,14 +2107,14 @@ linux_fast_tracepoint_collecting (struct lwp_info *lwp, struct thread_info *thread = get_lwp_thread (lwp); if (the_low_target.get_thread_area == NULL) - return 0; + return fast_tpoint_collect_result::not_collecting; /* Get the thread area address. This is used to recognize which thread is which when tracing with the in-process agent library. We don't read anything from the address, and treat it as opaque; it's the address itself that we assume is unique per-thread. */ if ((*the_low_target.get_thread_area) (lwpid_of (thread), &thread_area) == -1) - return 0; + return fast_tpoint_collect_result::not_collecting; return fast_tracepoint_collecting (thread_area, lwp->stop_pc, status); } @@ -2136,14 +2138,14 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat) && agent_loaded_p ()) { struct fast_tpoint_collect_status status; - int r; if (debug_threads) debug_printf ("Checking whether LWP %ld needs to move out of the " "jump pad.\n", lwpid_of (current_thread)); - r = linux_fast_tracepoint_collecting (lwp, &status); + fast_tpoint_collect_result r + = linux_fast_tracepoint_collecting (lwp, &status); if (wstat == NULL || (WSTOPSIG (*wstat) != SIGILL @@ -2153,9 +2155,10 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat) { lwp->collecting_fast_tracepoint = r; - if (r != 0) + if (r != fast_tpoint_collect_result::not_collecting) { - if (r == 1 && lwp->exit_jump_pad_bkpt == NULL) + if (r == fast_tpoint_collect_result::before_insn + && lwp->exit_jump_pad_bkpt == NULL) { /* Haven't executed the original instruction yet. Set breakpoint there, and wait till it's hit, @@ -2181,9 +2184,10 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat) reporting to GDB. Otherwise, it's an IPA lib bug: just report the signal to GDB, and pray for the best. */ - lwp->collecting_fast_tracepoint = 0; + lwp->collecting_fast_tracepoint + = fast_tpoint_collect_result::not_collecting; - if (r != 0 + if (r != fast_tpoint_collect_result::not_collecting && (status.adjusted_insn_addr <= lwp->stop_pc && lwp->stop_pc < status.adjusted_insn_addr_end)) { @@ -2715,7 +2719,8 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid, if (stopping_threads == NOT_STOPPING_THREADS && requested_child->status_pending_p - && requested_child->collecting_fast_tracepoint) + && (requested_child->collecting_fast_tracepoint + != fast_tpoint_collect_result::not_collecting)) { enqueue_one_deferred_signal (requested_child, &requested_child->status_pending); @@ -3467,20 +3472,22 @@ linux_wait_1 (ptid_t ptid, } } - if (event_child->collecting_fast_tracepoint) + if (event_child->collecting_fast_tracepoint + != fast_tpoint_collect_result::not_collecting) { if (debug_threads) debug_printf ("LWP %ld was trying to move out of the jump pad (%d). " "Check if we're already there.\n", lwpid_of (current_thread), - event_child->collecting_fast_tracepoint); + (int) event_child->collecting_fast_tracepoint); trace_event = 1; event_child->collecting_fast_tracepoint = linux_fast_tracepoint_collecting (event_child, NULL); - if (event_child->collecting_fast_tracepoint != 1) + if (event_child->collecting_fast_tracepoint + != fast_tpoint_collect_result::before_insn) { /* No longer need this breakpoint. */ if (event_child->exit_jump_pad_bkpt != NULL) @@ -3507,7 +3514,8 @@ linux_wait_1 (ptid_t ptid, } } - if (event_child->collecting_fast_tracepoint == 0) + if (event_child->collecting_fast_tracepoint + == fast_tpoint_collect_result::not_collecting) { if (debug_threads) debug_printf ("fast tracepoint finished " @@ -4192,7 +4200,8 @@ stuck_in_jump_pad_callback (struct inferior_list_entry *entry, void *data) && (gdb_breakpoint_here (lwp->stop_pc) || lwp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT || thread->last_resume_kind == resume_step) - && linux_fast_tracepoint_collecting (lwp, NULL)); + && (linux_fast_tracepoint_collecting (lwp, NULL) + != fast_tpoint_collect_result::not_collecting)); } static void @@ -4369,7 +4378,8 @@ single_step (struct lwp_info* lwp) static int lwp_signal_can_be_delivered (struct lwp_info *lwp) { - return !lwp->collecting_fast_tracepoint; + return (lwp->collecting_fast_tracepoint + == fast_tpoint_collect_result::not_collecting); } /* Resume execution of LWP. If STEP is nonzero, single-step it. If @@ -4381,7 +4391,6 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp, { struct thread_info *thread = get_lwp_thread (lwp); struct thread_info *saved_thread; - int fast_tp_collecting; int ptrace_request; struct process_info *proc = get_thread_process (thread); @@ -4397,9 +4406,12 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp, gdb_assert (lwp->waitstatus.kind == TARGET_WAITKIND_IGNORE); - fast_tp_collecting = lwp->collecting_fast_tracepoint; + fast_tpoint_collect_result fast_tp_collecting + = lwp->collecting_fast_tracepoint; - gdb_assert (!stabilizing_threads || fast_tp_collecting); + gdb_assert (!stabilizing_threads + || (fast_tp_collecting + != fast_tpoint_collect_result::not_collecting)); /* Cancel actions that rely on GDB not changing the PC (e.g., the user used the "jump" command, or "set $pc = foo"). */ @@ -4455,7 +4467,7 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp, if (can_hardware_single_step ()) { - if (fast_tp_collecting == 0) + if (fast_tp_collecting == fast_tpoint_collect_result::not_collecting) { if (step == 0) warning ("BAD - reinserting but not stepping."); @@ -4468,14 +4480,14 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp, step = maybe_hw_step (thread); } - if (fast_tp_collecting == 1) + if (fast_tp_collecting == fast_tpoint_collect_result::before_insn) { if (debug_threads) debug_printf ("lwp %ld wants to get out of fast tracepoint jump pad" " (exit-jump-pad-bkpt)\n", lwpid_of (thread)); } - else if (fast_tp_collecting == 2) + else if (fast_tp_collecting == fast_tpoint_collect_result::at_insn) { if (debug_threads) debug_printf ("lwp %ld wants to get out of fast tracepoint jump pad" @@ -5294,7 +5306,8 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except) if (thread->last_resume_kind == resume_stop && lwp->pending_signals_to_report == NULL - && lwp->collecting_fast_tracepoint == 0) + && (lwp->collecting_fast_tracepoint + == fast_tpoint_collect_result::not_collecting)) { /* We haven't reported this LWP as stopped yet (otherwise, the last_status.kind check above would catch it, and we wouldn't diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h index 6328da0..2bf7e7c 100644 --- a/gdb/gdbserver/linux-low.h +++ b/gdb/gdbserver/linux-low.h @@ -26,6 +26,7 @@ /* Included for ptrace type definitions. */ #include "nat/linux-ptrace.h" #include "target/waitstatus.h" /* For enum target_stop_reason. */ +#include "tracepoint.h" #define PTRACE_XFER_TYPE long @@ -353,12 +354,11 @@ struct lwp_info and then processed and cleared in linux_resume_one_lwp. */ struct thread_resume *resume; - /* True if it is known that this lwp is presently collecting a fast - tracepoint (it is in the jump pad or in some code that will - return to the jump pad. Normally, we won't care about this, but - we will if a signal arrives to this lwp while it is - collecting. */ - int collecting_fast_tracepoint; + /* Information bout this lwp's fast tracepoint collection status (is it + currently stopped in the jump pad, and if so, before or at/after the + relocated instruction). Normally, we won't care about this, but we will + if a signal arrives to this lwp while it is collecting. */ + fast_tpoint_collect_result collecting_fast_tracepoint; /* If this is non-zero, it points to a chain of signals which need to be reported to GDB. These were deferred because the thread diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c index b39026c..12c7a1b 100644 --- a/gdb/gdbserver/linux-x86-low.c +++ b/gdb/gdbserver/linux-x86-low.c @@ -809,7 +809,7 @@ x86_linux_read_description (void) /* Check the native XCR0 only if PTRACE_GETREGSET is available. */ xcr0_features = (have_ptrace_getregset - && (xcr0 & X86_XSTATE_ALL_MASK)); + && (xcr0 & X86_XSTATE_ALL_MASK)); if (xcr0_features) x86_xcr0 = xcr0; diff --git a/gdb/gdbserver/tdesc.h b/gdb/gdbserver/tdesc.h index ada879d..0341278 100644 --- a/gdb/gdbserver/tdesc.h +++ b/gdb/gdbserver/tdesc.h @@ -36,6 +36,7 @@ struct target_desc /* The register cache size, in bytes. */ int registers_size; +#ifndef IN_PROCESS_AGENT /* An array of register names. These are the "expedite" registers: registers whose values are sent along with stop replies. */ const char **expedite_regs; @@ -45,6 +46,7 @@ struct target_desc verbatim XML code (prefixed with a '@') or else the name of the actual XML file to be used in place of "target.xml". */ const char *xmltarget; +#endif }; /* Copy target description SRC to DEST. */ diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c index d4fe76a..68ce10f 100644 --- a/gdb/gdbserver/tracepoint.c +++ b/gdb/gdbserver/tracepoint.c @@ -5581,7 +5581,7 @@ force_unlock_trace_buffer (void) case, if we want to move the thread out of the jump pad, we need to single-step it until this function returns 0. */ -int +fast_tpoint_collect_result fast_tracepoint_collecting (CORE_ADDR thread_area, CORE_ADDR stop_pc, struct fast_tpoint_collect_status *status) @@ -5656,7 +5656,7 @@ fast_tracepoint_collecting (CORE_ADDR thread_area, if (tpoint == NULL) { warning ("in jump pad, but no matching tpoint?"); - return 0; + return fast_tpoint_collect_result::not_collecting; } else { @@ -5684,7 +5684,7 @@ fast_tracepoint_collecting (CORE_ADDR thread_area, if (tpoint == NULL) { warning ("in trampoline, but no matching tpoint?"); - return 0; + return fast_tpoint_collect_result::not_collecting; } else { @@ -5712,14 +5712,14 @@ fast_tracepoint_collecting (CORE_ADDR thread_area, { trace_debug ("fast_tracepoint_collecting:" " failed reading 'collecting' in the inferior"); - return 0; + return fast_tpoint_collect_result::not_collecting; } if (!ipa_collecting) { trace_debug ("fast_tracepoint_collecting: not collecting" " (and nobody is)."); - return 0; + return fast_tpoint_collect_result::not_collecting; } /* Some thread is collecting. Check which. */ @@ -5732,7 +5732,7 @@ fast_tracepoint_collecting (CORE_ADDR thread_area, { trace_debug ("fast_tracepoint_collecting: not collecting " "(another thread is)"); - return 0; + return fast_tpoint_collect_result::not_collecting; } tpoint @@ -5742,7 +5742,7 @@ fast_tracepoint_collecting (CORE_ADDR thread_area, warning ("fast_tracepoint_collecting: collecting, " "but tpoint %s not found?", paddress ((CORE_ADDR) ipa_collecting_obj.tpoint)); - return 0; + return fast_tpoint_collect_result::not_collecting; } /* The thread is within `gdb_collect', skip over the rest of @@ -5769,7 +5769,7 @@ fast_tracepoint_collecting (CORE_ADDR thread_area, fast_tracepoint_collecting, returning continue-until-break at %s", paddress (tpoint->adjusted_insn_addr)); - return 1; /* continue */ + return fast_tpoint_collect_result::before_insn; /* continue */ } else { @@ -5780,7 +5780,7 @@ fast_tracepoint_collecting, returning continue-until-break at %s", paddress (tpoint->adjusted_insn_addr), paddress (tpoint->adjusted_insn_addr_end)); - return 2; /* single-step */ + return fast_tpoint_collect_result::at_insn; /* single-step */ } } diff --git a/gdb/gdbserver/tracepoint.h b/gdb/gdbserver/tracepoint.h index 799a16c..31103a3 100644 --- a/gdb/gdbserver/tracepoint.h +++ b/gdb/gdbserver/tracepoint.h @@ -115,9 +115,25 @@ struct fast_tpoint_collect_status CORE_ADDR adjusted_insn_addr_end; }; -int fast_tracepoint_collecting (CORE_ADDR thread_area, - CORE_ADDR stop_pc, - struct fast_tpoint_collect_status *status); +/* The possible states a thread can be in, related to the collection of fast + tracepoint. */ + +enum class fast_tpoint_collect_result +{ + /* Not collecting a fast tracepoint. */ + not_collecting, + + /* In the jump pad, but before the relocated instruction. */ + before_insn, + + /* In the jump pad, but at (or after) the relocated instruction. */ + at_insn, +}; + +fast_tpoint_collect_result fast_tracepoint_collecting + (CORE_ADDR thread_area, CORE_ADDR stop_pc, + struct fast_tpoint_collect_status *status); + void force_unlock_trace_buffer (void); int handle_tracepoint_bkpts (struct thread_info *tinfo, CORE_ADDR stop_pc); diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index bcf3dee..5751861 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -4417,10 +4417,6 @@ recursive_dump_type (struct type *type, int spaces) { puts_filtered (" TYPE_TARGET_STUB"); } - if (TYPE_STATIC (type)) - { - puts_filtered (" TYPE_STATIC"); - } if (TYPE_PROTOTYPED (type)) { puts_filtered (" TYPE_PROTOTYPED"); diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index a38c2dc..60b6770 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -222,13 +222,6 @@ enum type_instance_flag_value #define TYPE_TARGET_STUB(t) (TYPE_MAIN_TYPE (t)->flag_target_stub) -/* * Static type. If this is set, the corresponding type had - a static modifier. - Note: This may be unnecessary, since static data members - are indicated by other means (bitpos == -1). */ - -#define TYPE_STATIC(t) (TYPE_MAIN_TYPE (t)->flag_static) - /* * This is a function type which appears to have a prototype. We need this for function calls in order to tell us if it's necessary to coerce the args, or to just do the standard conversions. This @@ -855,14 +848,9 @@ struct fn_field unsigned int is_const:1; unsigned int is_volatile:1; + unsigned int is_public:1; unsigned int is_private:1; unsigned int is_protected:1; - unsigned int is_public:1; - unsigned int is_abstract:1; - unsigned int is_static:1; - unsigned int is_final:1; - unsigned int is_synchronized:1; - unsigned int is_native:1; unsigned int is_artificial:1; /* * A stub method only has some fields valid (but they are enough @@ -881,11 +869,12 @@ struct fn_field /* * True if this function is aliased to an existing fn_field, false otherwise. These functions should be skipped during symbol lookups or type printing. */ + unsigned int is_alias : 1; /* * Unused. */ - unsigned int dummy:1; + unsigned int dummy:6; /* * Index into that baseclass's virtual function table, minus 2; else if static: VOFFSET_STATIC; else: 0. */ @@ -1474,12 +1463,7 @@ extern void set_type_vptr_basetype (struct type *, struct type *); #define TYPE_FN_FIELD_PRIVATE(thisfn, n) ((thisfn)[n].is_private) #define TYPE_FN_FIELD_PROTECTED(thisfn, n) ((thisfn)[n].is_protected) #define TYPE_FN_FIELD_PUBLIC(thisfn, n) ((thisfn)[n].is_public) -#define TYPE_FN_FIELD_STATIC(thisfn, n) ((thisfn)[n].is_static) -#define TYPE_FN_FIELD_FINAL(thisfn, n) ((thisfn)[n].is_final) -#define TYPE_FN_FIELD_SYNCHRONIZED(thisfn, n) ((thisfn)[n].is_synchronized) -#define TYPE_FN_FIELD_NATIVE(thisfn, n) ((thisfn)[n].is_native) #define TYPE_FN_FIELD_ARTIFICIAL(thisfn, n) ((thisfn)[n].is_artificial) -#define TYPE_FN_FIELD_ABSTRACT(thisfn, n) ((thisfn)[n].is_abstract) #define TYPE_FN_FIELD_STUB(thisfn, n) ((thisfn)[n].is_stub) #define TYPE_FN_FIELD_CONSTRUCTOR(thisfn, n) ((thisfn)[n].is_constructor) #define TYPE_FN_FIELD_DESTRUCTOR(thisfn, n) ((thisfn)[n].is_destructor) diff --git a/gdb/gnu-v2-abi.c b/gdb/gnu-v2-abi.c index dd6820b..8e04dd1 100644 --- a/gdb/gnu-v2-abi.c +++ b/gdb/gnu-v2-abi.c @@ -68,7 +68,7 @@ gnuv2_is_vtable_name (const char *name) static int gnuv2_is_operator_name (const char *name) { - return startswith (name, "operator"); + return startswith (name, CP_OPERATOR_STR); } diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c index 83ad03e..9801d08 100644 --- a/gdb/gnu-v3-abi.c +++ b/gdb/gnu-v3-abi.c @@ -46,7 +46,7 @@ gnuv3_is_vtable_name (const char *name) static int gnuv3_is_operator_name (const char *name) { - return startswith (name, "operator"); + return startswith (name, CP_OPERATOR_STR); } diff --git a/gdb/gnulib/aclocal.m4 b/gdb/gnulib/aclocal.m4 index cd0dd5d..a4ce6a6 100644 --- a/gdb/gnulib/aclocal.m4 +++ b/gdb/gnulib/aclocal.m4 @@ -1023,6 +1023,7 @@ m4_include([import/m4/dirfd.m4]) m4_include([import/m4/dirname.m4]) m4_include([import/m4/double-slash-root.m4]) m4_include([import/m4/eealloc.m4]) +m4_include([import/m4/environ.m4]) m4_include([import/m4/errno_h.m4]) m4_include([import/m4/exponentd.m4]) m4_include([import/m4/exponentl.m4]) @@ -1071,6 +1072,7 @@ m4_include([import/m4/rawmemchr.m4]) m4_include([import/m4/readlink.m4]) m4_include([import/m4/rename.m4]) m4_include([import/m4/rmdir.m4]) +m4_include([import/m4/setenv.m4]) m4_include([import/m4/signal_h.m4]) m4_include([import/m4/ssize_t.m4]) m4_include([import/m4/stat.m4]) diff --git a/gdb/gnulib/config.in b/gdb/gnulib/config.in index 057b12d..6061520 100644 --- a/gdb/gnulib/config.in +++ b/gdb/gnulib/config.in @@ -95,6 +95,9 @@ /* Define to 1 when the gnulib module dirfd should be tested. */ #undef GNULIB_TEST_DIRFD +/* Define to 1 when the gnulib module environ should be tested. */ +#undef GNULIB_TEST_ENVIRON + /* Define to 1 when the gnulib module frexp should be tested. */ #undef GNULIB_TEST_FREXP @@ -140,6 +143,9 @@ /* Define to 1 when the gnulib module rmdir should be tested. */ #undef GNULIB_TEST_RMDIR +/* Define to 1 when the gnulib module setenv should be tested. */ +#undef GNULIB_TEST_SETENV + /* Define to 1 when the gnulib module stat should be tested. */ #undef GNULIB_TEST_STAT @@ -152,6 +158,9 @@ /* Define to 1 when the gnulib module strtok_r should be tested. */ #undef GNULIB_TEST_STRTOK_R +/* Define to 1 when the gnulib module unsetenv should be tested. */ +#undef GNULIB_TEST_UNSETENV + /* Define to 1 if you have 'alloca' after including <alloca.h>, a header that may be supplied by this distribution. */ #undef HAVE_ALLOCA @@ -201,6 +210,10 @@ */ #undef HAVE_DECL_MEMMEM +/* Define to 1 if you have the declaration of `setenv', and to 0 if you don't. + */ +#undef HAVE_DECL_SETENV + /* Define to 1 if you have the declaration of `strtok_r', and to 0 if you don't. */ #undef HAVE_DECL_STRTOK_R @@ -209,12 +222,19 @@ don't. */ #undef HAVE_DECL_TOWLOWER +/* Define to 1 if you have the declaration of `unsetenv', and to 0 if you + don't. */ +#undef HAVE_DECL_UNSETENV + /* Define to 1 if you have the <dirent.h> header file. */ #undef HAVE_DIRENT_H /* Define to 1 if you have the `dirfd' function. */ #undef HAVE_DIRFD +/* Define if you have the declaration of environ. */ +#undef HAVE_ENVIRON_DECL + /* Define to 1 if you have the <features.h> header file. */ #undef HAVE_FEATURES_H @@ -1126,6 +1146,12 @@ /* Define to 1 if 'long double' and 'double' have the same representation. */ #undef HAVE_SAME_LONG_DOUBLE_AS_DOUBLE +/* Define to 1 if you have the <search.h> header file. */ +#undef HAVE_SEARCH_H + +/* Define to 1 if you have the `setenv' function. */ +#undef HAVE_SETENV + /* Define to 1 if 'sig_atomic_t' is a signed integer type. */ #undef HAVE_SIGNED_SIG_ATOMIC_T @@ -1189,9 +1215,15 @@ /* Define to 1 if you have the `towlower' function. */ #undef HAVE_TOWLOWER +/* Define to 1 if you have the `tsearch' function. */ +#undef HAVE_TSEARCH + /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H +/* Define to 1 if you have the `unsetenv' function. */ +#undef HAVE_UNSETENV + /* Define to 1 if the system has the type 'unsigned long long int'. */ #undef HAVE_UNSIGNED_LONG_LONG_INT @@ -1407,6 +1439,9 @@ #endif +/* Define to 1 if unsetenv returns void instead of int. */ +#undef VOID_UNSETENV + /* Define to l, ll, u, ul, ull, etc., as suitable for constants of type 'wchar_t'. */ #undef WCHAR_T_SUFFIX diff --git a/gdb/gnulib/configure b/gdb/gnulib/configure index d214164..2a0dfc2 100644 --- a/gdb/gnulib/configure +++ b/gdb/gnulib/configure @@ -3307,6 +3307,7 @@ as_fn_append ac_func_list " readlink" as_fn_append ac_func_list " realpath" as_fn_append ac_header_list " sys/param.h" as_fn_append ac_header_list " dirent.h" +as_fn_append ac_header_list " unistd.h" as_fn_append ac_func_list " btowc" as_fn_append ac_func_list " isblank" as_fn_append ac_func_list " iswctype" @@ -3324,7 +3325,6 @@ as_fn_append ac_header_list " limits.h" as_fn_append ac_header_list " wchar.h" as_fn_append ac_header_list " stdint.h" as_fn_append ac_header_list " inttypes.h" -as_fn_append ac_header_list " unistd.h" as_fn_append ac_func_list " symlink" as_fn_append ac_func_list " lstat" as_fn_append ac_header_list " math.h" @@ -3333,6 +3333,7 @@ as_fn_append ac_func_list " mbrtowc" as_fn_append ac_header_list " sys/mman.h" as_fn_append ac_func_list " mprotect" as_fn_append ac_func_list " link" +as_fn_append ac_func_list " setenv" as_fn_append ac_header_list " sys/stat.h" as_fn_append ac_header_list " features.h" as_fn_append ac_func_list " iswcntrl" @@ -5311,6 +5312,7 @@ fi # Code from module dirname-lgpl: # Code from module dosname: # Code from module double-slash-root: + # Code from module environ: # Code from module errno: # Code from module extensions: # Code from module extern-inline: @@ -5352,6 +5354,7 @@ fi # Code from module rename: # Code from module rmdir: # Code from module same-inode: + # Code from module setenv: # Code from module signal-h: # Code from module snippet/_Noreturn: # Code from module snippet/arg-nonnull: @@ -5376,6 +5379,7 @@ fi # Code from module sys_types: # Code from module time: # Code from module unistd: + # Code from module unsetenv: # Code from module update-copyright: # Code from module verify: # Code from module wchar: @@ -6826,6 +6830,59 @@ $as_echo "$gl_cv_pragma_columns" >&6; } + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if environ is properly declared" >&5 +$as_echo_n "checking if environ is properly declared... " >&6; } + if test "${gt_cv_var_environ_declaration+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if HAVE_UNISTD_H + #include <unistd.h> + #endif + /* mingw, BeOS, Haiku declare environ in <stdlib.h>, not in <unistd.h>. */ + #include <stdlib.h> + + extern struct { int foo; } environ; +int +main () +{ +environ.foo = 1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gt_cv_var_environ_declaration=no +else + gt_cv_var_environ_declaration=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_var_environ_declaration" >&5 +$as_echo "$gt_cv_var_environ_declaration" >&6; } + if test $gt_cv_var_environ_declaration = yes; then + +$as_echo "#define HAVE_ENVIRON_DECL 1" >>confdefs.h + + fi + + + if test $gt_cv_var_environ_declaration != yes; then + HAVE_DECL_ENVIRON=0 + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for complete errno.h" >&5 $as_echo_n "checking for complete errno.h... " >&6; } if test "${gl_cv_header_errno_h_complete+set}" = set; then : @@ -9919,8 +9976,6 @@ $as_echo "#define HAVE_LANGINFO_CODESET 1" >>confdefs.h - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fcntl.h" >&5 $as_echo_n "checking for working fcntl.h... " >&6; } if test "${gl_cv_header_working_fcntl_h+set}" = set; then : @@ -11411,6 +11466,55 @@ $as_echo "$gl_cv_func_memmem_works_always" >&6; } +ac_fn_c_check_decl "$LINENO" "setenv" "ac_cv_have_decl_setenv" "$ac_includes_default" +if test "x$ac_cv_have_decl_setenv" = x""yes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SETENV $ac_have_decl +_ACEOF + + + + + + + if test $ac_cv_have_decl_setenv = no; then + HAVE_DECL_SETENV=0 + fi + + + + + + for ac_header in search.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "search.h" "ac_cv_header_search_h" "$ac_includes_default" +if test "x$ac_cv_header_search_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SEARCH_H 1 +_ACEOF + +fi + +done + + for ac_func in tsearch +do : + ac_fn_c_check_func "$LINENO" "tsearch" "ac_cv_func_tsearch" +if test "x$ac_cv_func_tsearch" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_TSEARCH 1 +_ACEOF + +fi +done + + + GNULIB_PTHREAD_SIGMASK=0; GNULIB_RAISE=0; @@ -12246,6 +12350,17 @@ $as_echo "$gl_cv_next_time_h" >&6; } +ac_fn_c_check_decl "$LINENO" "unsetenv" "ac_cv_have_decl_unsetenv" "$ac_includes_default" +if test "x$ac_cv_have_decl_unsetenv" = x""yes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_UNSETENV $ac_have_decl +_ACEOF + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether <wchar.h> uses 'inline' correctly" >&5 $as_echo_n "checking whether <wchar.h> uses 'inline' correctly... " >&6; } @@ -12917,6 +13032,22 @@ $as_echo "#define DOUBLE_SLASH_IS_DISTINCT_ROOT 1" >>confdefs.h + + + + GNULIB_ENVIRON=1 + + + + + +$as_echo "#define GNULIB_TEST_ENVIRON 1" >>confdefs.h + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for flexible array member" >&5 $as_echo_n "checking for flexible array member... " >&6; } if test "${ac_cv_c_flexmember+set}" = set; then : @@ -17099,6 +17230,102 @@ $as_echo "#define GNULIB_TEST_RMDIR 1" >>confdefs.h + if test $ac_cv_func_setenv = no; then + HAVE_SETENV=0 + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether setenv validates arguments" >&5 +$as_echo_n "checking whether setenv validates arguments... " >&6; } +if test "${gl_cv_func_setenv_works+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_setenv_works="guessing yes" ;; + # If we don't know, assume the worst. + *) gl_cv_func_setenv_works="guessing no" ;; + esac + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <stdlib.h> + #include <errno.h> + #include <string.h> + +int +main () +{ + + int result = 0; + { + if (setenv ("", "", 0) != -1) + result |= 1; + else if (errno != EINVAL) + result |= 2; + } + { + if (setenv ("a", "=", 1) != 0) + result |= 4; + else if (strcmp (getenv ("a"), "=") != 0) + result |= 8; + } + return result; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + gl_cv_func_setenv_works=yes +else + gl_cv_func_setenv_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_setenv_works" >&5 +$as_echo "$gl_cv_func_setenv_works" >&6; } + case "$gl_cv_func_setenv_works" in + *yes) ;; + *) + REPLACE_SETENV=1 + ;; + esac + fi + + if test $HAVE_SETENV = 0 || test $REPLACE_SETENV = 1; then + + + + + + + + + gl_LIBOBJS="$gl_LIBOBJS setenv.$ac_objext" + + fi + + + + + + GNULIB_SETENV=1 + + + + + +$as_echo "#define GNULIB_TEST_SETENV 1" >>confdefs.h + + + + + @@ -18642,6 +18869,164 @@ fi + if test $ac_cv_have_decl_unsetenv = no; then + HAVE_DECL_UNSETENV=0 + fi + for ac_func in unsetenv +do : + ac_fn_c_check_func "$LINENO" "unsetenv" "ac_cv_func_unsetenv" +if test "x$ac_cv_func_unsetenv" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_UNSETENV 1 +_ACEOF + +fi +done + + if test $ac_cv_func_unsetenv = no; then + HAVE_UNSETENV=0 + else + HAVE_UNSETENV=1 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsetenv() return type" >&5 +$as_echo_n "checking for unsetenv() return type... " >&6; } +if test "${gt_cv_func_unsetenv_ret+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#undef _BSD +#define _BSD 1 /* unhide unsetenv declaration in OSF/1 5.1 <stdlib.h> */ +#include <stdlib.h> +extern +#ifdef __cplusplus +"C" +#endif +int unsetenv (const char *name); + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gt_cv_func_unsetenv_ret='int' +else + gt_cv_func_unsetenv_ret='void' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_unsetenv_ret" >&5 +$as_echo "$gt_cv_func_unsetenv_ret" >&6; } + if test $gt_cv_func_unsetenv_ret = 'void'; then + +$as_echo "#define VOID_UNSETENV 1" >>confdefs.h + + REPLACE_UNSETENV=1 + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether unsetenv obeys POSIX" >&5 +$as_echo_n "checking whether unsetenv obeys POSIX... " >&6; } +if test "${gl_cv_func_unsetenv_works+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_unsetenv_works="guessing yes" ;; + # If we don't know, assume the worst. + *) gl_cv_func_unsetenv_works="guessing no" ;; + esac + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <stdlib.h> + #include <errno.h> + extern char **environ; + +int +main () +{ + + char entry1[] = "a=1"; + char entry2[] = "b=2"; + char *env[] = { entry1, entry2, NULL }; + if (putenv ((char *) "a=1")) return 1; + if (putenv (entry2)) return 2; + entry2[0] = 'a'; + unsetenv ("a"); + if (getenv ("a")) return 3; + if (!unsetenv ("") || errno != EINVAL) return 4; + entry2[0] = 'b'; + environ = env; + if (!getenv ("a")) return 5; + entry2[0] = 'a'; + unsetenv ("a"); + if (getenv ("a")) return 6; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + gl_cv_func_unsetenv_works=yes +else + gl_cv_func_unsetenv_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_unsetenv_works" >&5 +$as_echo "$gl_cv_func_unsetenv_works" >&6; } + case "$gl_cv_func_unsetenv_works" in + *yes) ;; + *) + REPLACE_UNSETENV=1 + ;; + esac + fi + + if test $HAVE_UNSETENV = 0 || test $REPLACE_UNSETENV = 1; then + + + + + + + + + gl_LIBOBJS="$gl_LIBOBJS unsetenv.$ac_objext" + + + + + + fi + + + + + + GNULIB_UNSETENV=1 + + + + + +$as_echo "#define GNULIB_TEST_UNSETENV 1" >>confdefs.h + + + + + + diff --git a/gdb/gnulib/import/Makefile.am b/gdb/gnulib/import/Makefile.am index baa03a5..26f249d 100644 --- a/gdb/gnulib/import/Makefile.am +++ b/gdb/gnulib/import/Makefile.am @@ -21,7 +21,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=import --m4-base=import/m4 --doc-base=doc --tests-base=tests --aux-dir=import/extra --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca canonicalize-lgpl dirent dirfd errno fnmatch-gnu frexpl inttypes limits-h lstat memchr memmem pathmax rawmemchr readlink rename signal-h strchrnul strstr strtok_r sys_stat unistd update-copyright wchar wctype-h +# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=import --m4-base=import/m4 --doc-base=doc --tests-base=tests --aux-dir=import/extra --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca canonicalize-lgpl dirent dirfd errno fnmatch-gnu frexpl inttypes limits-h lstat memchr memmem pathmax rawmemchr readlink rename setenv signal-h strchrnul strstr strtok_r sys_stat unistd unsetenv update-copyright wchar wctype-h AUTOMAKE_OPTIONS = 1.9.6 gnits @@ -928,6 +928,15 @@ EXTRA_DIST += same-inode.h ## end gnulib module same-inode +## begin gnulib module setenv + + +EXTRA_DIST += setenv.c + +EXTRA_libgnu_a_SOURCES += setenv.c + +## end gnulib module setenv + ## begin gnulib module signal-h BUILT_SOURCES += signal.h @@ -1862,6 +1871,15 @@ EXTRA_DIST += unistd.in.h ## end gnulib module unistd +## begin gnulib module unsetenv + + +EXTRA_DIST += unsetenv.c + +EXTRA_libgnu_a_SOURCES += unsetenv.c + +## end gnulib module unsetenv + ## begin gnulib module update-copyright diff --git a/gdb/gnulib/import/Makefile.in b/gdb/gnulib/import/Makefile.in index d45d7ea..ca7a73d 100644 --- a/gdb/gnulib/import/Makefile.in +++ b/gdb/gnulib/import/Makefile.in @@ -36,7 +36,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=import --m4-base=import/m4 --doc-base=doc --tests-base=tests --aux-dir=import/extra --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca canonicalize-lgpl dirent dirfd errno fnmatch-gnu frexpl inttypes limits-h lstat memchr memmem pathmax rawmemchr readlink rename signal-h strchrnul strstr strtok_r sys_stat unistd update-copyright wchar wctype-h +# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=import --m4-base=import/m4 --doc-base=doc --tests-base=tests --aux-dir=import/extra --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca canonicalize-lgpl dirent dirfd errno fnmatch-gnu frexpl inttypes limits-h lstat memchr memmem pathmax rawmemchr readlink rename setenv signal-h strchrnul strstr strtok_r sys_stat unistd unsetenv update-copyright wchar wctype-h @@ -74,6 +74,7 @@ am__aclocal_m4_deps = $(top_srcdir)/import/m4/00gnulib.m4 \ $(top_srcdir)/import/m4/dirname.m4 \ $(top_srcdir)/import/m4/double-slash-root.m4 \ $(top_srcdir)/import/m4/eealloc.m4 \ + $(top_srcdir)/import/m4/environ.m4 \ $(top_srcdir)/import/m4/errno_h.m4 \ $(top_srcdir)/import/m4/exponentd.m4 \ $(top_srcdir)/import/m4/exponentl.m4 \ @@ -122,6 +123,7 @@ am__aclocal_m4_deps = $(top_srcdir)/import/m4/00gnulib.m4 \ $(top_srcdir)/import/m4/readlink.m4 \ $(top_srcdir)/import/m4/rename.m4 \ $(top_srcdir)/import/m4/rmdir.m4 \ + $(top_srcdir)/import/m4/setenv.m4 \ $(top_srcdir)/import/m4/signal_h.m4 \ $(top_srcdir)/import/m4/ssize_t.m4 \ $(top_srcdir)/import/m4/stat.m4 \ @@ -1289,7 +1291,7 @@ EXTRA_DIST = m4/gnulib-cache.m4 alloca.c alloca.in.h \ mbrtowc.c mbsinit.c mbsrtowcs-impl.h mbsrtowcs-state.c \ mbsrtowcs.c memchr.c memchr.valgrind memmem.c str-two-way.h \ pathmax.h rawmemchr.c rawmemchr.valgrind readlink.c rename.c \ - rmdir.c same-inode.h signal.in.h \ + rmdir.c same-inode.h setenv.c signal.in.h \ $(top_srcdir)/import/extra/snippet/_Noreturn.h \ $(top_srcdir)/import/extra/snippet/arg-nonnull.h \ $(top_srcdir)/import/extra/snippet/c++defs.h \ @@ -1297,7 +1299,7 @@ EXTRA_DIST = m4/gnulib-cache.m4 alloca.c alloca.in.h \ stdbool.in.h stddef.in.h stdint.in.h stdio.in.h stdlib.in.h \ strchrnul.c strchrnul.valgrind streq.h string.in.h \ str-two-way.h strstr.c strtok_r.c sys_stat.in.h sys_time.in.h \ - sys_types.in.h time.in.h unistd.in.h \ + sys_types.in.h time.in.h unistd.in.h unsetenv.c \ $(top_srcdir)/import/extra/update-copyright verify.h \ wchar.in.h wctype.in.h @@ -1343,7 +1345,7 @@ EXTRA_libgnu_a_SOURCES = alloca.c canonicalize-lgpl.c dirfd.c float.c \ gettimeofday.c isnan.c isnand.c isnan.c isnanl.c lstat.c \ malloc.c mbrtowc.c mbsinit.c mbsrtowcs-state.c mbsrtowcs.c \ memchr.c memmem.c rawmemchr.c readlink.c rename.c rmdir.c \ - stat.c strchrnul.c strstr.c strtok_r.c + setenv.c stat.c strchrnul.c strstr.c strtok_r.c unsetenv.c # Use this preprocessor expression to decide whether #include_next works. # Do not rely on a 'configure'-time test for this, since the expression @@ -1449,6 +1451,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readlink.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rename.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rmdir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setenv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strchrnul.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stripslash.Po@am__quote@ @@ -1456,6 +1459,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strstr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtok_r.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unistd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unsetenv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wctype-h.Po@am__quote@ .c.o: diff --git a/gdb/gnulib/import/m4/environ.m4 b/gdb/gnulib/import/m4/environ.m4 new file mode 100644 index 0000000..9a0ea7e --- /dev/null +++ b/gdb/gnulib/import/m4/environ.m4 @@ -0,0 +1,47 @@ +# environ.m4 serial 6 +dnl Copyright (C) 2001-2004, 2006-2016 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN_ONCE([gl_ENVIRON], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + dnl Persuade glibc <unistd.h> to declare environ. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_HEADERS_ONCE([unistd.h]) + gt_CHECK_VAR_DECL( + [#if HAVE_UNISTD_H + #include <unistd.h> + #endif + /* mingw, BeOS, Haiku declare environ in <stdlib.h>, not in <unistd.h>. */ + #include <stdlib.h> + ], + [environ]) + if test $gt_cv_var_environ_declaration != yes; then + HAVE_DECL_ENVIRON=0 + fi +]) + +# Check if a variable is properly declared. +# gt_CHECK_VAR_DECL(includes,variable) +AC_DEFUN([gt_CHECK_VAR_DECL], +[ + define([gt_cv_var], [gt_cv_var_]$2[_declaration]) + AC_MSG_CHECKING([if $2 is properly declared]) + AC_CACHE_VAL([gt_cv_var], [ + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[$1 + extern struct { int foo; } $2;]], + [[$2.foo = 1;]])], + [gt_cv_var=no], + [gt_cv_var=yes])]) + AC_MSG_RESULT([$gt_cv_var]) + if test $gt_cv_var = yes; then + AC_DEFINE([HAVE_]m4_translit($2, [a-z], [A-Z])[_DECL], 1, + [Define if you have the declaration of $2.]) + fi + undefine([gt_cv_var]) +]) diff --git a/gdb/gnulib/import/m4/gnulib-cache.m4 b/gdb/gnulib/import/m4/gnulib-cache.m4 index f99e59b..c4ebb73 100644 --- a/gdb/gnulib/import/m4/gnulib-cache.m4 +++ b/gdb/gnulib/import/m4/gnulib-cache.m4 @@ -27,7 +27,7 @@ # Specification in the form of a command-line invocation: -# gnulib-tool --import --lib=libgnu --source-base=import --m4-base=import/m4 --doc-base=doc --tests-base=tests --aux-dir=import/extra --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca canonicalize-lgpl dirent dirfd errno fnmatch-gnu frexpl inttypes limits-h lstat memchr memmem pathmax rawmemchr readlink rename signal-h strchrnul strstr strtok_r sys_stat unistd update-copyright wchar wctype-h +# gnulib-tool --import --lib=libgnu --source-base=import --m4-base=import/m4 --doc-base=doc --tests-base=tests --aux-dir=import/extra --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca canonicalize-lgpl dirent dirfd errno fnmatch-gnu frexpl inttypes limits-h lstat memchr memmem pathmax rawmemchr readlink rename setenv signal-h strchrnul strstr strtok_r sys_stat unistd unsetenv update-copyright wchar wctype-h # Specification in the form of a few gnulib-tool.m4 macro invocations: gl_LOCAL_DIR([]) @@ -48,12 +48,14 @@ gl_MODULES([ rawmemchr readlink rename + setenv signal-h strchrnul strstr strtok_r sys_stat unistd + unsetenv update-copyright wchar wctype-h diff --git a/gdb/gnulib/import/m4/gnulib-comp.m4 b/gdb/gnulib/import/m4/gnulib-comp.m4 index 42d04ed..5a36567 100644 --- a/gdb/gnulib/import/m4/gnulib-comp.m4 +++ b/gdb/gnulib/import/m4/gnulib-comp.m4 @@ -53,6 +53,7 @@ AC_DEFUN([gl_EARLY], # Code from module dirname-lgpl: # Code from module dosname: # Code from module double-slash-root: + # Code from module environ: # Code from module errno: # Code from module extensions: # Code from module extern-inline: @@ -94,6 +95,7 @@ AC_DEFUN([gl_EARLY], # Code from module rename: # Code from module rmdir: # Code from module same-inode: + # Code from module setenv: # Code from module signal-h: # Code from module snippet/_Noreturn: # Code from module snippet/arg-nonnull: @@ -118,6 +120,7 @@ AC_DEFUN([gl_EARLY], # Code from module sys_types: # Code from module time: # Code from module unistd: + # Code from module unsetenv: # Code from module update-copyright: # Code from module verify: # Code from module wchar: @@ -160,6 +163,8 @@ AC_DEFUN([gl_INIT], gl_DIRENT_MODULE_INDICATOR([dirfd]) gl_DIRNAME_LGPL gl_DOUBLE_SLASH_ROOT + gl_ENVIRON + gl_UNISTD_MODULE_INDICATOR([environ]) gl_HEADER_ERRNO_H AC_REQUIRE([gl_EXTERN_INLINE]) AC_C_FLEXIBLE_ARRAY_MEMBER @@ -285,6 +290,11 @@ AC_DEFUN([gl_INIT], AC_LIBOBJ([rmdir]) fi gl_UNISTD_MODULE_INDICATOR([rmdir]) + gl_FUNC_SETENV + if test $HAVE_SETENV = 0 || test $REPLACE_SETENV = 1; then + AC_LIBOBJ([setenv]) + fi + gl_STDLIB_MODULE_INDICATOR([setenv]) gl_SIGNAL_H gt_TYPE_SSIZE_T gl_FUNC_STAT @@ -328,6 +338,12 @@ AC_DEFUN([gl_INIT], AC_PROG_MKDIR_P gl_HEADER_TIME_H gl_UNISTD_H + gl_FUNC_UNSETENV + if test $HAVE_UNSETENV = 0 || test $REPLACE_UNSETENV = 1; then + AC_LIBOBJ([unsetenv]) + gl_PREREQ_UNSETENV + fi + gl_STDLIB_MODULE_INDICATOR([unsetenv]) gl_WCHAR_H gl_WCTYPE_H # End of code from modules @@ -533,6 +549,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/rename.c lib/rmdir.c lib/same-inode.h + lib/setenv.c lib/signal.in.h lib/stat.c lib/stdbool.in.h @@ -556,6 +573,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/time.in.h lib/unistd.c lib/unistd.in.h + lib/unsetenv.c lib/verify.h lib/wchar.in.h lib/wctype-h.c @@ -571,6 +589,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/dirname.m4 m4/double-slash-root.m4 m4/eealloc.m4 + m4/environ.m4 m4/errno_h.m4 m4/exponentd.m4 m4/exponentl.m4 @@ -618,6 +637,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/readlink.m4 m4/rename.m4 m4/rmdir.m4 + m4/setenv.m4 m4/signal_h.m4 m4/ssize_t.m4 m4/stat.m4 diff --git a/gdb/gnulib/import/m4/setenv.m4 b/gdb/gnulib/import/m4/setenv.m4 new file mode 100644 index 0000000..5d49aba --- /dev/null +++ b/gdb/gnulib/import/m4/setenv.m4 @@ -0,0 +1,160 @@ +# setenv.m4 serial 26 +dnl Copyright (C) 2001-2004, 2006-2016 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_SETENV], +[ + AC_REQUIRE([gl_FUNC_SETENV_SEPARATE]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + if test $ac_cv_func_setenv = no; then + HAVE_SETENV=0 + else + AC_CACHE_CHECK([whether setenv validates arguments], + [gl_cv_func_setenv_works], + [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ + #include <stdlib.h> + #include <errno.h> + #include <string.h> + ]], [[ + int result = 0; + { + if (setenv ("", "", 0) != -1) + result |= 1; + else if (errno != EINVAL) + result |= 2; + } + { + if (setenv ("a", "=", 1) != 0) + result |= 4; + else if (strcmp (getenv ("a"), "=") != 0) + result |= 8; + } + return result; + ]])], + [gl_cv_func_setenv_works=yes], [gl_cv_func_setenv_works=no], + [case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_setenv_works="guessing yes" ;; + # If we don't know, assume the worst. + *) gl_cv_func_setenv_works="guessing no" ;; + esac + ])]) + case "$gl_cv_func_setenv_works" in + *yes) ;; + *) + REPLACE_SETENV=1 + ;; + esac + fi +]) + +# Like gl_FUNC_SETENV, except prepare for separate compilation +# (no REPLACE_SETENV, no AC_LIBOBJ). +AC_DEFUN([gl_FUNC_SETENV_SEPARATE], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + AC_CHECK_DECLS_ONCE([setenv]) + if test $ac_cv_have_decl_setenv = no; then + HAVE_DECL_SETENV=0 + fi + AC_CHECK_FUNCS_ONCE([setenv]) + gl_PREREQ_SETENV +]) + +AC_DEFUN([gl_FUNC_UNSETENV], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CHECK_DECLS_ONCE([unsetenv]) + if test $ac_cv_have_decl_unsetenv = no; then + HAVE_DECL_UNSETENV=0 + fi + AC_CHECK_FUNCS([unsetenv]) + if test $ac_cv_func_unsetenv = no; then + HAVE_UNSETENV=0 + else + HAVE_UNSETENV=1 + dnl Some BSDs return void, failing to do error checking. + AC_CACHE_CHECK([for unsetenv() return type], [gt_cv_func_unsetenv_ret], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +#undef _BSD +#define _BSD 1 /* unhide unsetenv declaration in OSF/1 5.1 <stdlib.h> */ +#include <stdlib.h> +extern +#ifdef __cplusplus +"C" +#endif +int unsetenv (const char *name); + ]], + [[]])], + [gt_cv_func_unsetenv_ret='int'], + [gt_cv_func_unsetenv_ret='void'])]) + if test $gt_cv_func_unsetenv_ret = 'void'; then + AC_DEFINE([VOID_UNSETENV], [1], [Define to 1 if unsetenv returns void + instead of int.]) + REPLACE_UNSETENV=1 + fi + + dnl Solaris 10 unsetenv does not remove all copies of a name. + dnl Haiku alpha 2 unsetenv gets confused by assignment to environ. + dnl OpenBSD 4.7 unsetenv("") does not fail. + AC_CACHE_CHECK([whether unsetenv obeys POSIX], + [gl_cv_func_unsetenv_works], + [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ + #include <stdlib.h> + #include <errno.h> + extern char **environ; + ]], [[ + char entry1[] = "a=1"; + char entry2[] = "b=2"; + char *env[] = { entry1, entry2, NULL }; + if (putenv ((char *) "a=1")) return 1; + if (putenv (entry2)) return 2; + entry2[0] = 'a'; + unsetenv ("a"); + if (getenv ("a")) return 3; + if (!unsetenv ("") || errno != EINVAL) return 4; + entry2[0] = 'b'; + environ = env; + if (!getenv ("a")) return 5; + entry2[0] = 'a'; + unsetenv ("a"); + if (getenv ("a")) return 6; + ]])], + [gl_cv_func_unsetenv_works=yes], [gl_cv_func_unsetenv_works=no], + [case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_unsetenv_works="guessing yes" ;; + # If we don't know, assume the worst. + *) gl_cv_func_unsetenv_works="guessing no" ;; + esac + ])]) + case "$gl_cv_func_unsetenv_works" in + *yes) ;; + *) + REPLACE_UNSETENV=1 + ;; + esac + fi +]) + +# Prerequisites of lib/setenv.c. +AC_DEFUN([gl_PREREQ_SETENV], +[ + AC_REQUIRE([AC_FUNC_ALLOCA]) + AC_REQUIRE([gl_ENVIRON]) + AC_CHECK_HEADERS_ONCE([unistd.h]) + AC_CHECK_HEADERS([search.h]) + AC_CHECK_FUNCS([tsearch]) +]) + +# Prerequisites of lib/unsetenv.c. +AC_DEFUN([gl_PREREQ_UNSETENV], +[ + AC_REQUIRE([gl_ENVIRON]) + AC_CHECK_HEADERS_ONCE([unistd.h]) +]) diff --git a/gdb/gnulib/import/setenv.c b/gdb/gnulib/import/setenv.c new file mode 100644 index 0000000..85c32cb --- /dev/null +++ b/gdb/gnulib/import/setenv.c @@ -0,0 +1,390 @@ +/* Copyright (C) 1992, 1995-2003, 2005-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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/>. */ + +#if !_LIBC +/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc + optimizes away the name == NULL test below. */ +# define _GL_ARG_NONNULL(params) + +# define _GL_USE_STDLIB_ALLOC 1 +# include <config.h> +#endif + +#include <alloca.h> + +/* Specification. */ +#include <stdlib.h> + +#include <errno.h> +#ifndef __set_errno +# define __set_errno(ev) ((errno) = (ev)) +#endif + +#include <string.h> +#if _LIBC || HAVE_UNISTD_H +# include <unistd.h> +#endif + +#if !_LIBC +# include "malloca.h" +#endif + +#if _LIBC || !HAVE_SETENV + +#if !_LIBC +# define __environ environ +#endif + +#if _LIBC +/* This lock protects against simultaneous modifications of 'environ'. */ +# include <bits/libc-lock.h> +__libc_lock_define_initialized (static, envlock) +# define LOCK __libc_lock_lock (envlock) +# define UNLOCK __libc_lock_unlock (envlock) +#else +# define LOCK +# define UNLOCK +#endif + +/* In the GNU C library we must keep the namespace clean. */ +#ifdef _LIBC +# define setenv __setenv +# define clearenv __clearenv +# define tfind __tfind +# define tsearch __tsearch +#endif + +/* In the GNU C library implementation we try to be more clever and + allow arbitrarily many changes of the environment given that the used + values are from a small set. Outside glibc this will eat up all + memory after a while. */ +#if defined _LIBC || (defined HAVE_SEARCH_H && defined HAVE_TSEARCH \ + && defined __GNUC__) +# define USE_TSEARCH 1 +# include <search.h> +typedef int (*compar_fn_t) (const void *, const void *); + +/* This is a pointer to the root of the search tree with the known + values. */ +static void *known_values; + +# define KNOWN_VALUE(Str) \ + ({ \ + void *value = tfind (Str, &known_values, (compar_fn_t) strcmp); \ + value != NULL ? *(char **) value : NULL; \ + }) +# define STORE_VALUE(Str) \ + tsearch (Str, &known_values, (compar_fn_t) strcmp) + +#else +# undef USE_TSEARCH + +# define KNOWN_VALUE(Str) NULL +# define STORE_VALUE(Str) do { } while (0) + +#endif + + +/* If this variable is not a null pointer we allocated the current + environment. */ +static char **last_environ; + + +/* This function is used by 'setenv' and 'putenv'. The difference between + the two functions is that for the former must create a new string which + is then placed in the environment, while the argument of 'putenv' + must be used directly. This is all complicated by the fact that we try + to reuse values once generated for a 'setenv' call since we can never + free the strings. */ +int +__add_to_environ (const char *name, const char *value, const char *combined, + int replace) +{ + char **ep; + size_t size; + const size_t namelen = strlen (name); + const size_t vallen = value != NULL ? strlen (value) + 1 : 0; + + LOCK; + + /* We have to get the pointer now that we have the lock and not earlier + since another thread might have created a new environment. */ + ep = __environ; + + size = 0; + if (ep != NULL) + { + for (; *ep != NULL; ++ep) + if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=') + break; + else + ++size; + } + + if (ep == NULL || *ep == NULL) + { + char **new_environ; +#ifdef USE_TSEARCH + char *new_value; +#endif + + /* We allocated this space; we can extend it. */ + new_environ = + (char **) (last_environ == NULL + ? malloc ((size + 2) * sizeof (char *)) + : realloc (last_environ, (size + 2) * sizeof (char *))); + if (new_environ == NULL) + { + /* It's easier to set errno to ENOMEM than to rely on the + 'malloc-posix' and 'realloc-posix' gnulib modules. */ + __set_errno (ENOMEM); + UNLOCK; + return -1; + } + + /* If the whole entry is given add it. */ + if (combined != NULL) + /* We must not add the string to the search tree since it belongs + to the user. */ + new_environ[size] = (char *) combined; + else + { + /* See whether the value is already known. */ +#ifdef USE_TSEARCH +# ifdef _LIBC + new_value = (char *) alloca (namelen + 1 + vallen); + __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1), + value, vallen); +# else + new_value = (char *) malloca (namelen + 1 + vallen); + if (new_value == NULL) + { + __set_errno (ENOMEM); + UNLOCK; + return -1; + } + memcpy (new_value, name, namelen); + new_value[namelen] = '='; + memcpy (&new_value[namelen + 1], value, vallen); +# endif + + new_environ[size] = KNOWN_VALUE (new_value); + if (new_environ[size] == NULL) +#endif + { + new_environ[size] = (char *) malloc (namelen + 1 + vallen); + if (new_environ[size] == NULL) + { +#if defined USE_TSEARCH && !defined _LIBC + freea (new_value); +#endif + __set_errno (ENOMEM); + UNLOCK; + return -1; + } + +#ifdef USE_TSEARCH + memcpy (new_environ[size], new_value, namelen + 1 + vallen); +#else + memcpy (new_environ[size], name, namelen); + new_environ[size][namelen] = '='; + memcpy (&new_environ[size][namelen + 1], value, vallen); +#endif + /* And save the value now. We cannot do this when we remove + the string since then we cannot decide whether it is a + user string or not. */ + STORE_VALUE (new_environ[size]); + } +#if defined USE_TSEARCH && !defined _LIBC + freea (new_value); +#endif + } + + if (__environ != last_environ) + memcpy ((char *) new_environ, (char *) __environ, + size * sizeof (char *)); + + new_environ[size + 1] = NULL; + + last_environ = __environ = new_environ; + } + else if (replace) + { + char *np; + + /* Use the user string if given. */ + if (combined != NULL) + np = (char *) combined; + else + { +#ifdef USE_TSEARCH + char *new_value; +# ifdef _LIBC + new_value = alloca (namelen + 1 + vallen); + __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1), + value, vallen); +# else + new_value = malloca (namelen + 1 + vallen); + if (new_value == NULL) + { + __set_errno (ENOMEM); + UNLOCK; + return -1; + } + memcpy (new_value, name, namelen); + new_value[namelen] = '='; + memcpy (&new_value[namelen + 1], value, vallen); +# endif + + np = KNOWN_VALUE (new_value); + if (np == NULL) +#endif + { + np = (char *) malloc (namelen + 1 + vallen); + if (np == NULL) + { +#if defined USE_TSEARCH && !defined _LIBC + freea (new_value); +#endif + __set_errno (ENOMEM); + UNLOCK; + return -1; + } + +#ifdef USE_TSEARCH + memcpy (np, new_value, namelen + 1 + vallen); +#else + memcpy (np, name, namelen); + np[namelen] = '='; + memcpy (&np[namelen + 1], value, vallen); +#endif + /* And remember the value. */ + STORE_VALUE (np); + } +#if defined USE_TSEARCH && !defined _LIBC + freea (new_value); +#endif + } + + *ep = np; + } + + UNLOCK; + + return 0; +} + +int +setenv (const char *name, const char *value, int replace) +{ + if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) + { + __set_errno (EINVAL); + return -1; + } + + return __add_to_environ (name, value, NULL, replace); +} + +/* The 'clearenv' was planned to be added to POSIX.1 but probably + never made it. Nevertheless the POSIX.9 standard (POSIX bindings + for Fortran 77) requires this function. */ +int +clearenv (void) +{ + LOCK; + + if (__environ == last_environ && __environ != NULL) + { + /* We allocated this environment so we can free it. */ + free (__environ); + last_environ = NULL; + } + + /* Clear the environment pointer removes the whole environment. */ + __environ = NULL; + + UNLOCK; + + return 0; +} + +#ifdef _LIBC +static void +free_mem (void) +{ + /* Remove all traces. */ + clearenv (); + + /* Now remove the search tree. */ + __tdestroy (known_values, free); + known_values = NULL; +} +text_set_element (__libc_subfreeres, free_mem); + + +# undef setenv +# undef clearenv +weak_alias (__setenv, setenv) +weak_alias (__clearenv, clearenv) +#endif + +#endif /* _LIBC || !HAVE_SETENV */ + +/* The rest of this file is called into use when replacing an existing + but buggy setenv. Known bugs include failure to diagnose invalid + name, and consuming a leading '=' from value. */ +#if HAVE_SETENV + +# undef setenv +# if !HAVE_DECL_SETENV +extern int setenv (const char *, const char *, int); +# endif +# define STREQ(a, b) (strcmp (a, b) == 0) + +int +rpl_setenv (const char *name, const char *value, int replace) +{ + int result; + if (!name || !*name || strchr (name, '=')) + { + errno = EINVAL; + return -1; + } + /* Call the real setenv even if replace is 0, in case implementation + has underlying data to update, such as when environ changes. */ + result = setenv (name, value, replace); + if (result == 0 && replace && *value == '=') + { + char *tmp = getenv (name); + if (!STREQ (tmp, value)) + { + int saved_errno; + size_t len = strlen (value); + tmp = malloca (len + 2); + /* Since leading '=' is eaten, double it up. */ + *tmp = '='; + memcpy (tmp + 1, value, len + 1); + result = setenv (name, tmp, replace); + saved_errno = errno; + freea (tmp); + errno = saved_errno; + } + } + return result; +} + +#endif /* HAVE_SETENV */ diff --git a/gdb/gnulib/import/unsetenv.c b/gdb/gnulib/import/unsetenv.c new file mode 100644 index 0000000..8368744 --- /dev/null +++ b/gdb/gnulib/import/unsetenv.c @@ -0,0 +1,127 @@ +/* Copyright (C) 1992, 1995-2002, 2005-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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/>. */ + +/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc + optimizes away the name == NULL test below. */ +#define _GL_ARG_NONNULL(params) + +#include <config.h> + +/* Specification. */ +#include <stdlib.h> + +#include <errno.h> +#if !_LIBC +# define __set_errno(ev) ((errno) = (ev)) +#endif + +#include <string.h> +#include <unistd.h> + +#if !_LIBC +# define __environ environ +#endif + +#if _LIBC +/* This lock protects against simultaneous modifications of 'environ'. */ +# include <bits/libc-lock.h> +__libc_lock_define_initialized (static, envlock) +# define LOCK __libc_lock_lock (envlock) +# define UNLOCK __libc_lock_unlock (envlock) +#else +# define LOCK +# define UNLOCK +#endif + +/* In the GNU C library we must keep the namespace clean. */ +#ifdef _LIBC +# define unsetenv __unsetenv +#endif + +#if _LIBC || !HAVE_UNSETENV + +int +unsetenv (const char *name) +{ + size_t len; + char **ep; + + if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) + { + __set_errno (EINVAL); + return -1; + } + + len = strlen (name); + + LOCK; + + ep = __environ; + while (*ep != NULL) + if (!strncmp (*ep, name, len) && (*ep)[len] == '=') + { + /* Found it. Remove this pointer by moving later ones back. */ + char **dp = ep; + + do + dp[0] = dp[1]; + while (*dp++); + /* Continue the loop in case NAME appears again. */ + } + else + ++ep; + + UNLOCK; + + return 0; +} + +#ifdef _LIBC +# undef unsetenv +weak_alias (__unsetenv, unsetenv) +#endif + +#else /* HAVE_UNSETENV */ + +# undef unsetenv +# if !HAVE_DECL_UNSETENV +# if VOID_UNSETENV +extern void unsetenv (const char *); +# else +extern int unsetenv (const char *); +# endif +# endif + +/* Call the underlying unsetenv, in case there is hidden bookkeeping + that needs updating beyond just modifying environ. */ +int +rpl_unsetenv (const char *name) +{ + int result = 0; + if (!name || !*name || strchr (name, '=')) + { + errno = EINVAL; + return -1; + } + while (getenv (name)) +# if !VOID_UNSETENV + result = +# endif + unsetenv (name); + return result; +} + +#endif /* HAVE_UNSETENV */ diff --git a/gdb/gnulib/update-gnulib.sh b/gdb/gnulib/update-gnulib.sh index 19d949b..2775dc7 100755 --- a/gdb/gnulib/update-gnulib.sh +++ b/gdb/gnulib/update-gnulib.sh @@ -46,12 +46,14 @@ IMPORTED_GNULIB_MODULES="\ rawmemchr \ readlink \ rename \ + setenv \ signal-h \ strchrnul \ strstr \ strtok_r \ sys_stat \ unistd \ + unsetenv \ update-copyright \ wchar \ wctype-h \ diff --git a/gdb/go-exp.y b/gdb/go-exp.y index 057e227..f2f3596 100644 --- a/gdb/go-exp.y +++ b/gdb/go-exp.y @@ -1297,7 +1297,7 @@ static int popping; /* Temporary storage for yylex; this holds symbol names as they are built up. */ -static struct obstack name_obstack; +static auto_obstack name_obstack; /* Build "package.name" in name_obstack. For convenience of the caller, the name is NUL-terminated, @@ -1309,7 +1309,7 @@ build_packaged_name (const char *package, int package_len, { struct stoken result; - obstack_free (&name_obstack, obstack_base (&name_obstack)); + name_obstack.clear (); obstack_grow (&name_obstack, package, package_len); obstack_grow_str (&name_obstack, "."); obstack_grow (&name_obstack, name, name_len); @@ -1567,6 +1567,8 @@ go_parse (struct parser_state *par_state) gdb_assert (par_state != NULL); pstate = par_state; + /* Note that parsing (within yyparse) freely installs cleanups + assuming they'll be run here (below). */ back_to = make_cleanup (null_cleanup, NULL); scoped_restore restore_yydebug = make_scoped_restore (&yydebug, @@ -1579,8 +1581,7 @@ go_parse (struct parser_state *par_state) VEC_free (token_and_value, token_fifo); popping = 0; - obstack_init (&name_obstack); - make_cleanup_obstack_free (&name_obstack); + name_obstack.clear (); result = yyparse (); do_cleanups (back_to); diff --git a/gdb/go-lang.c b/gdb/go-lang.c index f38e845..9448f2c 100644 --- a/gdb/go-lang.c +++ b/gdb/go-lang.c @@ -565,7 +565,7 @@ go_language_arch_info (struct gdbarch *gdbarch, lai->bool_type_default = builtin->builtin_bool; } -static const struct language_defn go_language_defn = +extern const struct language_defn go_language_defn = { "go", "Go", @@ -600,13 +600,13 @@ static const struct language_defn go_language_defn = 1, /* C-style arrays. */ 0, /* String lower bound. */ default_word_break_characters, - default_make_symbol_completion_list, + default_collect_symbol_completion_matches, go_language_arch_info, default_print_array_index, default_pass_by_reference, c_get_string, c_watch_location_expression, - NULL, + NULL, /* la_get_symbol_name_cmp */ iterate_over_symbols, default_compute_string_hash, &default_varobj_ops, @@ -677,6 +677,4 @@ void _initialize_go_language (void) { go_type_data = gdbarch_data_register_post_init (build_go_types); - - add_language (&go_language_defn); } diff --git a/gdb/guile/scm-cmd.c b/gdb/guile/scm-cmd.c index ae5d145..5501d31 100644 --- a/gdb/guile/scm-cmd.c +++ b/gdb/guile/scm-cmd.c @@ -114,7 +114,7 @@ static const struct cmdscm_completer cmdscm_completers[] = { "COMPLETE_FILENAME", filename_completer }, { "COMPLETE_LOCATION", location_completer }, { "COMPLETE_COMMAND", command_completer }, - { "COMPLETE_SYMBOL", make_symbol_completion_list_fn }, + { "COMPLETE_SYMBOL", symbol_completer }, { "COMPLETE_EXPRESSION", expression_completer }, }; @@ -350,9 +350,8 @@ cmdscm_bad_completion_result (const char *msg, SCM completion) The result is a boolean indicating success. */ static int -cmdscm_add_completion (SCM completion, VEC (char_ptr) **result) +cmdscm_add_completion (SCM completion, completion_tracker &tracker) { - char *item; SCM except_scm; if (!scm_is_string (completion)) @@ -363,8 +362,9 @@ cmdscm_add_completion (SCM completion, VEC (char_ptr) **result) return 0; } - item = gdbscm_scm_to_string (completion, NULL, host_charset (), 1, - &except_scm); + gdb::unique_xmalloc_ptr<char> item + (gdbscm_scm_to_string (completion, NULL, host_charset (), 1, + &except_scm)); if (item == NULL) { /* Inform the user, but otherwise ignore the entire result. */ @@ -372,21 +372,21 @@ cmdscm_add_completion (SCM completion, VEC (char_ptr) **result) return 0; } - VEC_safe_push (char_ptr, *result, item); + tracker.add_completion (std::move (item)); return 1; } /* Called by gdb for command completion. */ -static VEC (char_ptr) * +static void cmdscm_completer (struct cmd_list_element *command, + completion_tracker &tracker, const char *text, const char *word) { command_smob *c_smob/*obj*/ = (command_smob *) get_cmd_context (command); SCM completer_result_scm; SCM text_scm, word_scm, result_scm; - VEC (char_ptr) *result = NULL; gdb_assert (c_smob != NULL); gdb_assert (gdbscm_is_procedure (c_smob->complete)); @@ -408,7 +408,7 @@ cmdscm_completer (struct cmd_list_element *command, { /* Inform the user, but otherwise ignore. */ gdbscm_print_gdb_exception (SCM_BOOL_F, completer_result_scm); - goto done; + return; } if (gdbscm_is_true (scm_list_p (completer_result_scm))) @@ -419,11 +419,8 @@ cmdscm_completer (struct cmd_list_element *command, { SCM next = scm_car (list); - if (!cmdscm_add_completion (next, &result)) - { - VEC_free (char_ptr, result); - goto done; - } + if (!cmdscm_add_completion (next, tracker)) + break; list = scm_cdr (list); } @@ -437,17 +434,13 @@ cmdscm_completer (struct cmd_list_element *command, { if (gdbscm_is_exception (next)) { - /* Inform the user, but otherwise ignore the entire result. */ + /* Inform the user. */ gdbscm_print_gdb_exception (SCM_BOOL_F, completer_result_scm); - VEC_free (char_ptr, result); - goto done; + break; } - if (!cmdscm_add_completion (next, &result)) - { - VEC_free (char_ptr, result); - goto done; - } + if (cmdscm_add_completion (next, tracker)) + break; next = itscm_safe_call_next_x (iter, NULL); } @@ -458,9 +451,6 @@ cmdscm_completer (struct cmd_list_element *command, cmdscm_bad_completion_result (_("Bad completer result: "), completer_result_scm); } - - done: - return result; } /* Helper for gdbscm_make_command which locates the command list to use and diff --git a/gdb/guile/scm-string.c b/gdb/guile/scm-string.c index d97f583..4e495eb 100644 --- a/gdb/guile/scm-string.c +++ b/gdb/guile/scm-string.c @@ -241,7 +241,6 @@ static SCM gdbscm_string_to_argv (SCM string_scm) { char *string; - char **c_argv; int i; SCM result = SCM_EOL; @@ -254,11 +253,10 @@ gdbscm_string_to_argv (SCM string_scm) return SCM_EOL; } - c_argv = gdb_buildargv (string); - for (i = 0; c_argv[i] != NULL; ++i) - result = scm_cons (gdbscm_scm_from_c_string (c_argv[i]), result); + gdb_argv c_argv (string); + for (char *arg : c_argv) + result = scm_cons (gdbscm_scm_from_c_string (arg), result); - freeargv (c_argv); xfree (string); return scm_reverse_x (result, SCM_EOL); diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c index d381e41..dd21b70 100644 --- a/gdb/i386-linux-tdep.c +++ b/gdb/i386-linux-tdep.c @@ -45,13 +45,14 @@ #include "record-full.h" #include "linux-record.h" -#include "features/i386/i386-linux.c" -#include "features/i386/i386-mmx-linux.c" -#include "features/i386/i386-mpx-linux.c" -#include "features/i386/i386-avx-mpx-linux.c" -#include "features/i386/i386-avx-linux.c" -#include "features/i386/i386-avx-avx512-linux.c" -#include "features/i386/i386-avx-mpx-avx512-pku-linux.c" + +#include "features/i386/32bit-core.c" +#include "features/i386/32bit-sse.c" +#include "features/i386/32bit-linux.c" +#include "features/i386/32bit-avx.c" +#include "features/i386/32bit-mpx.c" +#include "features/i386/32bit-avx512.c" +#include "features/i386/32bit-pkeys.c" /* Return non-zero, when the register is in the corresponding register group. Put the LINUX_ORIG_EAX register in the system group. */ @@ -678,6 +679,57 @@ i386_linux_core_read_xcr0 (bfd *abfd) return xcr0; } +/* See i386-linux-tdep.h. */ + +const struct target_desc * +i386_linux_read_description (uint64_t xcr0) +{ + if (xcr0 == 0) + return NULL; + + static struct target_desc *i386_linux_tdescs \ + [2/*X87*/][2/*SSE*/][2/*AVX*/][2/*MPX*/][2/*AVX512*/][2/*PKRU*/] = {}; + struct target_desc **tdesc; + + tdesc = &i386_linux_tdescs[(xcr0 & X86_XSTATE_X87) ? 1 : 0] + [(xcr0 & X86_XSTATE_SSE) ? 1 : 0] + [(xcr0 & X86_XSTATE_AVX) ? 1 : 0] + [(xcr0 & X86_XSTATE_MPX) ? 1 : 0] + [(xcr0 & X86_XSTATE_AVX512) ? 1 : 0] + [(xcr0 & X86_XSTATE_PKRU) ? 1 : 0]; + + if (*tdesc == NULL) + { + *tdesc = allocate_target_description (); + set_tdesc_architecture (*tdesc, bfd_scan_arch ("i386")); + set_tdesc_osabi (*tdesc, osabi_from_tdesc_string ("GNU/Linux")); + + long regnum = 0; + + if (xcr0 & X86_XSTATE_X87) + regnum = create_feature_i386_32bit_core (*tdesc, regnum); + + if (xcr0 & X86_XSTATE_SSE) + regnum = create_feature_i386_32bit_sse (*tdesc, regnum); + + regnum = create_feature_i386_32bit_linux (*tdesc, regnum); + + if (xcr0 & X86_XSTATE_AVX) + regnum = create_feature_i386_32bit_avx (*tdesc, regnum); + + if (xcr0 & X86_XSTATE_MPX) + regnum = create_feature_i386_32bit_mpx (*tdesc, regnum); + + if (xcr0 & X86_XSTATE_AVX512) + regnum = create_feature_i386_32bit_avx512 (*tdesc, regnum); + + if (xcr0 & X86_XSTATE_PKRU) + regnum = create_feature_i386_32bit_pkeys (*tdesc, regnum); + } + + return *tdesc; +} + /* Get Linux/x86 target description from core dump. */ static const struct target_desc * @@ -687,31 +739,15 @@ i386_linux_core_read_description (struct gdbarch *gdbarch, { /* Linux/i386. */ uint64_t xcr0 = i386_linux_core_read_xcr0 (abfd); + const struct target_desc *tdesc = i386_linux_read_description (xcr0); - switch ((xcr0 & X86_XSTATE_ALL_MASK)) - { - case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK: - return tdesc_i386_avx_mpx_avx512_pku_linux; - case X86_XSTATE_AVX_AVX512_MASK: - return tdesc_i386_avx_avx512_linux; - case X86_XSTATE_MPX_MASK: - return tdesc_i386_mpx_linux; - case X86_XSTATE_AVX_MPX_MASK: - return tdesc_i386_avx_mpx_linux; - case X86_XSTATE_AVX_MASK: - return tdesc_i386_avx_linux; - case X86_XSTATE_SSE_MASK: - return tdesc_i386_linux; - case X86_XSTATE_X87_MASK: - return tdesc_i386_mmx_linux; - default: - break; - } + if (tdesc != NULL) + return tdesc; if (bfd_get_section_by_name (abfd, ".reg-xfp") != NULL) - return tdesc_i386_linux; + return i386_linux_read_description (X86_XSTATE_SSE_MASK); else - return tdesc_i386_mmx_linux; + return i386_linux_read_description (X86_XSTATE_X87_MASK); } /* Similar to i386_supply_fpregset, but use XSAVE extended state. */ @@ -819,8 +855,7 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); const struct target_desc *tdesc = info.target_desc; - struct tdesc_arch_data *tdesc_data - = (struct tdesc_arch_data *) info.tdep_info; + struct tdesc_arch_data *tdesc_data = info.tdesc_data; const struct tdesc_feature *feature; int valid_p; @@ -835,7 +870,7 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_num_regs (gdbarch, I386_LINUX_NUM_REGS); if (! tdesc_has_registers (tdesc)) - tdesc = tdesc_i386_linux; + tdesc = i386_linux_read_description (X86_XSTATE_SSE_MASK); tdep->tdesc = tdesc; feature = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.linux"); @@ -1081,12 +1116,27 @@ _initialize_i386_linux_tdep (void) gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_LINUX, i386_linux_init_abi); - /* Initialize the Linux target description. */ - initialize_tdesc_i386_linux (); - initialize_tdesc_i386_mmx_linux (); - initialize_tdesc_i386_avx_linux (); - initialize_tdesc_i386_mpx_linux (); - initialize_tdesc_i386_avx_mpx_linux (); - initialize_tdesc_i386_avx_avx512_linux (); - initialize_tdesc_i386_avx_mpx_avx512_pku_linux (); +#if GDB_SELF_TEST + struct + { + const char *xml; + uint64_t mask; + } xml_masks[] = { + { "i386/i386-linux.xml", X86_XSTATE_SSE_MASK }, + { "i386/i386-mmx-linux.xml", X86_XSTATE_X87_MASK }, + { "i386/i386-avx-linux.xml", X86_XSTATE_AVX_MASK }, + { "i386/i386-mpx-linux.xml", X86_XSTATE_MPX_MASK }, + { "i386/i386-avx-mpx-linux.xml", X86_XSTATE_AVX_MPX_MASK }, + { "i386/i386-avx-avx512-linux.xml", X86_XSTATE_AVX_AVX512_MASK }, + { "i386/i386-avx-mpx-avx512-pku-linux.xml", + X86_XSTATE_AVX_MPX_AVX512_PKU_MASK }, + }; + + for (auto &a : xml_masks) + { + auto tdesc = i386_linux_read_description (a.mask); + + selftests::record_xml_tdesc (a.xml, tdesc); + } +#endif /* GDB_SELF_TEST */ } diff --git a/gdb/i386-linux-tdep.h b/gdb/i386-linux-tdep.h index 8d4c7ca..1ca8d6b 100644 --- a/gdb/i386-linux-tdep.h +++ b/gdb/i386-linux-tdep.h @@ -42,14 +42,8 @@ extern uint64_t i386_linux_core_read_xcr0 (bfd *abfd); extern void i386_linux_handle_segmentation_fault (struct gdbarch *gdbarch, struct ui_out *uiout); -/* Linux target description. */ -extern struct target_desc *tdesc_i386_linux; -extern struct target_desc *tdesc_i386_mmx_linux; -extern struct target_desc *tdesc_i386_avx_linux; -extern struct target_desc *tdesc_i386_mpx_linux; -extern struct target_desc *tdesc_i386_avx_mpx_linux; -extern struct target_desc *tdesc_i386_avx_avx512_linux; -extern struct target_desc *tdesc_i386_avx_mpx_avx512_pku_linux; +/* Return the target description according to XCR0. */ +extern const struct target_desc *i386_linux_read_description (uint64_t xcr0); /* Format of XSAVE extended state is: struct diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index bd728f0..b1e5afd 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -8604,7 +8604,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Hook in ABI-specific overrides, if they have been registered. Note: If INFO specifies a 64 bit arch, this is where we turn a 32-bit i386 into a 64-bit amd64. */ - info.tdep_info = tdesc_data; + info.tdesc_data = tdesc_data; gdbarch_init_osabi (info, gdbarch); if (!i386_validate_tdesc_p (tdep, tdesc_data)) diff --git a/gdb/infcmd.c b/gdb/infcmd.c index defa7b0..c8a82db 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -2230,7 +2230,7 @@ unset_environment_command (char *var, int from_tty) /* If there is no argument, delete all environment variables. Ask for confirmation if reading from the terminal. */ if (!from_tty || query (_("Delete all environment variables? "))) - current_inferior ()->environment = gdb_environ::from_host_environ (); + current_inferior ()->environment.clear (); } else current_inferior ()->environment.unset (var); diff --git a/gdb/inferior.c b/gdb/inferior.c index 9fa2dad..a20c6c5 100644 --- a/gdb/inferior.c +++ b/gdb/inferior.c @@ -534,7 +534,6 @@ static void print_inferior (struct ui_out *uiout, char *requested_inferiors) { struct inferior *inf; - struct cleanup *old_chain; int inf_count = 0; /* Compute number of inferiors we will print. */ @@ -552,8 +551,7 @@ print_inferior (struct ui_out *uiout, char *requested_inferiors) return; } - old_chain = make_cleanup_ui_out_table_begin_end (uiout, 4, inf_count, - "inferiors"); + ui_out_emit_table table_emitter (uiout, 4, inf_count, "inferiors"); uiout->table_header (1, ui_left, "current", ""); uiout->table_header (4, ui_left, "number", "Num"); uiout->table_header (17, ui_left, "target-id", "Description"); @@ -597,8 +595,6 @@ print_inferior (struct ui_out *uiout, char *requested_inferiors) uiout->text ("\n"); } - - do_cleanups (old_chain); } static void @@ -799,20 +795,17 @@ static void add_inferior_command (char *args, int from_tty) { int i, copies = 1; - char *exec = NULL; - char **argv; + gdb::unique_xmalloc_ptr<char> exec; symfile_add_flags add_flags = 0; - struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); if (from_tty) add_flags |= SYMFILE_VERBOSE; if (args) { - argv = gdb_buildargv (args); - make_cleanup_freeargv (argv); + gdb_argv built_argv (args); - for (; *argv != NULL; argv++) + for (char **argv = built_argv.get (); *argv != NULL; argv++) { if (**argv == '-') { @@ -828,8 +821,7 @@ add_inferior_command (char *args, int from_tty) ++argv; if (!*argv) error (_("No argument to -exec")); - exec = tilde_expand (*argv); - make_cleanup (xfree, exec); + exec.reset (tilde_expand (*argv)); } } else @@ -853,12 +845,10 @@ add_inferior_command (char *args, int from_tty) set_current_inferior (inf); switch_to_thread (null_ptid); - exec_file_attach (exec, from_tty); - symbol_file_add_main (exec, add_flags); + exec_file_attach (exec.get (), from_tty); + symbol_file_add_main (exec.get (), add_flags); } } - - do_cleanups (old_chain); } /* clone-inferior [-copies N] [ID] */ @@ -867,15 +857,13 @@ static void clone_inferior_command (char *args, int from_tty) { int i, copies = 1; - char **argv; struct inferior *orginf = NULL; - struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); if (args) { - argv = gdb_buildargv (args); - make_cleanup_freeargv (argv); + gdb_argv built_argv (args); + char **argv = built_argv.get (); for (; *argv != NULL; argv++) { if (**argv == '-') @@ -946,8 +934,6 @@ clone_inferior_command (char *args, int from_tty) switch_to_thread (null_ptid); clone_program_space (pspace, orginf->pspace); } - - do_cleanups (old_chain); } /* Print notices when new inferiors are created and die. */ diff --git a/gdb/infrun.c b/gdb/infrun.c index 5e4cd51..d6723fd 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -66,6 +66,7 @@ #include "common/enum-flags.h" #include "progspace-and-thread.h" #include "common/gdb_optional.h" +#include "arch-utils.h" /* Prototypes for local functions */ @@ -6787,7 +6788,7 @@ process_event_stop_test (struct execution_control_state *ecs) tmp_sal = find_pc_line (ecs->stop_func_start, 0); if (tmp_sal.line != 0 && !function_name_is_marked_for_skip (ecs->stop_func_name, - &tmp_sal)) + tmp_sal)) { if (execution_direction == EXEC_REVERSE) handle_step_into_function_backward (gdbarch, ecs); @@ -7317,8 +7318,8 @@ handle_step_into_function (struct gdbarch *gdbarch, cust = find_pc_compunit_symtab (stop_pc); if (cust != NULL && compunit_language (cust) != language_asm) - ecs->stop_func_start = gdbarch_skip_prologue (gdbarch, - ecs->stop_func_start); + ecs->stop_func_start + = gdbarch_skip_prologue_noexcept (gdbarch, ecs->stop_func_start); stop_func_sal = find_pc_line (ecs->stop_func_start, 0); /* Use the step_resume_break to step until the end of the prologue, @@ -7396,8 +7397,8 @@ handle_step_into_function_backward (struct gdbarch *gdbarch, cust = find_pc_compunit_symtab (stop_pc); if (cust != NULL && compunit_language (cust) != language_asm) - ecs->stop_func_start = gdbarch_skip_prologue (gdbarch, - ecs->stop_func_start); + ecs->stop_func_start + = gdbarch_skip_prologue_noexcept (gdbarch, ecs->stop_func_start); stop_func_sal = find_pc_line (stop_pc, 0); @@ -8511,14 +8512,12 @@ sig_print_info (enum gdb_signal oursig) static void handle_command (char *args, int from_tty) { - char **argv; int digits, wordlen; int sigfirst, signum, siglast; enum gdb_signal oursig; int allsigs; int nsigs; unsigned char *sigs; - struct cleanup *old_chain; if (args == NULL) { @@ -8533,24 +8532,23 @@ handle_command (char *args, int from_tty) /* Break the command line up into args. */ - argv = gdb_buildargv (args); - old_chain = make_cleanup_freeargv (argv); + gdb_argv built_argv (args); /* Walk through the args, looking for signal oursigs, signal names, and actions. Signal numbers and signal names may be interspersed with actions, with the actions being performed for all signals cumulatively specified. Signal ranges can be specified as <LOW>-<HIGH>. */ - while (*argv != NULL) + for (char *arg : built_argv) { - wordlen = strlen (*argv); - for (digits = 0; isdigit ((*argv)[digits]); digits++) + wordlen = strlen (arg); + for (digits = 0; isdigit (arg[digits]); digits++) {; } allsigs = 0; sigfirst = siglast = -1; - if (wordlen >= 1 && !strncmp (*argv, "all", wordlen)) + if (wordlen >= 1 && !strncmp (arg, "all", wordlen)) { /* Apply action to all signals except those used by the debugger. Silently skip those. */ @@ -8558,37 +8556,37 @@ handle_command (char *args, int from_tty) sigfirst = 0; siglast = nsigs - 1; } - else if (wordlen >= 1 && !strncmp (*argv, "stop", wordlen)) + else if (wordlen >= 1 && !strncmp (arg, "stop", wordlen)) { SET_SIGS (nsigs, sigs, signal_stop); SET_SIGS (nsigs, sigs, signal_print); } - else if (wordlen >= 1 && !strncmp (*argv, "ignore", wordlen)) + else if (wordlen >= 1 && !strncmp (arg, "ignore", wordlen)) { UNSET_SIGS (nsigs, sigs, signal_program); } - else if (wordlen >= 2 && !strncmp (*argv, "print", wordlen)) + else if (wordlen >= 2 && !strncmp (arg, "print", wordlen)) { SET_SIGS (nsigs, sigs, signal_print); } - else if (wordlen >= 2 && !strncmp (*argv, "pass", wordlen)) + else if (wordlen >= 2 && !strncmp (arg, "pass", wordlen)) { SET_SIGS (nsigs, sigs, signal_program); } - else if (wordlen >= 3 && !strncmp (*argv, "nostop", wordlen)) + else if (wordlen >= 3 && !strncmp (arg, "nostop", wordlen)) { UNSET_SIGS (nsigs, sigs, signal_stop); } - else if (wordlen >= 3 && !strncmp (*argv, "noignore", wordlen)) + else if (wordlen >= 3 && !strncmp (arg, "noignore", wordlen)) { SET_SIGS (nsigs, sigs, signal_program); } - else if (wordlen >= 4 && !strncmp (*argv, "noprint", wordlen)) + else if (wordlen >= 4 && !strncmp (arg, "noprint", wordlen)) { UNSET_SIGS (nsigs, sigs, signal_print); UNSET_SIGS (nsigs, sigs, signal_stop); } - else if (wordlen >= 4 && !strncmp (*argv, "nopass", wordlen)) + else if (wordlen >= 4 && !strncmp (arg, "nopass", wordlen)) { UNSET_SIGS (nsigs, sigs, signal_program); } @@ -8601,11 +8599,11 @@ handle_command (char *args, int from_tty) SIGHUP, SIGINT, SIGALRM, etc. will work right anyway. */ sigfirst = siglast = (int) - gdb_signal_from_command (atoi (*argv)); - if ((*argv)[digits] == '-') + gdb_signal_from_command (atoi (arg)); + if (arg[digits] == '-') { siglast = (int) - gdb_signal_from_command (atoi ((*argv) + digits + 1)); + gdb_signal_from_command (atoi (arg + digits + 1)); } if (sigfirst > siglast) { @@ -8617,7 +8615,7 @@ handle_command (char *args, int from_tty) } else { - oursig = gdb_signal_from_name (*argv); + oursig = gdb_signal_from_name (arg); if (oursig != GDB_SIGNAL_UNKNOWN) { sigfirst = siglast = (int) oursig; @@ -8625,7 +8623,7 @@ handle_command (char *args, int from_tty) else { /* Not a number and not a recognized flag word => complain. */ - error (_("Unrecognized or ambiguous flag word: \"%s\"."), *argv); + error (_("Unrecognized or ambiguous flag word: \"%s\"."), arg); } } @@ -8663,8 +8661,6 @@ Are you sure you want to change it? "), break; } } - - argv++; } for (signum = 0; signum < nsigs; signum++) @@ -8685,17 +8681,15 @@ Are you sure you want to change it? "), break; } - - do_cleanups (old_chain); } /* Complete the "handle" command. */ -static VEC (char_ptr) * +static void handle_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, const char *text, const char *word) { - VEC (char_ptr) *vec_signals, *vec_keywords, *return_val; static const char * const keywords[] = { "all", @@ -8710,13 +8704,8 @@ handle_completer (struct cmd_list_element *ignore, NULL, }; - vec_signals = signal_completer (ignore, text, word); - vec_keywords = complete_on_enum (keywords, word, word); - - return_val = VEC_merge (char_ptr, vec_signals, vec_keywords); - VEC_free (char_ptr, vec_signals); - VEC_free (char_ptr, vec_keywords); - return return_val; + signal_completer (ignore, tracker, text, word); + complete_on_enum (tracker, keywords, word, word); } enum gdb_signal diff --git a/gdb/interps.c b/gdb/interps.c index af86390..1e59034 100644 --- a/gdb/interps.c +++ b/gdb/interps.c @@ -407,21 +407,14 @@ interpreter_exec_cmd (char *args, int from_tty) { struct ui_interp_info *ui_interp = get_current_interp_info (); struct interp *old_interp, *interp_to_use; - char **prules = NULL; - char **trule = NULL; unsigned int nrules; unsigned int i; - struct cleanup *cleanup; if (args == NULL) error_no_arg (_("interpreter-exec command")); - prules = gdb_buildargv (args); - cleanup = make_cleanup_freeargv (prules); - - nrules = 0; - for (trule = prules; *trule != NULL; trule++) - nrules++; + gdb_argv prules (args); + nrules = prules.count (); if (nrules < 2) error (_("usage: interpreter-exec <interpreter> [ <command> ... ]")); @@ -446,19 +439,17 @@ interpreter_exec_cmd (char *args, int from_tty) } interp_set (old_interp, 0); - - do_cleanups (cleanup); } /* See interps.h. */ -VEC (char_ptr) * +void interpreter_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, const char *text, const char *word) { struct interp_factory *interp; int textlen; - VEC (char_ptr) *matches = NULL; int ix; textlen = strlen (text); @@ -485,11 +476,9 @@ interpreter_completer (struct cmd_list_element *ignore, match[text - word] = '\0'; strcat (match, interp->name); } - VEC_safe_push (char_ptr, matches, match); + tracker.add_completion (gdb::unique_xmalloc_ptr<char> (match)); } } - - return matches; } struct interp * diff --git a/gdb/interps.h b/gdb/interps.h index 1b9580c..b20cf5c 100644 --- a/gdb/interps.h +++ b/gdb/interps.h @@ -138,9 +138,10 @@ extern void interp_pre_command_loop (struct interp *interp); /* List the possible interpreters which could complete the given text. */ -extern VEC (char_ptr) *interpreter_completer (struct cmd_list_element *ignore, - const char *text, - const char *word); +extern void interpreter_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, + const char *text, + const char *word); /* well-known interpreters */ #define INTERP_CONSOLE "console" @@ -211,29 +211,20 @@ jit_reader_load (const char *file_name) static void jit_reader_load_command (char *args, int from_tty) { - char *so_name; - struct cleanup *prev_cleanup; - if (args == NULL) error (_("No reader name provided.")); - args = tilde_expand (args); - prev_cleanup = make_cleanup (xfree, args); + gdb::unique_xmalloc_ptr<char> file (tilde_expand (args)); if (loaded_jit_reader != NULL) error (_("JIT reader already loaded. Run jit-reader-unload first.")); - if (IS_ABSOLUTE_PATH (args)) - so_name = args; - else - { - so_name = xstrprintf ("%s%s%s", jit_reader_dir, SLASH_STRING, args); - make_cleanup (xfree, so_name); - } + if (!IS_ABSOLUTE_PATH (file.get ())) + file.reset (xstrprintf ("%s%s%s", jit_reader_dir, SLASH_STRING, + file.get ())); - loaded_jit_reader = jit_reader_load (so_name); + loaded_jit_reader = jit_reader_load (file.get ()); reinit_frame_cache (); jit_inferior_created_hook (); - do_cleanups (prev_cleanup); } /* Provides the jit-reader-unload command. */ diff --git a/gdb/language.c b/gdb/language.c index 844ed7e..2cce56b 100644 --- a/gdb/language.c +++ b/gdb/language.c @@ -45,6 +45,7 @@ #include "frame.h" #include "c-lang.h" #include "dictionary.h" /* for dict_hash */ +#include <algorithm> extern void _initialize_language (void); @@ -92,12 +93,26 @@ enum language_mode language_mode = language_mode_auto; const struct language_defn *expected_language; -/* The list of supported languages. The list itself is malloc'd. */ - -static const struct language_defn **languages; -static unsigned languages_size; -static unsigned languages_allocsize; -#define DEFAULT_ALLOCSIZE 4 +/* The list of supported languages. Keep this in the same order as + the 'enum language' values. */ + +static const struct language_defn *languages[] = { + &unknown_language_defn, + &auto_language_defn, + &c_language_defn, + &objc_language_defn, + &cplus_language_defn, + &d_language_defn, + &go_language_defn, + &f_language_defn, + &m2_language_defn, + &asm_language_defn, + &pascal_language_defn, + &opencl_language_defn, + &rust_language_defn, + &minimal_language_defn, + &ada_language_defn, +}; /* The current values of the "set language/type/range" enum commands. */ @@ -149,16 +164,19 @@ show_language_command (struct ui_file *file, int from_tty, static void set_language_command (char *ignore, int from_tty, struct cmd_list_element *c) { - int i; enum language flang = language_unknown; + /* "local" is a synonym of "auto". */ + if (strcmp (language, "local") == 0) + language = "auto"; + /* Search the list of languages for a match. */ - for (i = 0; i < languages_size; i++) + for (const auto &lang : languages) { - if (strcmp (languages[i]->la_name, language) == 0) + if (strcmp (lang->la_name, language) == 0) { /* Found it! Go into manual mode, and use this language. */ - if (languages[i]->la_language == language_auto) + if (lang->la_language == language_auto) { /* Enter auto mode. Set to the current frame's language, if known, or fallback to the initial language. */ @@ -187,7 +205,7 @@ set_language_command (char *ignore, int from_tty, struct cmd_list_element *c) { /* Enter manual mode. Set the specified language. */ language_mode = language_mode_manual; - current_language = languages[i]; + current_language = lang; set_range_case (); expected_language = current_language; return; @@ -365,21 +383,11 @@ set_range_case (void) enum language set_language (enum language lang) { - int i; enum language prev_language; prev_language = current_language->la_language; - - for (i = 0; i < languages_size; i++) - { - if (languages[i]->la_language == lang) - { - current_language = languages[i]; - set_range_case (); - break; - } - } - + current_language = languages[lang]; + set_range_case (); return prev_language; } @@ -475,11 +483,12 @@ range_error (const char *string,...) enum language language_enum (char *str) { - int i; + for (const auto &lang : languages) + if (strcmp (lang->la_name, str) == 0) + return lang->la_language; - for (i = 0; i < languages_size; i++) - if (strcmp (languages[i]->la_name, str) == 0) - return languages[i]->la_language; + if (strcmp (str, "local") == 0) + return language_auto; return language_unknown; } @@ -489,32 +498,15 @@ language_enum (char *str) const struct language_defn * language_def (enum language lang) { - int i; - - for (i = 0; i < languages_size; i++) - { - if (languages[i]->la_language == lang) - { - return languages[i]; - } - } - return NULL; + return languages[lang]; } /* Return the language as a string. */ + const char * language_str (enum language lang) { - int i; - - for (i = 0; i < languages_size; i++) - { - if (languages[i]->la_language == lang) - { - return languages[i]->la_name; - } - } - return "Unknown"; + return languages[lang]->la_name; } static void @@ -531,55 +523,45 @@ show_check (char *ignore, int from_tty) cmd_show_list (showchecklist, from_tty, ""); } -/* Add a language to the set of known languages. */ -void -add_language (const struct language_defn *lang) -{ - /* For the "set language" command. */ - static const char **language_names = NULL; - /* For the "help set language" command. */ +/* Build and install the "set language LANG" command. */ - if (lang->la_magic != LANG_MAGIC) - { - fprintf_unfiltered (gdb_stderr, - "Magic number of %s language struct wrong\n", - lang->la_name); - internal_error (__FILE__, __LINE__, - _("failed internal consistency check")); - } +static void +add_set_language_command () +{ + static const char **language_names; - if (!languages) - { - languages_allocsize = DEFAULT_ALLOCSIZE; - languages = XNEWVEC (const struct language_defn *, languages_allocsize); - } - if (languages_size >= languages_allocsize) + /* Build the language names array, to be used as enumeration in the + "set language" enum command. +1 for "local" and +1 for NULL + termination. */ + language_names = new const char *[ARRAY_SIZE (languages) + 2]; + + /* Display "auto", "local" and "unknown" first, and then the rest, + alpha sorted. */ + const char **language_names_p = language_names; + *language_names_p++ = auto_language_defn.la_name; + *language_names_p++ = "local"; + *language_names_p++ = unknown_language_defn.la_name; + const char **sort_begin = language_names_p; + for (const auto &lang : languages) { - languages_allocsize *= 2; - languages = (const struct language_defn **) xrealloc ((char *) languages, - languages_allocsize * sizeof (*languages)); + /* Already handled above. */ + if (lang->la_language == language_auto + || lang->la_language == language_unknown) + continue; + *language_names_p++ = lang->la_name; } - languages[languages_size++] = lang; - - /* Build the language names array, to be used as enumeration in the - set language" enum command. */ - language_names = XRESIZEVEC (const char *, language_names, - languages_size + 1); - - for (int i = 0; i < languages_size; ++i) - language_names[i] = languages[i]->la_name; - language_names[languages_size] = NULL; + *language_names_p = NULL; + std::sort (sort_begin, language_names_p, compare_cstrings); /* Add the filename extensions. */ - if (lang->la_filename_extensions != NULL) - { - int i; - - for (i = 0; lang->la_filename_extensions[i] != NULL; ++i) - add_filename_language (lang->la_filename_extensions[i], - lang->la_language); - } + for (const auto &lang : languages) + if (lang->la_filename_extensions != NULL) + { + for (size_t i = 0; lang->la_filename_extensions[i] != NULL; ++i) + add_filename_language (lang->la_filename_extensions[i], + lang->la_language); + } /* Build the "help set language" docs. */ string_file doc; @@ -588,24 +570,24 @@ add_language (const struct language_defn *lang) "The currently understood settings are:\n\nlocal or " "auto Automatic setting based on source file\n")); - for (int i = 0; i < languages_size; ++i) + for (const auto &lang : languages) { /* Already dealt with these above. */ - if (languages[i]->la_language == language_unknown - || languages[i]->la_language == language_auto) + if (lang->la_language == language_unknown + || lang->la_language == language_auto) continue; /* FIXME: i18n: for now assume that the human-readable name is just a capitalization of the internal name. */ doc.printf ("%-16s Use the %c%s language\n", - languages[i]->la_name, + lang->la_name, /* Capitalize first letter of language name. */ - toupper (languages[i]->la_name[0]), - languages[i]->la_name + 1); + toupper (lang->la_name[0]), + lang->la_name + 1); } add_setshow_enum_cmd ("language", class_support, - (const char **) language_names, + language_names, &language, doc.c_str (), _("Show the current source language."), @@ -621,13 +603,11 @@ add_language (const struct language_defn *lang) CORE_ADDR skip_language_trampoline (struct frame_info *frame, CORE_ADDR pc) { - int i; - - for (i = 0; i < languages_size; i++) + for (const auto &lang : languages) { - if (languages[i]->skip_trampoline) + if (lang->skip_trampoline != NULL) { - CORE_ADDR real_pc = (languages[i]->skip_trampoline) (frame, pc); + CORE_ADDR real_pc = lang->skip_trampoline (frame, pc); if (real_pc) return real_pc; @@ -864,7 +844,7 @@ const struct language_defn unknown_language_defn = 1, /* c-style arrays */ 0, /* String lower bound */ default_word_break_characters, - default_make_symbol_completion_list, + default_collect_symbol_completion_matches, unknown_language_arch_info, /* la_language_arch_info. */ default_print_array_index, default_pass_by_reference, @@ -915,7 +895,7 @@ const struct language_defn auto_language_defn = 1, /* c-style arrays */ 0, /* String lower bound */ default_word_break_characters, - default_make_symbol_completion_list, + default_collect_symbol_completion_matches, unknown_language_arch_info, /* la_language_arch_info. */ default_print_array_index, default_pass_by_reference, @@ -930,54 +910,6 @@ const struct language_defn auto_language_defn = LANG_MAGIC }; -const struct language_defn local_language_defn = -{ - "local", - "Local", - language_auto, - range_check_off, - case_sensitive_on, - array_row_major, - macro_expansion_no, - NULL, - &exp_descriptor_standard, - unk_lang_parser, - unk_lang_error, - null_post_parser, - unk_lang_printchar, /* Print character constant */ - unk_lang_printstr, - unk_lang_emit_char, - unk_lang_print_type, /* Print a type using appropriate syntax */ - default_print_typedef, /* Print a typedef using appropriate syntax */ - unk_lang_val_print, /* Print a value using appropriate syntax */ - unk_lang_value_print, /* Print a top-level value */ - default_read_var_value, /* la_read_var_value */ - unk_lang_trampoline, /* Language specific skip_trampoline */ - "this", /* name_of_this */ - basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ - basic_lookup_transparent_type,/* lookup_transparent_type */ - unk_lang_demangle, /* Language specific symbol demangler */ - NULL, - unk_lang_class_name, /* Language specific - class_name_from_physname */ - unk_op_print_tab, /* expression operators for printing */ - 1, /* c-style arrays */ - 0, /* String lower bound */ - default_word_break_characters, - default_make_symbol_completion_list, - unknown_language_arch_info, /* la_language_arch_info. */ - default_print_array_index, - default_pass_by_reference, - default_get_string, - c_watch_location_expression, - NULL, /* la_get_symbol_name_cmp */ - iterate_over_symbols, - default_compute_string_hash, - &default_varobj_ops, - NULL, - NULL, - LANG_MAGIC -}; /* Per-architecture language information. */ @@ -994,16 +926,15 @@ static void * language_gdbarch_post_init (struct gdbarch *gdbarch) { struct language_gdbarch *l; - int i; l = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct language_gdbarch); - for (i = 0; i < languages_size; i++) - { - if (languages[i] != NULL - && languages[i]->la_language_arch_info != NULL) - languages[i]->la_language_arch_info - (gdbarch, l->arch_info + languages[i]->la_language); - } + for (const auto &lang : languages) + if (lang != NULL && lang->la_language_arch_info != NULL) + { + lang->la_language_arch_info (gdbarch, + l->arch_info + lang->la_language); + } + return l; } @@ -1217,9 +1148,7 @@ For Fortran the default is off; for other languages the default is on."), show_case_command, &setlist, &showlist); - add_language (&auto_language_defn); - add_language (&local_language_defn); - add_language (&unknown_language_defn); + add_set_language_command (); language = xstrdup ("auto"); type = xstrdup ("auto"); diff --git a/gdb/language.h b/gdb/language.h index 7aab52c..d7857f3 100644 --- a/gdb/language.h +++ b/gdb/language.h @@ -138,7 +138,7 @@ struct language_arch_info transformed for lookup. */ typedef int (*symbol_name_cmp_ftype) (const char *symbol_search_name, - const char *lookup_name); + const char *lookup_name); /* Structure tying together assorted information about a language. */ @@ -327,14 +327,17 @@ struct language_defn /* The list of characters forming word boundaries. */ const char *(*la_word_break_characters) (void); - /* Should return a vector of all symbols which are possible + /* Add to the completion tracker all symbols which are possible completions for TEXT. WORD is the entire command on which the completion is being made. If CODE is TYPE_CODE_UNDEF, then all symbols should be examined; otherwise, only STRUCT_DOMAIN symbols whose type has a code of CODE should be matched. */ - VEC (char_ptr) *(*la_make_symbol_completion_list) (const char *text, - const char *word, - enum type_code code); + void (*la_collect_symbol_completion_matches) + (completion_tracker &tracker, + complete_symbol_mode mode, + const char *text, + const char *word, + enum type_code code); /* The per-architecture (OS/ABI) language information. */ void (*la_language_arch_info) (struct gdbarch *, @@ -573,10 +576,6 @@ extern const struct language_defn *language_def (enum language); extern const char *language_str (enum language); -/* Add a language to the set known by GDB (at initialization time). */ - -extern void add_language (const struct language_defn *); - /* Check for a language-specific trampoline. */ extern CORE_ADDR skip_language_trampoline (struct frame_info *, CORE_ADDR pc); @@ -627,4 +626,49 @@ extern unsigned int default_compute_string_hash (const char *string); void c_get_string (struct value *value, gdb_byte **buffer, int *length, struct type **char_type, const char **charset); +/* The languages supported by GDB. */ + +extern const struct language_defn auto_language_defn; +extern const struct language_defn unknown_language_defn; +extern const struct language_defn minimal_language_defn; + +extern const struct language_defn ada_language_defn; +extern const struct language_defn asm_language_defn; +extern const struct language_defn c_language_defn; +extern const struct language_defn cplus_language_defn; +extern const struct language_defn d_language_defn; +extern const struct language_defn f_language_defn; +extern const struct language_defn go_language_defn; +extern const struct language_defn m2_language_defn; +extern const struct language_defn objc_language_defn; +extern const struct language_defn opencl_language_defn; +extern const struct language_defn pascal_language_defn; +extern const struct language_defn rust_language_defn; + +/* Save the current language and restore it upon destruction. */ + +class scoped_restore_current_language +{ +public: + + explicit scoped_restore_current_language () + : m_lang (current_language->la_language) + { + } + + ~scoped_restore_current_language () + { + set_language (m_lang); + } + + scoped_restore_current_language (const scoped_restore_current_language &) + = delete; + scoped_restore_current_language &operator= + (const scoped_restore_current_language &) = delete; + +private: + + enum language m_lang; +}; + #endif /* defined (LANGUAGE_H) */ diff --git a/gdb/linespec.c b/gdb/linespec.c index 8077706..cd440bf 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -46,6 +46,38 @@ #include "location.h" #include "common/function-view.h" +/* An enumeration of the various things a user might attempt to + complete for a linespec location. */ + +enum class linespec_complete_what +{ + /* Nothing, no possible completion. */ + NOTHING, + + /* A function/method name. Due to ambiguity between + + (gdb) b source[TAB] + source_file.c + source_function + + this can also indicate a source filename, iff we haven't seen a + separate source filename component, as in "b source.c:function". */ + FUNCTION, + + /* A label symbol. E.g., break file.c:function:LABEL. */ + LABEL, + + /* An expression. E.g., "break foo if EXPR", or "break *EXPR". */ + EXPRESSION, + + /* A linespec keyword ("if"/"thread"/"task"). + E.g., "break func threa<tab>". */ + KEYWORD, +}; + +typedef struct symbol *symbolp; +DEF_VEC_P (symbolp); + typedef struct type *typep; DEF_VEC_P (typep); @@ -205,9 +237,9 @@ enum ls_token_type }; typedef enum ls_token_type linespec_token_type; -/* List of keywords */ - -static const char * const linespec_keywords[] = { "if", "thread", "task" }; +/* List of keywords. This is NULL-terminated so that it can be used + as enum completer. */ +const char * const linespec_keywords[] = { "if", "thread", "task", NULL }; #define IF_KEYWORD_INDEX 0 /* A token of the linespec lexer */ @@ -260,6 +292,29 @@ struct ls_parser /* The result of the parse. */ struct linespec result; #define PARSER_RESULT(PPTR) (&(PPTR)->result) + + /* What the parser believes the current word point should complete + to. */ + linespec_complete_what complete_what; + + /* The completion word point. The parser advances this as it skips + tokens. At some point the input string will end or parsing will + fail, and then we attempt completion at the captured completion + word point, interpreting the string at completion_word as + COMPLETE_WHAT. */ + const char *completion_word; + + /* If the current token was a quoted string, then this is the + quoting character (either " or '). */ + int completion_quote_char; + + /* If the current token was a quoted string, then this points at the + end of the quoted string. */ + const char *completion_quote_end; + + /* If parsing for completion, then this points at the completion + tracker. Otherwise, this is NULL. */ + struct completion_tracker *completion_tracker; }; typedef struct ls_parser linespec_parser; @@ -289,7 +344,8 @@ static VEC (block_symbol_d) *find_label_symbols (struct linespec_state *self, VEC (block_symbol_d) *function_symbols, VEC (block_symbol_d) **label_funcs_ret, - const char *name); + const char *name, + bool completion_mode = false); static void find_linespec_symbols (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs, @@ -392,7 +448,7 @@ linespec_lexer_lex_keyword (const char *p) if (p != NULL) { - for (i = 0; i < ARRAY_SIZE (linespec_keywords); ++i) + for (i = 0; linespec_keywords[i] != NULL; ++i) { int len = strlen (linespec_keywords[i]); @@ -413,7 +469,7 @@ linespec_lexer_lex_keyword (const char *p) { p += len; p = skip_spaces_const (p); - for (j = 0; j < ARRAY_SIZE (linespec_keywords); ++j) + for (j = 0; linespec_keywords[j] != NULL; ++j) { int nextlen = strlen (linespec_keywords[j]); @@ -534,6 +590,30 @@ find_parameter_list_end (const char *input) return p; } +/* If the [STRING, STRING_LEN) string ends with what looks like a + keyword, return the keyword start offset in STRING. Return -1 + otherwise. */ + +static size_t +string_find_incomplete_keyword_at_end (const char * const *keywords, + const char *string, size_t string_len) +{ + const char *end = string + string_len; + const char *p = end; + + while (p > string && *p != ' ') + --p; + if (p > string) + { + p++; + size_t len = end - p; + for (size_t i = 0; keywords[i] != NULL; ++i) + if (strncmp (keywords[i], p, len) == 0) + return p - string; + } + + return -1; +} /* Lex a string from the input in PARSER. */ @@ -581,13 +661,31 @@ linespec_lexer_lex_string (linespec_parser *parser) /* Skip to the ending quote. */ end = skip_quote_char (PARSER_STREAM (parser), quote_char); - /* Error if the input did not terminate properly. */ - if (end == NULL) - error (_("unmatched quote")); + /* This helps the completer mode decide whether we have a + complete string. */ + parser->completion_quote_char = quote_char; + parser->completion_quote_end = end; - /* Skip over the ending quote and mark the length of the string. */ - PARSER_STREAM (parser) = (char *) ++end; - LS_TOKEN_STOKEN (token).length = PARSER_STREAM (parser) - 2 - start; + /* Error if the input did not terminate properly, unless in + completion mode. */ + if (end == NULL) + { + if (parser->completion_tracker == NULL) + error (_("unmatched quote")); + + /* In completion mode, we'll try to complete the incomplete + token. */ + token.type = LSTOKEN_STRING; + while (*PARSER_STREAM (parser) != '\0') + PARSER_STREAM (parser)++; + LS_TOKEN_STOKEN (token).length = PARSER_STREAM (parser) - 1 - start; + } + else + { + /* Skip over the ending quote and mark the length of the string. */ + PARSER_STREAM (parser) = (char *) ++end; + LS_TOKEN_STOKEN (token).length = PARSER_STREAM (parser) - 2 - start; + } } else { @@ -665,14 +763,50 @@ linespec_lexer_lex_string (linespec_parser *parser) else if (*PARSER_STREAM (parser) == '<' || *PARSER_STREAM (parser) == '(') { - const char *p; + /* Don't interpret 'operator<' / 'operator<<' as a + template parameter list though. */ + if (*PARSER_STREAM (parser) == '<' + && (PARSER_STATE (parser)->language->la_language + == language_cplus) + && (PARSER_STREAM (parser) - start) >= CP_OPERATOR_LEN) + { + const char *p = PARSER_STREAM (parser); - p = find_parameter_list_end (PARSER_STREAM (parser)); - if (p != NULL) + while (p > start && isspace (p[-1])) + p--; + if (p - start >= CP_OPERATOR_LEN) + { + p -= CP_OPERATOR_LEN; + if (strncmp (p, CP_OPERATOR_STR, CP_OPERATOR_LEN) == 0 + && (p == start + || !(isalnum (p[-1]) || p[-1] == '_'))) + { + /* This is an operator name. Keep going. */ + ++(PARSER_STREAM (parser)); + if (*PARSER_STREAM (parser) == '<') + ++(PARSER_STREAM (parser)); + continue; + } + } + } + + const char *p = find_parameter_list_end (PARSER_STREAM (parser)); + PARSER_STREAM (parser) = p; + + /* Don't loop around to the normal \0 case above because + we don't want to misinterpret a potential keyword at + the end of the token when the string isn't + "()<>"-balanced. This handles "b + function(thread<tab>" in completion mode. */ + if (*p == '\0') { - PARSER_STREAM (parser) = p; - continue; + LS_TOKEN_STOKEN (token).ptr = start; + LS_TOKEN_STOKEN (token).length + = PARSER_STREAM (parser) - start; + return token; } + else + continue; } /* Commas are terminators, but not if they are part of an operator name. */ @@ -680,10 +814,9 @@ linespec_lexer_lex_string (linespec_parser *parser) { if ((PARSER_STATE (parser)->language->la_language == language_cplus) - && (PARSER_STREAM (parser) - start) > 8 - /* strlen ("operator") */) + && (PARSER_STREAM (parser) - start) > CP_OPERATOR_LEN) { - const char *p = strstr (start, "operator"); + const char *p = strstr (start, CP_OPERATOR_STR); if (p != NULL && is_operator_name (p)) { @@ -791,13 +924,48 @@ linespec_lexer_lex_one (linespec_parser *parser) } /* Consume the current token and return the next token in PARSER's - input stream. */ + input stream. Also advance the completion word for completion + mode. */ static linespec_token linespec_lexer_consume_token (linespec_parser *parser) { + gdb_assert (parser->lexer.current.type != LSTOKEN_EOI); + + bool advance_word = (parser->lexer.current.type != LSTOKEN_STRING + || *PARSER_STREAM (parser) != '\0'); + + /* If we're moving past a string to some other token, it must be the + quote was terminated. */ + if (parser->completion_quote_char) + { + gdb_assert (parser->lexer.current.type == LSTOKEN_STRING); + + /* If the string was the last (non-EOI) token, we're past the + quote, but remember that for later. */ + if (*PARSER_STREAM (parser) != '\0') + { + parser->completion_quote_char = '\0'; + parser->completion_quote_end = NULL;; + } + } + parser->lexer.current.type = LSTOKEN_CONSUMED; - return linespec_lexer_lex_one (parser); + linespec_lexer_lex_one (parser); + + if (parser->lexer.current.type == LSTOKEN_STRING) + { + /* Advance the completion word past a potential initial + quote-char. */ + parser->completion_word = LS_TOKEN_STOKEN (parser->lexer.current).ptr; + } + else if (advance_word) + { + /* Advance the completion word past any whitespace. */ + parser->completion_word = PARSER_STREAM (parser); + } + + return parser->lexer.current; } /* Return the next token without consuming the current token. */ @@ -808,10 +976,16 @@ linespec_lexer_peek_token (linespec_parser *parser) linespec_token next; const char *saved_stream = PARSER_STREAM (parser); linespec_token saved_token = parser->lexer.current; + int saved_completion_quote_char = parser->completion_quote_char; + const char *saved_completion_quote_end = parser->completion_quote_end; + const char *saved_completion_word = parser->completion_word; next = linespec_lexer_consume_token (parser); PARSER_STREAM (parser) = saved_stream; parser->lexer.current = saved_token; + parser->completion_quote_char = saved_completion_quote_char; + parser->completion_quote_end = saved_completion_quote_end; + parser->completion_word = saved_completion_word; return next; } @@ -1448,6 +1622,17 @@ source_file_not_found_error (const char *name) throw_error (NOT_FOUND_ERROR, _("No source file named %s."), name); } +/* Unless at EIO, save the current stream position as completion word + point, and consume the next token. */ + +static linespec_token +save_stream_and_consume_token (linespec_parser *parser) +{ + if (linespec_lexer_peek_token (parser).type != LSTOKEN_EOI) + parser->completion_word = PARSER_STREAM (parser); + return linespec_lexer_consume_token (parser); +} + /* See description in linespec.h. */ struct line_offset @@ -1475,6 +1660,26 @@ linespec_parse_line_offset (const char *string) return line_offset; } +/* In completion mode, if the user is still typing the number, there's + no possible completion to offer. But if there's already input past + the number, setup to expect NEXT. */ + +static void +set_completion_after_number (linespec_parser *parser, + linespec_complete_what next) +{ + if (*PARSER_STREAM (parser) == ' ') + { + parser->completion_word = skip_spaces_const (PARSER_STREAM (parser) + 1); + parser->complete_what = next; + } + else + { + parser->completion_word = PARSER_STREAM (parser); + parser->complete_what = linespec_complete_what::NOTHING; + } +} + /* Parse the basic_spec in PARSER's input. */ static void @@ -1490,11 +1695,20 @@ linespec_parse_basic (linespec_parser *parser) token = linespec_lexer_lex_one (parser); /* If it is EOI or KEYWORD, issue an error. */ - if (token.type == LSTOKEN_KEYWORD || token.type == LSTOKEN_EOI) - unexpected_linespec_error (parser); + if (token.type == LSTOKEN_KEYWORD) + { + parser->complete_what = linespec_complete_what::NOTHING; + unexpected_linespec_error (parser); + } + else if (token.type == LSTOKEN_EOI) + { + unexpected_linespec_error (parser); + } /* If it is a LSTOKEN_NUMBER, we have an offset. */ else if (token.type == LSTOKEN_NUMBER) { + set_completion_after_number (parser, linespec_complete_what::KEYWORD); + /* Record the line offset and get the next token. */ name = copy_token_string (token); cleanup = make_cleanup (xfree, name); @@ -1506,7 +1720,10 @@ linespec_parse_basic (linespec_parser *parser) /* If the next token is a comma, stop parsing and return. */ if (token.type == LSTOKEN_COMMA) - return; + { + parser->complete_what = linespec_complete_what::NOTHING; + return; + } /* If the next token is anything but EOI or KEYWORD, issue an error. */ @@ -1519,12 +1736,58 @@ linespec_parse_basic (linespec_parser *parser) /* Next token must be LSTOKEN_STRING. */ if (token.type != LSTOKEN_STRING) - unexpected_linespec_error (parser); + { + parser->complete_what = linespec_complete_what::NOTHING; + unexpected_linespec_error (parser); + } /* The current token will contain the name of a function, method, or label. */ - name = copy_token_string (token); - cleanup = make_cleanup (xfree, name); + name = copy_token_string (token); + cleanup = make_cleanup (free_current_contents, &name); + + if (parser->completion_tracker != NULL) + { + /* If the function name ends with a ":", then this may be an + incomplete "::" scope operator instead of a label separator. + E.g., + "b klass:<tab>" + which should expand to: + "b klass::method()" + + Do a tentative completion assuming the later. If we find + completions, advance the stream past the colon token and make + it part of the function name/token. */ + + if (!parser->completion_quote_char + && strcmp (PARSER_STREAM (parser), ":") == 0) + { + completion_tracker tmp_tracker; + const char *source_filename + = PARSER_EXPLICIT (parser)->source_filename; + + linespec_complete_function (tmp_tracker, + parser->completion_word, + source_filename); + + if (tmp_tracker.have_completions ()) + { + PARSER_STREAM (parser)++; + LS_TOKEN_STOKEN (token).length++; + + xfree (name); + name = savestring (parser->completion_word, + (PARSER_STREAM (parser) + - parser->completion_word)); + } + } + + PARSER_EXPLICIT (parser)->function_name = name; + discard_cleanups (cleanup); + } + else + { + /* XXX Reindent before pushing. */ /* Try looking it up as a function/method. */ find_linespec_symbols (PARSER_STATE (parser), @@ -1584,11 +1847,19 @@ linespec_parse_basic (linespec_parser *parser) return; } } + } + + int previous_qc = parser->completion_quote_char; /* Get the next token. */ token = linespec_lexer_consume_token (parser); - if (token.type == LSTOKEN_COLON) + if (token.type == LSTOKEN_EOI) + { + if (previous_qc && !parser->completion_quote_char) + parser->complete_what = linespec_complete_what::KEYWORD; + } + else if (token.type == LSTOKEN_COLON) { /* User specified a label or a lineno. */ token = linespec_lexer_consume_token (parser); @@ -1597,17 +1868,56 @@ linespec_parse_basic (linespec_parser *parser) { /* User specified an offset. Record the line offset and get the next token. */ + set_completion_after_number (parser, linespec_complete_what::KEYWORD); + name = copy_token_string (token); cleanup = make_cleanup (xfree, name); PARSER_EXPLICIT (parser)->line_offset = linespec_parse_line_offset (name); do_cleanups (cleanup); - /* Ge the next token. */ + /* Get the next token. */ token = linespec_lexer_consume_token (parser); } + else if (token.type == LSTOKEN_EOI && parser->completion_tracker != NULL) + { + parser->complete_what = linespec_complete_what::LABEL; + } else if (token.type == LSTOKEN_STRING) { + parser->complete_what = linespec_complete_what::LABEL; + + /* If we have text after the label separated by whitespace + (e.g., "b func():lab i<tab>"), don't consider it part of + the label. In completion mode that should complete to + "if", in normal mode, the 'i' should be treated as + garbage. */ + if (parser->completion_quote_char == '\0') + { + const char *ptr = LS_TOKEN_STOKEN (token).ptr; + for (size_t i = 0; i < LS_TOKEN_STOKEN (token).length; i++) + { + if (ptr[i] == ' ') + { + LS_TOKEN_STOKEN (token).length = i; + PARSER_STREAM (parser) = skip_spaces_const (ptr + i + 1); + break; + } + } + } + + if (parser->completion_tracker != NULL) + { + if (PARSER_STREAM (parser)[-1] == ' ') + { + parser->completion_word = PARSER_STREAM (parser); + parser->complete_what = linespec_complete_what::KEYWORD; + } + } + else + { + /* XXX Reindent before pushing. */ + /* Grab a copy of the label's name and look it up. */ name = copy_token_string (token); cleanup = make_cleanup (xfree, name); @@ -1630,8 +1940,10 @@ linespec_parse_basic (linespec_parser *parser) name); } + } + /* Check for a line offset. */ - token = linespec_lexer_consume_token (parser); + token = save_stream_and_consume_token (parser); if (token.type == LSTOKEN_COLON) { /* Get the next token. */ @@ -1641,7 +1953,7 @@ linespec_parse_basic (linespec_parser *parser) if (token.type != LSTOKEN_NUMBER) unexpected_linespec_error (parser); - /* Record the lione offset and get the next token. */ + /* Record the line offset and get the next token. */ name = copy_token_string (token); cleanup = make_cleanup (xfree, name); @@ -1989,32 +2301,34 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) return sals; } -/* Convert the explicit location EXPLICIT_LOC into SaLs. */ +/* Build RESULT from the explicit location components SOURCE_FILENAME, + FUNCTION_NAME, LABEL_NAME and LINE_OFFSET. */ -static struct symtabs_and_lines -convert_explicit_location_to_sals (struct linespec_state *self, - linespec_p result, - const struct explicit_location *explicit_loc) +static void +convert_explicit_location_to_linespec (struct linespec_state *self, + linespec_p result, + const char *source_filename, + const char *function_name, + const char *label_name, + struct line_offset line_offset) { VEC (block_symbol_d) *labels; VEC (block_symbol_d) *symbols; VEC (bound_minimal_symbol_d) *minimal_symbols; - if (explicit_loc->source_filename != NULL) + if (source_filename != NULL) { TRY { result->file_symtabs - = symtabs_from_filename (explicit_loc->source_filename, - self->search_pspace); + = symtabs_from_filename (source_filename, self->search_pspace); } CATCH (except, RETURN_MASK_ERROR) { - source_file_not_found_error (explicit_loc->source_filename); + source_file_not_found_error (source_filename); } END_CATCH - result->explicit_loc.source_filename - = xstrdup (explicit_loc->source_filename); + result->explicit_loc.source_filename = xstrdup (source_filename); } else { @@ -2022,41 +2336,53 @@ convert_explicit_location_to_sals (struct linespec_state *self, VEC_safe_push (symtab_ptr, result->file_symtabs, NULL); } - if (explicit_loc->function_name != NULL) + if (function_name != NULL) { find_linespec_symbols (self, result->file_symtabs, - explicit_loc->function_name, &symbols, + function_name, &symbols, &minimal_symbols); if (symbols == NULL && minimal_symbols == NULL) - symbol_not_found_error (explicit_loc->function_name, + symbol_not_found_error (function_name, result->explicit_loc.source_filename); - result->explicit_loc.function_name - = xstrdup (explicit_loc->function_name); + result->explicit_loc.function_name = xstrdup (function_name); result->function_symbols = symbols; result->minimal_symbols = minimal_symbols; } - if (explicit_loc->label_name != NULL) + if (label_name != NULL) { symbols = NULL; labels = find_label_symbols (self, result->function_symbols, - &symbols, explicit_loc->label_name); + &symbols, label_name); if (labels == NULL) undefined_label_error (result->explicit_loc.function_name, - explicit_loc->label_name); + label_name); - result->explicit_loc.label_name = xstrdup (explicit_loc->label_name); + result->explicit_loc.label_name = xstrdup (label_name); result->labels.label_symbols = labels; result->labels.function_symbols = symbols; } - if (explicit_loc->line_offset.sign != LINE_OFFSET_UNKNOWN) - result->explicit_loc.line_offset = explicit_loc->line_offset; + if (line_offset.sign != LINE_OFFSET_UNKNOWN) + result->explicit_loc.line_offset = line_offset; +} + +/* Convert the explicit location EXPLICIT_LOC into SaLs. */ - return convert_linespec_to_sals (self, result); +static struct symtabs_and_lines +convert_explicit_location_to_sals (struct linespec_state *self, + linespec_p result, + const struct explicit_location *explicit_loc) +{ + convert_explicit_location_to_linespec (self, result, + explicit_loc->source_filename, + explicit_loc->function_name, + explicit_loc->label_name, + explicit_loc->line_offset); + return convert_linespec_to_sals (self, result); } /* Parse a string that specifies a linespec. @@ -2117,11 +2443,15 @@ parse_linespec (linespec_parser *parser, const char *arg) struct gdb_exception file_exception = exception_none; struct cleanup *cleanup; + values.nelts = 0; + values.sals = NULL; + /* A special case to start. It has become quite popular for IDEs to work around bugs in the previous parser by quoting the entire linespec, so we attempt to deal with this nicely. */ parser->is_quote_enclosed = 0; - if (!is_ada_operator (arg) + if (parser->completion_tracker == NULL + && !is_ada_operator (arg) && strchr (linespec_quote_characters, *arg) != NULL) { const char *end; @@ -2138,20 +2468,34 @@ parse_linespec (linespec_parser *parser, const char *arg) parser->lexer.saved_arg = arg; parser->lexer.stream = arg; + parser->completion_word = arg; + parser->complete_what = linespec_complete_what::FUNCTION; /* Initialize the default symtab and line offset. */ initialize_defaults (&PARSER_STATE (parser)->default_symtab, &PARSER_STATE (parser)->default_line); /* Objective-C shortcut. */ - values = decode_objc (PARSER_STATE (parser), PARSER_RESULT (parser), arg); - if (values.sals != NULL) - return values; + if (parser->completion_tracker == NULL) + { + values = decode_objc (PARSER_STATE (parser), PARSER_RESULT (parser), arg); + if (values.sals != NULL) + return values; + } + else + { + /* "-"/"+" is either an objc selector, or a number. There's + nothing to complete the latter to, so just let the caller + complete on functions, which finds objc selectors, if there's + any. */ + if ((arg[0] == '-' || arg[0] == '+') && arg[1] == '\0') + return {}; + } /* Start parsing. */ /* Get the first token. */ - token = linespec_lexer_lex_one (parser); + token = linespec_lexer_consume_token (parser); /* It must be either LSTOKEN_STRING or LSTOKEN_NUMBER. */ if (token.type == LSTOKEN_STRING && *LS_TOKEN_STOKEN (token).ptr == '$') @@ -2159,7 +2503,8 @@ parse_linespec (linespec_parser *parser, const char *arg) char *var; /* A NULL entry means to use GLOBAL_DEFAULT_SYMTAB. */ - VEC_safe_push (symtab_ptr, PARSER_RESULT (parser)->file_symtabs, NULL); + if (parser->completion_tracker == NULL) + VEC_safe_push (symtab_ptr, PARSER_RESULT (parser)->file_symtabs, NULL); /* User specified a convenience variable or history value. */ var = copy_token_string (token); @@ -2178,8 +2523,16 @@ parse_linespec (linespec_parser *parser, const char *arg) goto convert_to_sals; } } + else if (token.type == LSTOKEN_EOI && parser->completion_tracker != NULL) + { + /* Let the default linespec_complete_what::FUNCTION kick in. */ + unexpected_linespec_error (parser); + } else if (token.type != LSTOKEN_STRING && token.type != LSTOKEN_NUMBER) - unexpected_linespec_error (parser); + { + parser->complete_what = linespec_complete_what::NOTHING; + unexpected_linespec_error (parser); + } /* Shortcut: If the next token is not LSTOKEN_COLON, we know that this token cannot represent a filename. */ @@ -2227,8 +2580,9 @@ parse_linespec (linespec_parser *parser, const char *arg) } } /* If the next token is not EOI, KEYWORD, or COMMA, issue an error. */ - else if (token.type != LSTOKEN_EOI && token.type != LSTOKEN_KEYWORD - && token.type != LSTOKEN_COMMA) + else if (parser->completion_tracker == NULL + && (token.type != LSTOKEN_EOI && token.type != LSTOKEN_KEYWORD + && token.type != LSTOKEN_COMMA)) { /* TOKEN is the _next_ token, not the one currently in the parser. Consuming the token will give the correct error message. */ @@ -2244,7 +2598,8 @@ parse_linespec (linespec_parser *parser, const char *arg) /* Parse the rest of the linespec. */ linespec_parse_basic (parser); - if (PARSER_RESULT (parser)->function_symbols == NULL + if (parser->completion_tracker == NULL + && PARSER_RESULT (parser)->function_symbols == NULL && PARSER_RESULT (parser)->labels.label_symbols == NULL && PARSER_EXPLICIT (parser)->line_offset.sign == LINE_OFFSET_UNKNOWN && PARSER_RESULT (parser)->minimal_symbols == NULL) @@ -2265,11 +2620,21 @@ parse_linespec (linespec_parser *parser, const char *arg) if necessary. */ token = linespec_lexer_lex_one (parser); if (token.type != LSTOKEN_EOI && token.type != LSTOKEN_KEYWORD) - PARSER_STREAM (parser) = LS_TOKEN_STOKEN (token).ptr; + unexpected_linespec_error (parser); + else if (token.type == LSTOKEN_KEYWORD) + { + /* Setup the completion word past the keyword. Lexing never + advances past a keyword automatically, so skip it + manually. */ + parser->completion_word + = skip_spaces_const (skip_to_space_const (PARSER_STREAM (parser))); + parser->complete_what = linespec_complete_what::EXPRESSION; + } /* Convert the data in PARSER_RESULT to SALs. */ - values = convert_linespec_to_sals (PARSER_STATE (parser), - PARSER_RESULT (parser)); + if (parser->completion_tracker == NULL) + values = convert_linespec_to_sals (PARSER_STATE (parser), + PARSER_RESULT (parser)); return values; } @@ -2388,6 +2753,344 @@ linespec_lex_to_end (char **stringp) do_cleanups (cleanup); } +/* See linespec.h. */ + +void +linespec_complete_function (completion_tracker &tracker, + const char *function, + const char *source_filename) +{ + complete_symbol_mode mode = complete_symbol_mode::LINESPEC; + + if (source_filename != NULL) + { + collect_file_symbol_completion_matches (tracker, mode, + function, function, + source_filename); + } + else + collect_symbol_completion_matches (tracker, mode, function, function); +} + +/* Helper for complete_linespec to simplify it. SOURCE_FILENAME is + only meaningful if COMPONENT is FUNCTION. */ + +static void +complete_linespec_component (linespec_parser *parser, + completion_tracker &tracker, + const char *text, + linespec_complete_what component, + const char *source_filename) +{ + if (component == linespec_complete_what::KEYWORD) + { + complete_on_enum (tracker, linespec_keywords, text, text); + } + else if (component == linespec_complete_what::EXPRESSION) + { + const char *word + = advance_to_expression_complete_word_point (tracker, text); + complete_expression (tracker, text, word); + } + else if (component == linespec_complete_what::FUNCTION) + { + completion_list fn_list; + + linespec_complete_function (tracker, text, source_filename); + if (source_filename == NULL) + { + /* Haven't seen a source component, like in "b + file.c:function[TAB]". Maybe this wasn't a function, but + a filename instead, like "b file.[TAB]". */ + fn_list = complete_source_filenames (text); + } + + /* If we only have a single filename completion, append a ':' for + the user, since that's the only thing that can usefully follow + the filename. */ + if (fn_list.size () == 1 && !tracker.have_completions ()) + { + char *fn = fn_list[0].release (); + + /* If we also need to append a quote char, it needs to be + appended before the ':'. Append it now, and make ':' the + new "quote" char. */ + if (tracker.quote_char ()) + { + char quote_char_str[2] = { tracker.quote_char () }; + + fn = reconcat (fn, fn, quote_char_str, (char *) NULL); + tracker.set_quote_char (':'); + } + else + fn = reconcat (fn, fn, ":", (char *) NULL); + fn_list[0].reset (fn); + + /* Tell readline to skip appending a space. */ + tracker.set_suppress_append_ws (true); + } + tracker.add_completions (std::move (fn_list)); + } +} + +/* Helper for linespec_complete_label. Find labels that match + LABEL_NAME in the function symbols listed in the PARSER, and add + them to the tracker. */ + +static void +complete_label (completion_tracker &tracker, + linespec_parser *parser, + const char *label_name) +{ + VEC (block_symbol_d) *label_function_symbols = NULL; + VEC (block_symbol_d) *labels + = find_label_symbols (PARSER_STATE (parser), + PARSER_RESULT (parser)->function_symbols, + &label_function_symbols, + label_name, true); + + struct block_symbol *label; + for (int ix = 0; + VEC_iterate (block_symbol_d, labels, ix, label); ++ix) + { + char *match = xstrdup (SYMBOL_SEARCH_NAME (label->symbol)); + tracker.add_completion (gdb::unique_xmalloc_ptr<char> (match)); + } + VEC_free (block_symbol_d, labels); +} + +/* See linespec.h. */ + +void +linespec_complete_label (completion_tracker &tracker, + const struct language_defn *language, + const char *source_filename, + const char *function_name, + const char *label_name) +{ + linespec_parser parser; + struct cleanup *cleanup; + + linespec_parser_new (&parser, 0, language, NULL, NULL, 0, NULL); + cleanup = make_cleanup (linespec_parser_delete, &parser); + + line_offset unknown_offset = { 0, LINE_OFFSET_UNKNOWN }; + + TRY + { + convert_explicit_location_to_linespec (PARSER_STATE (&parser), + PARSER_RESULT (&parser), + source_filename, + function_name, + NULL, unknown_offset); + } + CATCH (ex, RETURN_MASK_ERROR) + { + do_cleanups (cleanup); + return; + } + END_CATCH + + complete_label (tracker, &parser, label_name); + + do_cleanups (cleanup); +} + +/* See description in linespec.h. */ + +void +linespec_complete (completion_tracker &tracker, const char *text) +{ + linespec_parser parser; + struct cleanup *cleanup; + const char *orig = text; + + linespec_parser_new (&parser, 0, current_language, NULL, NULL, 0, NULL); + cleanup = make_cleanup (linespec_parser_delete, &parser); + parser.lexer.saved_arg = text; + PARSER_STREAM (&parser) = text; + + parser.completion_tracker = &tracker; + PARSER_STATE (&parser)->is_linespec = 1; + + /* Parse as much as possible. parser.completion_word will hold + furthest completion point we managed to parse to. */ + TRY + { + parse_linespec (&parser, text); + } + CATCH (except, RETURN_MASK_ERROR) + { + } + END_CATCH + + if (parser.completion_quote_char != '\0' + && parser.completion_quote_end != NULL + && parser.completion_quote_end[1] == '\0') + { + /* If completing a quoted string with the cursor right at + terminating quote char, complete the completion word without + interpretation, so that readline advances the cursor one + whitespace past the quote, even if there's no match. This + makes these cases behave the same: + + before: "b function()" + after: "b function() " + + before: "b 'function()'" + after: "b 'function()' " + + and trusts the user in this case: + + before: "b 'not_loaded_function_yet()'" + after: "b 'not_loaded_function_yet()' " + */ + parser.complete_what = linespec_complete_what::NOTHING; + parser.completion_quote_char = '\0'; + + gdb::unique_xmalloc_ptr<char> text_copy + (xstrdup (parser.completion_word)); + tracker.add_completion (std::move (text_copy)); + } + + tracker.set_quote_char (parser.completion_quote_char); + + if (parser.complete_what == linespec_complete_what::LABEL) + { + parser.complete_what = linespec_complete_what::NOTHING; + + const char *func_name = PARSER_EXPLICIT (&parser)->function_name; + + VEC (block_symbol_d) *function_symbols; + VEC (bound_minimal_symbol_d) *minimal_symbols; + find_linespec_symbols (PARSER_STATE (&parser), + PARSER_RESULT (&parser)->file_symtabs, + func_name, + &function_symbols, &minimal_symbols); + + PARSER_RESULT (&parser)->function_symbols = function_symbols; + PARSER_RESULT (&parser)->minimal_symbols = minimal_symbols; + + complete_label (tracker, &parser, parser.completion_word); + } + else if (parser.complete_what == linespec_complete_what::FUNCTION) + { + /* While parsing/lexing, we didn't know whether the completion + word completes to a unique function/source name already or + not. + + E.g.: + "b function() <tab>" + may need to complete either to: + "b function() const" + or to: + "b function() if/thread/task" + + Or, this: + "b foo t" + may need to complete either to: + "b foo template_fun<T>()" + with "foo" being the template function's return type, or to: + "b foo thread/task" + + Or, this: + "b file<TAB>" + may need to complete either to a source file name: + "b file.c" + or this, also a filename, but a unique completion: + "b file.c:" + or to a function name: + "b file_function" + + Address that by completing assuming source or function, and + seeing if we find a completion that matches exactly the + completion word. If so, then it must be a function (see note + below) and we advance the completion word to the end of input + and switch to KEYWORD completion mode. + + Note: if we find a unique completion for a source filename, + then it won't match the completion word, because the LCD will + contain a trailing ':'. And if we're completing at or after + the ':', then complete_linespec_component won't try to + complete on source filenames. */ + + const char *text = parser.completion_word; + const char *word = parser.completion_word; + + complete_linespec_component (&parser, tracker, + parser.completion_word, + linespec_complete_what::FUNCTION, + PARSER_EXPLICIT (&parser)->source_filename); + + parser.complete_what = linespec_complete_what::NOTHING; + + if (tracker.quote_char ()) + { + /* The function/file name was not close-quoted, so this + can't be a keyword. Note: complete_linespec_component + may have swapped the original quote char for ':' when we + get here, but that still indicates the same. */ + } + else if (!tracker.have_completions ()) + { + size_t key_start; + size_t wordlen = strlen (parser.completion_word); + + key_start + = string_find_incomplete_keyword_at_end (linespec_keywords, + parser.completion_word, + wordlen); + + if (key_start != -1 + || (wordlen > 0 + && parser.completion_word[wordlen - 1] == ' ')) + { + parser.completion_word += key_start; + parser.complete_what = linespec_complete_what::KEYWORD; + } + } + else if (tracker.completes_to_completion_word (word)) + { + /* Skip the function and complete on keywords. */ + parser.completion_word += strlen (word); + parser.complete_what = linespec_complete_what::KEYWORD; + tracker.discard_completions (); + } + } + + tracker.advance_custom_word_point_by (parser.completion_word - orig); + + complete_linespec_component (&parser, tracker, + parser.completion_word, + parser.complete_what, + PARSER_EXPLICIT (&parser)->source_filename); + + /* If we're past the "filename:function:label:offset" linespec, and + didn't find any match, then assume the user might want to create + a pending breakpoint anyway and offer the keyword + completions. */ + if (!parser.completion_quote_char + && (parser.complete_what == linespec_complete_what::FUNCTION + || parser.complete_what == linespec_complete_what::LABEL + || parser.complete_what == linespec_complete_what::NOTHING) + && !tracker.have_completions ()) + { + const char *end + = parser.completion_word + strlen (parser.completion_word); + + if (end > orig && end[-1] == ' ') + { + tracker.advance_custom_word_point_by (end - parser.completion_word); + + complete_linespec_component (&parser, tracker, end, + linespec_complete_what::KEYWORD, + NULL); + } + } + + do_cleanups (cleanup); +} + /* A helper function for decode_line_full and decode_line_1 to turn LOCATION into symtabs_and_lines. */ @@ -3374,22 +4077,77 @@ find_linespec_symbols (struct linespec_state *state, } } -/* Return all labels named NAME in FUNCTION_SYMBOLS. Return the - actual function symbol in which the label was found in LABEL_FUNC_RET. */ +/* Helper for find_label_symbols. Find all labels that match name + NAME in BLOCK. Return all labels that match in FUNCTION_SYMBOLS. + Return the actual function symbol in which the label was found in + LABEL_FUNC_RET. If COMPLETION_MODE is true, then NAME is + interpreted as a label name prefix. Otherwise, only a label named + exactly NAME match. */ + +static void +find_label_symbols_in_block (const struct block *block, + const char *name, struct symbol *fn_sym, + bool completion_mode, + VEC (block_symbol_d) **result, + VEC (block_symbol_d) **label_funcs_ret) +{ + if (completion_mode) + { + struct block_iterator iter; + struct symbol *sym; + size_t name_len = strlen (name); + + int (*cmp) (const char *, const char *, size_t); + cmp = case_sensitivity == case_sensitive_on ? strncmp : strncasecmp; + + ALL_BLOCK_SYMBOLS (block, iter, sym) + { + if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), + SYMBOL_DOMAIN (sym), LABEL_DOMAIN) + && cmp (SYMBOL_SEARCH_NAME (sym), name, name_len) == 0) + { + struct block_symbol label_bsym = {sym, block}; + struct block_symbol fn_bsym = {fn_sym, block}; + + VEC_safe_push (block_symbol_d, *result, &label_bsym); + VEC_safe_push (block_symbol_d, *label_funcs_ret, &fn_bsym); + } + } + } + else + { + struct block_symbol label_sym + = lookup_symbol (name, block, LABEL_DOMAIN, 0); + + if (label_sym.symbol != NULL) + { + struct block_symbol fn_bsym = {fn_sym, block}; + + VEC_safe_push (block_symbol_d, *result, &label_sym); + VEC_safe_push (block_symbol_d, *label_funcs_ret, &fn_bsym); + } + } +} + +/* Return all labels that match name NAME in FUNCTION_SYMBOLS. Return + the actual function symbol in which the label was found in + LABEL_FUNC_RET. If COMPLETION_MODE is true, then NAME is + interpreted as a label name prefix. Otherwise, only labels named + exactly NAME match. */ static VEC (block_symbol_d) * find_label_symbols (struct linespec_state *self, VEC (block_symbol_d) *function_symbols, - VEC (block_symbol_d) **label_funcs_ret, const char *name) + VEC (block_symbol_d) **label_funcs_ret, const char *name, + bool completion_mode) { int ix; const struct block *block; - + struct symbol *fn_sym; VEC (block_symbol_d) *result = NULL; if (function_symbols == NULL) { - struct block_symbol block_sym; struct block_symbol fn_block_sym; set_current_program_space (self->program_space); @@ -3401,16 +4159,10 @@ find_label_symbols (struct linespec_state *self, ; if (!block) return NULL; - fn_block_sym.symbol = BLOCK_FUNCTION (block); - fn_block_sym.block = block; - - block_sym = lookup_symbol (name, block, LABEL_DOMAIN, 0); + fn_sym = BLOCK_FUNCTION (block); - if (block_sym.symbol != NULL) - { - VEC_safe_push (block_symbol_d, result, &block_sym); - VEC_safe_push (block_symbol_d, *label_funcs_ret, &fn_block_sym); - } + find_label_symbols_in_block (block, name, fn_sym, completion_mode, + &result, label_funcs_ret); } else { @@ -3419,18 +4171,13 @@ find_label_symbols (struct linespec_state *self, for (ix = 0; VEC_iterate (block_symbol_d, function_symbols, ix, elt); ++ix) { - struct symbol *fn_sym = elt->symbol; - struct block_symbol block_sym; + fn_sym = elt->symbol; set_current_program_space (SYMTAB_PSPACE (symbol_symtab (fn_sym))); block = SYMBOL_BLOCK_VALUE (fn_sym); - block_sym = lookup_symbol (name, block, LABEL_DOMAIN, 0); - if (block_sym.symbol != NULL) - { - VEC_safe_push (block_symbol_d, result, &block_sym); - VEC_safe_push (block_symbol_d, *label_funcs_ret, elt); - } + find_label_symbols_in_block (block, name, fn_sym, completion_mode, + &result, label_funcs_ret); } } diff --git a/gdb/linespec.h b/gdb/linespec.h index ecbd7a8..abc945f 100644 --- a/gdb/linespec.h +++ b/gdb/linespec.h @@ -177,6 +177,32 @@ extern int is_ada_operator (const char *string); extern void linespec_lex_to_end (char **stringp); +extern const char * const linespec_keywords[]; + +/* Complete a linespec. */ + +extern void linespec_complete (completion_tracker &tracker, + const char *text); + +/* Complete a function symbol, in linespec mode. If SOURCE_FILENAME + is non-NULL, limits completion to the list of functions defined in + source files that match SOURCE_FILENAME. */ + +extern void linespec_complete_function (completion_tracker &tracker, + const char *function, + const char *source_filename); + +/* Complete a label symbol, in linespec mode. Only labels of + functions named FUNCTION_NAME are considered. If SOURCE_FILENAME + is non-NULL, limits completion to labels of functions defined in + source files that match SOURCE_FILENAME. */ + +extern void linespec_complete_label (completion_tracker &tracker, + const struct language_defn *language, + const char *source_filename, + const char *function_name, + const char *label_name); + /* Evaluate the expression pointed to by EXP_PTR into a CORE_ADDR, advancing EXP_PTR past any parsed text. */ diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 8b29245..b9c7d1f 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -4187,20 +4187,17 @@ void linux_proc_pending_signals (int pid, sigset_t *pending, sigset_t *blocked, sigset_t *ignored) { - FILE *procfile; char buffer[PATH_MAX], fname[PATH_MAX]; - struct cleanup *cleanup; sigemptyset (pending); sigemptyset (blocked); sigemptyset (ignored); xsnprintf (fname, sizeof fname, "/proc/%d/status", pid); - procfile = gdb_fopen_cloexec (fname, "r"); + gdb_file_up procfile = gdb_fopen_cloexec (fname, "r"); if (procfile == NULL) error (_("Could not open %s"), fname); - cleanup = make_cleanup_fclose (procfile); - while (fgets (buffer, PATH_MAX, procfile) != NULL) + while (fgets (buffer, PATH_MAX, procfile.get ()) != NULL) { /* Normal queued signals are on the SigPnd line in the status file. However, 2.6 kernels also have a "shared" pending @@ -4219,8 +4216,6 @@ linux_proc_pending_signals (int pid, sigset_t *pending, else if (startswith (buffer, "SigIgn:\t")) add_line_to_sigset (buffer + 8, ignored); } - - do_cleanups (cleanup); } static enum target_xfer_status diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index 1afa8d7..5c7f8a0 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -1127,6 +1127,26 @@ linux_core_info_proc (struct gdbarch *gdbarch, const char *args, error (_("unable to handle request")); } +/* Read siginfo data from the core, if possible. Returns -1 on + failure. Otherwise, returns the number of bytes read. READBUF, + OFFSET, and LEN are all as specified by the to_xfer_partial + interface. */ + +static LONGEST +linux_core_xfer_siginfo (struct gdbarch *gdbarch, gdb_byte *readbuf, + ULONGEST offset, ULONGEST len) +{ + thread_section_name section_name (".note.linuxcore.siginfo", inferior_ptid); + asection *section = bfd_get_section_by_name (core_bfd, section_name.c_str ()); + if (section == NULL) + return -1; + + if (!bfd_get_section_contents (core_bfd, section, readbuf, offset, len)) + return -1; + + return len; +} + typedef int linux_find_memory_region_ftype (ULONGEST vaddr, ULONGEST size, ULONGEST offset, ULONGEST inode, int read, int write, @@ -1506,16 +1526,12 @@ linux_make_mappings_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, char *note_data, int *note_size) { struct cleanup *cleanup; - struct obstack data_obstack, filename_obstack; struct linux_make_mappings_data mapping_data; struct type *long_type = arch_integer_type (gdbarch, gdbarch_long_bit (gdbarch), 0, "long"); gdb_byte buf[sizeof (ULONGEST)]; - obstack_init (&data_obstack); - cleanup = make_cleanup_obstack_free (&data_obstack); - obstack_init (&filename_obstack); - make_cleanup_obstack_free (&filename_obstack); + auto_obstack data_obstack, filename_obstack; mapping_data.file_count = 0; mapping_data.data_obstack = &data_obstack; @@ -1548,7 +1564,6 @@ linux_make_mappings_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, obstack_object_size (&data_obstack)); } - do_cleanups (cleanup); return note_data; } @@ -2521,6 +2536,7 @@ linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_core_pid_to_str (gdbarch, linux_core_pid_to_str); set_gdbarch_info_proc (gdbarch, linux_info_proc); set_gdbarch_core_info_proc (gdbarch, linux_core_info_proc); + set_gdbarch_core_xfer_siginfo (gdbarch, linux_core_xfer_siginfo); set_gdbarch_find_memory_regions (gdbarch, linux_find_memory_regions); set_gdbarch_make_corefile_notes (gdbarch, linux_make_corefile_notes); set_gdbarch_has_shared_address_space (gdbarch, diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c index 86254f8..cf68013 100644 --- a/gdb/linux-thread-db.c +++ b/gdb/linux-thread-db.c @@ -1623,45 +1623,49 @@ info_auto_load_libthread_db (char *args, int from_tty) if (info_count > 0 && args == auto_load_info_scripts_pattern_nl) uiout->text ("\n"); - make_cleanup_ui_out_table_begin_end (uiout, 2, unique_filenames, - "LinuxThreadDbTable"); + { + ui_out_emit_table table_emitter (uiout, 2, unique_filenames, + "LinuxThreadDbTable"); - uiout->table_header (max_filename_len, ui_left, "filename", "Filename"); - uiout->table_header (pids_len, ui_left, "PIDs", "Pids"); - uiout->table_body (); + uiout->table_header (max_filename_len, ui_left, "filename", "Filename"); + uiout->table_header (pids_len, ui_left, "PIDs", "Pids"); + uiout->table_body (); - pids = (char *) xmalloc (max_pids_len + 1); - make_cleanup (xfree, pids); + pids = (char *) xmalloc (max_pids_len + 1); + make_cleanup (xfree, pids); - /* Note I is incremented inside the cycle, not at its end. */ - for (i = 0; i < info_count;) - { - ui_out_emit_tuple tuple_emitter (uiout, NULL); - char *pids_end; - - info = array[i]; - uiout->field_string ("filename", info->filename); - pids_end = pids; + /* Note I is incremented inside the cycle, not at its end. */ + for (i = 0; i < info_count;) + { + ui_out_emit_tuple tuple_emitter (uiout, NULL); + char *pids_end; - while (i < info_count && strcmp (info->filename, array[i]->filename) == 0) - { - if (pids_end != pids) - { - *pids_end++ = ','; - *pids_end++ = ' '; - } - pids_end += xsnprintf (pids_end, &pids[max_pids_len + 1] - pids_end, - "%u", array[i]->pid); - gdb_assert (pids_end < &pids[max_pids_len + 1]); + info = array[i]; + uiout->field_string ("filename", info->filename); + pids_end = pids; - i++; - } - *pids_end = '\0'; + while (i < info_count && strcmp (info->filename, + array[i]->filename) == 0) + { + if (pids_end != pids) + { + *pids_end++ = ','; + *pids_end++ = ' '; + } + pids_end += xsnprintf (pids_end, + &pids[max_pids_len + 1] - pids_end, + "%u", array[i]->pid); + gdb_assert (pids_end < &pids[max_pids_len + 1]); + + i++; + } + *pids_end = '\0'; - uiout->field_string ("pids", pids); + uiout->field_string ("pids", pids); - uiout->text ("\n"); - } + uiout->text ("\n"); + } + } do_cleanups (back_to); diff --git a/gdb/location.c b/gdb/location.c index 8796320..3238c9a 100644 --- a/gdb/location.c +++ b/gdb/location.c @@ -24,6 +24,7 @@ #include "linespec.h" #include "cli/cli-utils.h" #include "probe.h" +#include "cp-support.h" #include <ctype.h> #include <string.h> @@ -414,13 +415,44 @@ event_location_to_string (struct event_location *location) return EL_STRING (location); } +/* Find an instance of the quote character C in the string S that is + outside of all single- and double-quoted strings (i.e., any quoting + other than C). */ + +static const char * +find_end_quote (const char *s, char end_quote_char) +{ + /* zero if we're not in quotes; + '"' if we're in a double-quoted string; + '\'' if we're in a single-quoted string. */ + char nested_quote_char = '\0'; + + for (const char *scan = s; *scan != '\0'; scan++) + { + if (nested_quote_char != '\0') + { + if (*scan == nested_quote_char) + nested_quote_char = '\0'; + else if (scan[0] == '\\' && *(scan + 1) != '\0') + scan++; + } + else if (*scan == end_quote_char && nested_quote_char == '\0') + return scan; + else if (*scan == '"' || *scan == '\'') + nested_quote_char = *scan; + } + + return 0; +} + /* A lexer for explicit locations. This function will advance INP past any strings that it lexes. Returns a malloc'd copy of the lexed string or NULL if no lexing was done. */ static gdb::unique_xmalloc_ptr<char> explicit_location_lex_one (const char **inp, - const struct language_defn *language) + const struct language_defn *language, + explicit_completion_info *completion_info) { const char *start = *inp; @@ -430,21 +462,27 @@ explicit_location_lex_one (const char **inp, /* If quoted, skip to the ending quote. */ if (strchr (get_gdb_linespec_parser_quote_characters (), *start)) { - char quote_char = *start; + if (completion_info != NULL) + completion_info->quoted_arg_start = start; - /* If the input is not an Ada operator, skip to the matching - closing quote and return the string. */ - if (!(language->la_language == language_ada - && quote_char == '\"' && is_ada_operator (start))) - { - const char *end = find_toplevel_char (start + 1, quote_char); + const char *end = find_end_quote (start + 1, *start); - if (end == NULL) + if (end == NULL) + { + if (completion_info == NULL) error (_("Unmatched quote, %s."), start); - *inp = end + 1; + + end = start + strlen (start); + *inp = end; return gdb::unique_xmalloc_ptr<char> (savestring (start + 1, - *inp - start - 2)); + *inp - start - 1)); } + + if (completion_info != NULL) + completion_info->quoted_arg_end = end; + *inp = end + 1; + return gdb::unique_xmalloc_ptr<char> (savestring (start + 1, + *inp - start - 2)); } /* If the input starts with '-' or '+', the string ends with the next @@ -473,8 +511,8 @@ explicit_location_lex_one (const char **inp, { /* Special case: C++ operator,. */ if (language->la_language == language_cplus - && strncmp (*inp, "operator", 8) == 0) - (*inp) += 8; + && startswith (*inp, CP_OPERATOR_STR)) + (*inp) += CP_OPERATOR_LEN; ++(*inp); } } @@ -485,12 +523,180 @@ explicit_location_lex_one (const char **inp, return NULL; } +/* Return true if COMMA points past "operator". START is the start of + the line that COMMAND points to, hence when reading backwards, we + must not read any character before START. */ + +static bool +is_cp_operator (const char *start, const char *comma) +{ + if (comma != NULL + && (comma - start) >= CP_OPERATOR_LEN) + { + const char *p = comma; + + while (p > start && isspace (p[-1])) + p--; + if (p - start >= CP_OPERATOR_LEN) + { + p -= CP_OPERATOR_LEN; + if (strncmp (p, CP_OPERATOR_STR, CP_OPERATOR_LEN) == 0 + && (p == start + || !(isalnum (p[-1]) || p[-1] == '_'))) + { + return true; + } + } + } + return false; +} + +/* When scanning the input string looking for the next explicit + location option/delimiter, we jump to the next option by looking + for ",", and "-". Such a character can also appear in C++ symbols + like "operator," and "operator-". So when we find such a + character, we call this function to check if we found such a + symbol, meaning we had a false positive for an option string. In + that case, we keep looking for the next delimiter, until we find + one that is not a false positive, or we reach end of string. FOUND + is the character that scanning found (either '-' or ','), and START + is the start of the line that FOUND points to, hence when reading + backwards, we must not read any character before START. Returns a + pointer to the next non-false-positive delimiter character, or NULL + if none was found. */ + +static const char * +skip_op_false_positives (const char *start, const char *found) +{ + while (found != NULL && is_cp_operator (start, found)) + { + if (found[0] == '-' && found[1] == '-') + start = found + 2; + else + start = found + 1; + found = find_toplevel_char (start, *found); + } + + return found; +} + +/* Assuming both FIRST and NEW_TOK point into the same string, return + the pointer that is closer to the start of the string. If FIRST is + NULL, returns NEW_TOK. If NEW_TOK is NULL, returns FIRST. */ + +static const char * +first_of (const char *first, const char *new_tok) +{ + if (first == NULL) + return new_tok; + else if (new_tok != NULL && new_tok < first) + return new_tok; + else + return first; +} + +/* A lexer for functions in explicit locations. This function will + advance INP past a function until the next option, or until end of + string. Returns a malloc'd copy of the lexed string or NULL if no + lexing was done. */ + +static gdb::unique_xmalloc_ptr<char> +explicit_location_lex_one_function (const char **inp, + const struct language_defn *language, + explicit_completion_info *completion_info) +{ + const char *start = *inp; + + if (*start == '\0') + return NULL; + + /* If quoted, skip to the ending quote. */ + if (strchr (get_gdb_linespec_parser_quote_characters (), *start)) + { + char quote_char = *start; + + /* If the input is not an Ada operator, skip to the matching + closing quote and return the string. */ + if (!(language->la_language == language_ada + && quote_char == '\"' && is_ada_operator (start))) + { + if (completion_info != NULL) + completion_info->quoted_arg_start = start; + + const char *end = find_toplevel_char (start + 1, quote_char); + + if (end == NULL) + { + if (completion_info == NULL) + error (_("Unmatched quote, %s."), start); + + end = start + strlen (start); + *inp = end; + char *saved = savestring (start + 1, *inp - start - 1); + return gdb::unique_xmalloc_ptr<char> (saved); + } + + if (completion_info != NULL) + completion_info->quoted_arg_end = end; + *inp = end + 1; + char *saved = savestring (start + 1, *inp - start - 2); + return gdb::unique_xmalloc_ptr<char> (saved); + } + } + + const char *comma = find_toplevel_char (start, ','); + + /* If we have "-function -myfunction", or perhaps better example, + "-function -[BasicClass doIt]" (objc selector), treat + "-myfunction" as the function name. I.e., skip the first char if + it is an hyphen. Don't skip the first char always, because we + may have C++ "operator<", and find_toplevel_char needs to see the + 'o' in that case. */ + const char *hyphen + = (*start == '-' + ? find_toplevel_char (start + 1, '-') + : find_toplevel_char (start, '-')); + + /* Check for C++ "operator," and "operator-". */ + comma = skip_op_false_positives (start, comma); + hyphen = skip_op_false_positives (start, hyphen); + + /* Pick the one that appears first. */ + const char *end = first_of (hyphen, comma); + + /* See if a linespec keyword appears first. */ + const char *s = start; + const char *ws = find_toplevel_char (start, ' '); + while (ws != NULL && linespec_lexer_lex_keyword (ws + 1) == NULL) + { + s = ws + 1; + ws = find_toplevel_char (s, ' '); + } + if (ws != NULL) + end = first_of (end, ws + 1); + + /* If we don't have any terminator, then take the whole string. */ + if (end == NULL) + end = start + strlen (start); + + /* Trim whitespace at the end. */ + while (end > start && end[-1] == ' ') + end--; + + *inp = end; + + if (*inp - start > 0) + return gdb::unique_xmalloc_ptr<char> (savestring (start, *inp - start)); + + return NULL; +} + /* See description in location.h. */ event_location_up string_to_explicit_location (const char **argp, const struct language_defn *language, - int dont_throw) + explicit_completion_info *completion_info) { event_location_up location; @@ -513,6 +719,14 @@ string_to_explicit_location (const char **argp, int len; const char *start; + /* Clear these on each iteration, since they should be filled + with info about the last option. */ + if (completion_info != NULL) + { + completion_info->quoted_arg_start = NULL; + completion_info->quoted_arg_end = NULL; + } + /* If *ARGP starts with a keyword, stop processing options. */ if (linespec_lexer_lex_keyword (*argp) != NULL) @@ -521,40 +735,68 @@ string_to_explicit_location (const char **argp, /* Mark the start of the string in case we need to rewind. */ start = *argp; + if (completion_info != NULL) + completion_info->last_option = start; + /* Get the option string. */ gdb::unique_xmalloc_ptr<char> opt - = explicit_location_lex_one (argp, language); + = explicit_location_lex_one (argp, language, NULL); - *argp = skip_spaces_const (*argp); + /* Use the length of the option to allow abbreviations. */ + len = strlen (opt.get ()); /* Get the argument string. */ - gdb::unique_xmalloc_ptr<char> oarg - = explicit_location_lex_one (argp, language); - bool have_oarg = oarg != NULL; *argp = skip_spaces_const (*argp); - /* Use the length of the option to allow abbreviations. */ - len = strlen (opt.get ()); + /* All options have a required argument. Checking for this + required argument is deferred until later. */ + gdb::unique_xmalloc_ptr<char> oarg; + /* True if we have an argument. This is required because we'll + move from OARG before checking whether we have an + argument. */ + bool have_oarg = false; + + /* Convenience to consistently set both OARG/HAVE_OARG from + ARG. */ + auto set_oarg = [&] (gdb::unique_xmalloc_ptr<char> arg) + { + oarg = std::move (arg); + have_oarg = oarg != NULL; + }; - /* All options have a required argument. Checking for this required - argument is deferred until later. */ if (strncmp (opt.get (), "-source", len) == 0) - EL_EXPLICIT (location)->source_filename = oarg.release (); + { + set_oarg (explicit_location_lex_one (argp, language, + completion_info)); + EL_EXPLICIT (location)->source_filename = oarg.release (); + } else if (strncmp (opt.get (), "-function", len) == 0) - EL_EXPLICIT (location)->function_name = oarg.release (); + { + set_oarg (explicit_location_lex_one_function (argp, language, + completion_info)); + EL_EXPLICIT (location)->function_name = oarg.release (); + } else if (strncmp (opt.get (), "-line", len) == 0) { + set_oarg (explicit_location_lex_one (argp, language, NULL)); + *argp = skip_spaces_const (*argp); if (have_oarg) - EL_EXPLICIT (location)->line_offset - = linespec_parse_line_offset (oarg.get ()); + { + EL_EXPLICIT (location)->line_offset + = linespec_parse_line_offset (oarg.get ()); + continue; + } } else if (strncmp (opt.get (), "-label", len) == 0) - EL_EXPLICIT (location)->label_name = oarg.release (); + { + set_oarg (explicit_location_lex_one (argp, language, completion_info)); + EL_EXPLICIT (location)->label_name = oarg.release (); + } /* Only emit an "invalid argument" error for options that look like option strings. */ else if (opt.get ()[0] == '-' && !isdigit (opt.get ()[1])) { - if (!dont_throw) + if (completion_info == NULL) error (_("invalid explicit location argument, \"%s\""), opt.get ()); } else @@ -566,11 +808,13 @@ string_to_explicit_location (const char **argp, return location; } + *argp = skip_spaces_const (*argp); + /* It's a little lame to error after the fact, but in this case, it provides a much better user experience to issue the "invalid argument" error before any missing argument error. */ - if (!have_oarg && !dont_throw) + if (!have_oarg && completion_info == NULL) error (_("missing argument for \"%s\""), opt.get ()); } @@ -580,7 +824,7 @@ string_to_explicit_location (const char **argp, && EL_EXPLICIT (location)->function_name == NULL && EL_EXPLICIT (location)->label_name == NULL && (EL_EXPLICIT (location)->line_offset.sign == LINE_OFFSET_UNKNOWN) - && !dont_throw) + && completion_info == NULL) { error (_("Source filename requires function, label, or " "line offset.")); @@ -638,7 +882,7 @@ string_to_event_location (char **stringp, /* Try an explicit location. */ orig = arg = *stringp; - event_location_up location = string_to_explicit_location (&arg, language, 0); + event_location_up location = string_to_explicit_location (&arg, language, NULL); if (location != NULL) { /* It was a valid explicit location. Advance STRINGP to diff --git a/gdb/location.h b/gdb/location.h index 7e1f012..58536e0 100644 --- a/gdb/location.h +++ b/gdb/location.h @@ -218,20 +218,37 @@ extern event_location_up string_to_event_location_basic (char **argp, const struct language_defn *language); +/* Structure filled in by string_to_explicit_location to aid the + completer. */ +struct explicit_completion_info +{ + /* Pointer to the last option found. E.g., in "b -sou src.c -fun + func", LAST_OPTION is left pointing at "-fun func". */ + const char *last_option = NULL; + + /* These point to the start and end of a quoted argument, iff the + last argument was quoted. If parsing finds an incomplete quoted + string (e.g., "break -function 'fun"), then QUOTED_ARG_START is + set to point to the opening \', and QUOTED_ARG_END is left NULL. + If the last option is not quoted, then both are set to NULL. */ + const char *quoted_arg_start = NULL; + const char *quoted_arg_end = NULL; +}; + /* Attempt to convert the input string in *ARGP into an explicit location. ARGP is advanced past any processed input. Returns an event_location (malloc'd) if an explicit location was successfully found in *ARGP, NULL otherwise. - IF !DONT_THROW, this function may call error() if *ARGP looks like - properly formed input, e.g., if it is called with missing argument - parameters or invalid options. If DONT_THROW is non-zero, this function - will not throw any exceptions. */ + If COMPLETION_INFO is NULL, this function may call error() if *ARGP + looks like improperly formed input, e.g., if it is called with + missing argument parameters or invalid options. If COMPLETION_INFO + is not NULL, this function will not throw any exceptions. */ extern event_location_up string_to_explicit_location (const char **argp, - const struct language_defn *langauge, - int dont_throw); + const struct language_defn *language, + explicit_completion_info *completion_info); /* A convenience function for testing for unset locations. */ diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c index d9c8b1f..a0ef77e 100644 --- a/gdb/m2-lang.c +++ b/gdb/m2-lang.c @@ -354,7 +354,7 @@ const struct exp_descriptor exp_descriptor_modula2 = evaluate_subexp_modula2 }; -const struct language_defn m2_language_defn = +extern const struct language_defn m2_language_defn = { "modula-2", "Modula-2", @@ -388,7 +388,7 @@ const struct language_defn m2_language_defn = 0, /* arrays are first-class (not c-style) */ 0, /* String lower bound */ default_word_break_characters, - default_make_symbol_completion_list, + default_collect_symbol_completion_matches, m2_language_arch_info, default_print_array_index, default_pass_by_reference, @@ -440,6 +440,4 @@ void _initialize_m2_language (void) { m2_type_data = gdbarch_data_register_post_init (build_m2_types); - - add_language (&m2_language_defn); } diff --git a/gdb/maint.c b/gdb/maint.c index d95f658..a0d43ec 100644 --- a/gdb/maint.c +++ b/gdb/maint.c @@ -178,6 +178,19 @@ maintenance_info_command (char *arg, int from_tty) gdb_stdout); } +/* The "maintenance check" command is defined as a prefix, with + allow_unknown 0. Therefore, its own definition is called only for + "maintenance check" with no args. */ + +static void +maintenance_check_command (char *arg, int from_tty) +{ + printf_unfiltered (_("\"maintenance check\" must be followed " + "by the name of a check command.\n")); + help_list (maintenancechecklist, "maintenance check ", all_commands, + gdb_stdout); +} + /* Mini tokenizing lexer for 'maint info sections' command. */ static int @@ -1104,6 +1117,11 @@ Print the internal architecture configuration.\n\ Takes an optional file parameter."), &maintenanceprintlist); + add_prefix_cmd ("check", class_maintenance, maintenance_check_command, _("\ +Commands for checking internal gdb state."), + &maintenancechecklist, "maintenance check ", 0, + &maintenancelist); + add_cmd ("translate-address", class_maintenance, maintenance_translate_address, _("Translate a section name and address to a symbol."), diff --git a/gdb/mem-break.c b/gdb/mem-break.c index f87eea4..e35d0a5 100644 --- a/gdb/mem-break.c +++ b/gdb/mem-break.c @@ -37,7 +37,7 @@ int default_memory_insert_breakpoint (struct gdbarch *gdbarch, struct bp_target_info *bp_tgt) { - CORE_ADDR addr = bp_tgt->reqstd_address; + CORE_ADDR addr = bp_tgt->placed_address; const unsigned char *bp; gdb_byte *readbuf; int bplen; diff --git a/gdb/mi/mi-cmd-break.c b/gdb/mi/mi-cmd-break.c index 9412af8..560174e 100644 --- a/gdb/mi/mi-cmd-break.c +++ b/gdb/mi/mi-cmd-break.c @@ -141,7 +141,7 @@ mi_argv_to_format (char **argv, int argc) xsnprintf (tmp, sizeof (tmp), "\\%o", (unsigned char) argv[0][i]); - obstack_grow (&obstack, tmp, strlen (tmp)); + obstack_grow_str (&obstack, tmp); } break; } @@ -152,7 +152,7 @@ mi_argv_to_format (char **argv, int argc) for (i = 1; i < argc; i++) { obstack_1grow (&obstack, ','); - obstack_grow (&obstack, argv[i], strlen (argv[i])); + obstack_grow_str (&obstack, argv[i]); } obstack_1grow (&obstack, '\0'); diff --git a/gdb/mi/mi-cmd-info.c b/gdb/mi/mi-cmd-info.c index 7da4f90..fa0d16e 100644 --- a/gdb/mi/mi-cmd-info.c +++ b/gdb/mi/mi-cmd-info.c @@ -51,8 +51,9 @@ mi_cmd_info_ada_exceptions (const char *command, char **argv, int argc) exceptions = ada_exceptions_list (regexp); old_chain = make_cleanup (VEC_cleanup (ada_exc_info), &exceptions); - make_cleanup_ui_out_table_begin_end - (uiout, 2, VEC_length (ada_exc_info, exceptions), "ada-exceptions"); + ui_out_emit_table table_emitter (uiout, 2, + VEC_length (ada_exc_info, exceptions), + "ada-exceptions"); uiout->table_header (1, ui_left, "name", "Name"); uiout->table_header (1, ui_left, "address", "Address"); uiout->table_body (); diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index 53289bb..0bf587f 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -1659,8 +1659,6 @@ mi_cmd_data_write_memory (const char *command, char **argv, int argc) /* FIXME: ezannoni 2000-02-17 LONGEST could possibly not be big enough when using a compiler other than GCC. */ LONGEST value; - gdb_byte *buffer; - struct cleanup *old_chain; long offset = 0; int oind = 0; char *oarg; @@ -1707,13 +1705,10 @@ mi_cmd_data_write_memory (const char *command, char **argv, int argc) /* Get the value as a number. */ value = parse_and_eval_address (argv[3]); /* Get the value into an array. */ - buffer = (gdb_byte *) xmalloc (word_size); - old_chain = make_cleanup (xfree, buffer); - store_signed_integer (buffer, word_size, byte_order, value); + gdb::byte_vector buffer (word_size); + store_signed_integer (buffer.data (), word_size, byte_order, value); /* Write it down to memory. */ - write_memory_with_notification (addr, buffer, word_size); - /* Free the buffer. */ - do_cleanups (old_chain); + write_memory_with_notification (addr, buffer.data (), word_size); } /* Implementation of the -data-write-memory-bytes command. @@ -2243,9 +2238,10 @@ mi_cmd_execute (struct mi_parse *parse) error (_("Invalid frame id: %d"), frame); } + gdb::optional<scoped_restore_current_language> lang_saver; if (parse->language != language_unknown) { - make_cleanup_restore_current_language (); + lang_saver.emplace (); set_language (parse->language); } diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c index f144a2e..001fd40 100644 --- a/gdb/mips-linux-tdep.c +++ b/gdb/mips-linux-tdep.c @@ -1616,8 +1616,7 @@ mips_linux_init_abi (struct gdbarch_info info, { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum mips_abi abi = mips_abi (gdbarch); - struct tdesc_arch_data *tdesc_data - = (struct tdesc_arch_data *) info.tdep_info; + struct tdesc_arch_data *tdesc_data = info.tdesc_data; linux_init_abi (info, gdbarch); diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index c1800e4..75e45ef 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -8451,7 +8451,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) break; } else if (arches != NULL) - fpu_type = gdbarch_tdep (arches->gdbarch)->mips_fpu_type; + fpu_type = MIPS_FPU_TYPE (arches->gdbarch); else fpu_type = MIPS_FPU_DOUBLE; if (gdbarch_debug) @@ -8491,7 +8491,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) != mips64_transfers_32bit_regs_p) continue; /* Be pedantic about which FPU is selected. */ - if (gdbarch_tdep (arches->gdbarch)->mips_fpu_type != fpu_type) + if (MIPS_FPU_TYPE (arches->gdbarch) != fpu_type) continue; if (tdesc_data != NULL) @@ -8785,7 +8785,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) mips_register_g_packet_guesses (gdbarch); /* Hook in OS ABI-specific overrides, if they have been registered. */ - info.tdep_info = tdesc_data; + info.tdesc_data = tdesc_data; gdbarch_init_osabi (info, gdbarch); /* The hook may have adjusted num_regs, fetch the final value and @@ -8907,6 +8907,24 @@ show_mips_compression (struct ui_file *file, int from_tty, value); } +/* Return a textual name for MIPS FPU type FPU_TYPE. */ + +static const char * +mips_fpu_type_str (enum mips_fpu_type fpu_type) +{ + switch (fpu_type) + { + case MIPS_FPU_NONE: + return "none"; + case MIPS_FPU_SINGLE: + return "single"; + case MIPS_FPU_DOUBLE: + return "double"; + default: + return "???"; + } +} + static void mips_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) { @@ -8957,19 +8975,13 @@ mips_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) fprintf_unfiltered (file, "mips_dump_tdep: MIPS_DEFAULT_FPU_TYPE = %d (%s)\n", MIPS_DEFAULT_FPU_TYPE, - (MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_NONE ? "none" - : MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_SINGLE ? "single" - : MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_DOUBLE ? "double" - : "???")); + mips_fpu_type_str (MIPS_DEFAULT_FPU_TYPE)); fprintf_unfiltered (file, "mips_dump_tdep: MIPS_EABI = %d\n", MIPS_EABI (gdbarch)); fprintf_unfiltered (file, "mips_dump_tdep: MIPS_FPU_TYPE = %d (%s)\n", MIPS_FPU_TYPE (gdbarch), - (MIPS_FPU_TYPE (gdbarch) == MIPS_FPU_NONE ? "none" - : MIPS_FPU_TYPE (gdbarch) == MIPS_FPU_SINGLE ? "single" - : MIPS_FPU_TYPE (gdbarch) == MIPS_FPU_DOUBLE ? "double" - : "???")); + mips_fpu_type_str (MIPS_FPU_TYPE (gdbarch))); } extern initialize_file_ftype _initialize_mips_tdep; /* -Wmissing-prototypes */ diff --git a/gdb/nat/linux-btrace.c b/gdb/nat/linux-btrace.c index b2c84c1..1a383b7 100644 --- a/gdb/nat/linux-btrace.c +++ b/gdb/nat/linux-btrace.c @@ -204,24 +204,23 @@ linux_determine_kernel_start (void) { static uint64_t kernel_start; static int cached; - FILE *file; if (cached != 0) return kernel_start; cached = 1; - file = gdb_fopen_cloexec ("/proc/kallsyms", "r"); + gdb_file_up file = gdb_fopen_cloexec ("/proc/kallsyms", "r"); if (file == NULL) return kernel_start; - while (!feof (file)) + while (!feof (file.get ())) { char buffer[1024], symbol[8], *line; uint64_t addr; int match; - line = fgets (buffer, sizeof (buffer), file); + line = fgets (buffer, sizeof (buffer), file.get ()); if (line == NULL) break; @@ -236,8 +235,6 @@ linux_determine_kernel_start (void) } } - fclose (file); - return kernel_start; } diff --git a/gdb/nat/linux-osdata.c b/gdb/nat/linux-osdata.c index ba2e5a5..4b40a4d 100644 --- a/gdb/nat/linux-osdata.c +++ b/gdb/nat/linux-osdata.c @@ -61,7 +61,6 @@ int linux_common_core_of_thread (ptid_t ptid) { char filename[sizeof ("/proc//task//stat") + 2 * MAX_PID_T_STRLEN]; - FILE *f; char *content = NULL; char *p; char *ts = 0; @@ -71,7 +70,7 @@ linux_common_core_of_thread (ptid_t ptid) sprintf (filename, "/proc/%lld/task/%lld/stat", (PID_T) ptid_get_pid (ptid), (PID_T) ptid_get_lwp (ptid)); - f = gdb_fopen_cloexec (filename, "r"); + gdb_file_up f = gdb_fopen_cloexec (filename, "r"); if (!f) return -1; @@ -79,7 +78,7 @@ linux_common_core_of_thread (ptid_t ptid) { int n; content = (char *) xrealloc (content, content_read + 1024); - n = fread (content + content_read, 1, 1024, f); + n = fread (content + content_read, 1, 1024, f.get ()); content_read += n; if (n < 1024) { @@ -104,7 +103,6 @@ linux_common_core_of_thread (ptid_t ptid) core = -1; xfree (content); - fclose (f); return core; } @@ -117,7 +115,7 @@ static void command_from_pid (char *command, int maxlen, PID_T pid) { char *stat_path = xstrprintf ("/proc/%lld/stat", pid); - FILE *fp = gdb_fopen_cloexec (stat_path, "r"); + gdb_file_up fp = gdb_fopen_cloexec (stat_path, "r"); command[0] = '\0'; @@ -128,15 +126,13 @@ command_from_pid (char *command, int maxlen, PID_T pid) (for the brackets). */ char cmd[18]; PID_T stat_pid; - int items_read = fscanf (fp, "%lld %17s", &stat_pid, cmd); + int items_read = fscanf (fp.get (), "%lld %17s", &stat_pid, cmd); if (items_read == 2 && pid == stat_pid) { cmd[strlen (cmd) - 1] = '\0'; /* Remove trailing parenthesis. */ strncpy (command, cmd + 1, maxlen); /* Ignore leading parenthesis. */ } - - fclose (fp); } else { @@ -157,16 +153,16 @@ commandline_from_pid (PID_T pid) { char *pathname = xstrprintf ("/proc/%lld/cmdline", pid); char *commandline = NULL; - FILE *f = gdb_fopen_cloexec (pathname, "r"); + gdb_file_up f = gdb_fopen_cloexec (pathname, "r"); if (f) { size_t len = 0; - while (!feof (f)) + while (!feof (f.get ())) { char buf[1024]; - size_t read_bytes = fread (buf, 1, sizeof (buf), f); + size_t read_bytes = fread (buf, 1, sizeof (buf), f.get ()); if (read_bytes) { @@ -176,8 +172,6 @@ commandline_from_pid (PID_T pid) } } - fclose (f); - if (commandline) { size_t i; @@ -675,7 +669,6 @@ linux_xfer_osdata_cpus (gdb_byte *readbuf, if (offset == 0) { - FILE *fp; int first_item = 1; if (len_avail != -1 && len_avail != 0) @@ -685,14 +678,14 @@ linux_xfer_osdata_cpus (gdb_byte *readbuf, buffer_init (&buffer); buffer_grow_str (&buffer, "<osdata type=\"cpus\">\n"); - fp = gdb_fopen_cloexec ("/proc/cpuinfo", "r"); + gdb_file_up fp = gdb_fopen_cloexec ("/proc/cpuinfo", "r"); if (fp != NULL) { char buf[8192]; do { - if (fgets (buf, sizeof (buf), fp)) + if (fgets (buf, sizeof (buf), fp.get ())) { char *key, *value; int i = 0; @@ -732,12 +725,10 @@ linux_xfer_osdata_cpus (gdb_byte *readbuf, value); } } - while (!feof (fp)); + while (!feof (fp.get ())); if (first_item == 0) buffer_grow_str (&buffer, "</item>"); - - fclose (fp); } buffer_grow_str0 (&buffer, "</osdata>\n"); @@ -942,7 +933,6 @@ static void print_sockets (unsigned short family, int tcp, struct buffer *buffer) { const char *proc_file; - FILE *fp; if (family == AF_INET) proc_file = tcp ? "/proc/net/tcp" : "/proc/net/udp"; @@ -951,14 +941,14 @@ print_sockets (unsigned short family, int tcp, struct buffer *buffer) else return; - fp = gdb_fopen_cloexec (proc_file, "r"); + gdb_file_up fp = gdb_fopen_cloexec (proc_file, "r"); if (fp) { char buf[8192]; do { - if (fgets (buf, sizeof (buf), fp)) + if (fgets (buf, sizeof (buf), fp.get ())) { uid_t uid; unsigned int local_port, remote_port, state; @@ -1064,9 +1054,7 @@ print_sockets (unsigned short family, int tcp, struct buffer *buffer) } } } - while (!feof (fp)); - - fclose (fp); + while (!feof (fp.get ())); } } @@ -1163,8 +1151,6 @@ linux_xfer_osdata_shm (gdb_byte *readbuf, if (offset == 0) { - FILE *fp; - if (len_avail != -1 && len_avail != 0) buffer_free (&buffer); len_avail = 0; @@ -1172,14 +1158,14 @@ linux_xfer_osdata_shm (gdb_byte *readbuf, buffer_init (&buffer); buffer_grow_str (&buffer, "<osdata type=\"shared memory\">\n"); - fp = gdb_fopen_cloexec ("/proc/sysvipc/shm", "r"); + gdb_file_up fp = gdb_fopen_cloexec ("/proc/sysvipc/shm", "r"); if (fp) { char buf[8192]; do { - if (fgets (buf, sizeof (buf), fp)) + if (fgets (buf, sizeof (buf), fp.get ())) { key_t key; uid_t uid, cuid; @@ -1252,9 +1238,7 @@ linux_xfer_osdata_shm (gdb_byte *readbuf, } } } - while (!feof (fp)); - - fclose (fp); + while (!feof (fp.get ())); } buffer_grow_str0 (&buffer, "</osdata>\n"); @@ -1291,8 +1275,6 @@ linux_xfer_osdata_sem (gdb_byte *readbuf, if (offset == 0) { - FILE *fp; - if (len_avail != -1 && len_avail != 0) buffer_free (&buffer); len_avail = 0; @@ -1300,14 +1282,14 @@ linux_xfer_osdata_sem (gdb_byte *readbuf, buffer_init (&buffer); buffer_grow_str (&buffer, "<osdata type=\"semaphores\">\n"); - fp = gdb_fopen_cloexec ("/proc/sysvipc/sem", "r"); + gdb_file_up fp = gdb_fopen_cloexec ("/proc/sysvipc/sem", "r"); if (fp) { char buf[8192]; do { - if (fgets (buf, sizeof (buf), fp)) + if (fgets (buf, sizeof (buf), fp.get ())) { key_t key; uid_t uid, cuid; @@ -1364,9 +1346,7 @@ linux_xfer_osdata_sem (gdb_byte *readbuf, } } } - while (!feof (fp)); - - fclose (fp); + while (!feof (fp.get ())); } buffer_grow_str0 (&buffer, "</osdata>\n"); @@ -1403,8 +1383,6 @@ linux_xfer_osdata_msg (gdb_byte *readbuf, if (offset == 0) { - FILE *fp; - if (len_avail != -1 && len_avail != 0) buffer_free (&buffer); len_avail = 0; @@ -1412,14 +1390,14 @@ linux_xfer_osdata_msg (gdb_byte *readbuf, buffer_init (&buffer); buffer_grow_str (&buffer, "<osdata type=\"message queues\">\n"); - fp = gdb_fopen_cloexec ("/proc/sysvipc/msg", "r"); + gdb_file_up fp = gdb_fopen_cloexec ("/proc/sysvipc/msg", "r"); if (fp) { char buf[8192]; do { - if (fgets (buf, sizeof (buf), fp)) + if (fgets (buf, sizeof (buf), fp.get ())) { key_t key; PID_T lspid, lrpid; @@ -1490,9 +1468,7 @@ linux_xfer_osdata_msg (gdb_byte *readbuf, } } } - while (!feof (fp)); - - fclose (fp); + while (!feof (fp.get ())); } buffer_grow_str0 (&buffer, "</osdata>\n"); @@ -1529,8 +1505,6 @@ linux_xfer_osdata_modules (gdb_byte *readbuf, if (offset == 0) { - FILE *fp; - if (len_avail != -1 && len_avail != 0) buffer_free (&buffer); len_avail = 0; @@ -1538,14 +1512,14 @@ linux_xfer_osdata_modules (gdb_byte *readbuf, buffer_init (&buffer); buffer_grow_str (&buffer, "<osdata type=\"modules\">\n"); - fp = gdb_fopen_cloexec ("/proc/modules", "r"); + gdb_file_up fp = gdb_fopen_cloexec ("/proc/modules", "r"); if (fp) { char buf[8192]; do { - if (fgets (buf, sizeof (buf), fp)) + if (fgets (buf, sizeof (buf), fp.get ())) { char *name, *dependencies, *status, *tmp; unsigned int size; @@ -1600,9 +1574,7 @@ linux_xfer_osdata_modules (gdb_byte *readbuf, address); } } - while (!feof (fp)); - - fclose (fp); + while (!feof (fp.get ())); } buffer_grow_str0 (&buffer, "</osdata>\n"); diff --git a/gdb/nat/linux-procfs.c b/gdb/nat/linux-procfs.c index 5290045..a12f622 100644 --- a/gdb/nat/linux-procfs.c +++ b/gdb/nat/linux-procfs.c @@ -29,12 +29,11 @@ static int linux_proc_get_int (pid_t lwpid, const char *field, int warn) { size_t field_len = strlen (field); - FILE *status_file; char buf[100]; int retval = -1; snprintf (buf, sizeof (buf), "/proc/%d/status", (int) lwpid); - status_file = gdb_fopen_cloexec (buf, "r"); + gdb_file_up status_file = gdb_fopen_cloexec (buf, "r"); if (status_file == NULL) { if (warn) @@ -42,14 +41,13 @@ linux_proc_get_int (pid_t lwpid, const char *field, int warn) return -1; } - while (fgets (buf, sizeof (buf), status_file)) + while (fgets (buf, sizeof (buf), status_file.get ())) if (strncmp (buf, field, field_len) == 0 && buf[field_len] == ':') { retval = strtol (&buf[field_len + 1], NULL, 10); break; } - fclose (status_file); return retval; } @@ -128,12 +126,11 @@ parse_proc_status_state (const char *state) static int linux_proc_pid_get_state (pid_t pid, int warn, enum proc_state *state) { - FILE *procfile; int have_state; char buffer[100]; xsnprintf (buffer, sizeof (buffer), "/proc/%d/status", (int) pid); - procfile = gdb_fopen_cloexec (buffer, "r"); + gdb_file_up procfile = gdb_fopen_cloexec (buffer, "r"); if (procfile == NULL) { if (warn) @@ -142,14 +139,13 @@ linux_proc_pid_get_state (pid_t pid, int warn, enum proc_state *state) } have_state = 0; - while (fgets (buffer, sizeof (buffer), procfile) != NULL) + while (fgets (buffer, sizeof (buffer), procfile.get ()) != NULL) if (startswith (buffer, "State:")) { have_state = 1; *state = parse_proc_status_state (buffer + sizeof ("State:") - 1); break; } - fclose (procfile); return have_state; } @@ -242,7 +238,6 @@ linux_proc_tid_get_name (ptid_t ptid) static char comm_buf[TASK_COMM_LEN]; char comm_path[100]; - FILE *comm_file; const char *comm_val; pid_t pid = ptid_get_pid (ptid); pid_t tid = ptid_lwp_p (ptid) ? ptid_get_lwp (ptid) : ptid_get_pid (ptid); @@ -250,12 +245,11 @@ linux_proc_tid_get_name (ptid_t ptid) xsnprintf (comm_path, sizeof (comm_path), "/proc/%ld/task/%ld/comm", (long) pid, (long) tid); - comm_file = gdb_fopen_cloexec (comm_path, "r"); + gdb_file_up comm_file = gdb_fopen_cloexec (comm_path, "r"); if (comm_file == NULL) return NULL; - comm_val = fgets (comm_buf, sizeof (comm_buf), comm_file); - fclose (comm_file); + comm_val = fgets (comm_buf, sizeof (comm_buf), comm_file.get ()); if (comm_val != NULL) { diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c index ae84567..7725248 100644 --- a/gdb/nds32-tdep.c +++ b/gdb/nds32-tdep.c @@ -2134,7 +2134,7 @@ nds32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) nds32_add_reggroups (gdbarch); /* Hook in ABI-specific overrides, if they have been registered. */ - info.tdep_info = (void *) tdesc_data; + info.tdesc_data = tdesc_data; gdbarch_init_osabi (info, gdbarch); /* Override tdesc_register callbacks for system registers. */ diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c index b20e088..24cbf6b 100644 --- a/gdb/objc-lang.c +++ b/gdb/objc-lang.c @@ -364,7 +364,7 @@ static const char *objc_extensions[] = ".m", NULL }; -const struct language_defn objc_language_defn = { +extern const struct language_defn objc_language_defn = { "objective-c", /* Language name */ "Objective-C", language_objc, @@ -397,7 +397,7 @@ const struct language_defn objc_language_defn = { 1, /* C-style arrays */ 0, /* String lower bound */ default_word_break_characters, - default_make_symbol_completion_list, + default_collect_symbol_completion_matches, c_language_arch_info, default_print_array_index, default_pass_by_reference, @@ -1378,7 +1378,6 @@ extern initialize_file_ftype _initialize_objc_language; void _initialize_objc_language (void) { - add_language (&objc_language_defn); add_info ("selectors", selectors_info, /* INFO SELECTORS command. */ _("All Objective-C selectors, or those matching REGEXP.")); add_info ("classes", classes_info, /* INFO CLASSES command. */ diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 9500b1c..d261c87 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -142,12 +142,19 @@ get_objfile_bfd_data (struct objfile *objfile, struct bfd *abfd) { storage = ((struct objfile_per_bfd_storage *) - bfd_zalloc (abfd, sizeof (struct objfile_per_bfd_storage))); + bfd_alloc (abfd, sizeof (struct objfile_per_bfd_storage))); set_bfd_data (abfd, objfiles_bfd_data, storage); } else - storage = OBSTACK_ZALLOC (&objfile->objfile_obstack, - struct objfile_per_bfd_storage); + { + storage = (objfile_per_bfd_storage *) + obstack_alloc (&objfile->objfile_obstack, + sizeof (objfile_per_bfd_storage)); + } + + /* objfile_per_bfd_storage is not trivially constructible, must + call the ctor manually. */ + storage = new (storage) objfile_per_bfd_storage (); /* Look up the gdbarch associated with the BFD. */ if (abfd != NULL) @@ -171,7 +178,7 @@ free_objfile_per_bfd_storage (struct objfile_per_bfd_storage *storage) bcache_xfree (storage->macro_cache); if (storage->demangled_names_hash) htab_delete (storage->demangled_names_hash); - obstack_free (&storage->storage_obstack, 0); + storage->~objfile_per_bfd_storage (); } /* A wrapper for free_objfile_per_bfd_storage that can be passed as a diff --git a/gdb/objfiles.h b/gdb/objfiles.h index 58db6c9..3260425 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -184,24 +184,28 @@ extern void print_symbol_bcache_statistics (void); struct objfile_per_bfd_storage { + objfile_per_bfd_storage () + : minsyms_read (false) + {} + /* The storage has an obstack of its own. */ - struct obstack storage_obstack; + auto_obstack storage_obstack; /* Byte cache for file names. */ - struct bcache *filename_cache; + bcache *filename_cache = NULL; /* Byte cache for macros. */ - struct bcache *macro_cache; + bcache *macro_cache = NULL; /* The gdbarch associated with the BFD. Note that this gdbarch is determined solely from BFD information, without looking at target information. The gdbarch determined from a running target may differ from this e.g. with respect to register types and names. */ - struct gdbarch *gdbarch; + struct gdbarch *gdbarch = NULL; /* Hash table for mapping symbol names to demangled names. Each entry in the hash table is actually two consecutive strings, @@ -209,19 +213,19 @@ struct objfile_per_bfd_storage name, and the second is the demangled name or just a zero byte if the name doesn't demangle. */ - struct htab *demangled_names_hash; + htab *demangled_names_hash = NULL; /* The per-objfile information about the entry point, the scope (file/func) containing the entry point, and the scope of the user's main() func. */ - struct entry_info ei; + entry_info ei {}; /* The name and language of any "main" found in this objfile. The name can be NULL, which means that the information was not recorded. */ - const char *name_of_main; - enum language language_of_main; + const char *name_of_main = NULL; + enum language language_of_main = language_unknown; /* Each file contains a pointer to an array of minimal symbols for all global symbols that are defined within the file. The array is @@ -233,15 +237,15 @@ struct objfile_per_bfd_storage as all the data that it points to, should be allocated on the objfile_obstack for this file. */ - struct minimal_symbol *msymbols; - int minimal_symbol_count; + minimal_symbol *msymbols = NULL; + int minimal_symbol_count = 0; /* The number of minimal symbols read, before any minimal symbol de-duplication is applied. Note in particular that this has only a passing relationship with the actual size of the table above; use minimal_symbol_count if you need the true size. */ - int n_minsyms; + int n_minsyms = 0; /* This is true if minimal symbols have already been read. Symbol readers can use this to bypass minimal symbol reading. Also, the @@ -251,16 +255,16 @@ struct objfile_per_bfd_storage for multiple readers to install minimal symbols into a given per-BFD. */ - unsigned int minsyms_read : 1; + bool minsyms_read : 1; /* This is a hash table used to index the minimal symbols by name. */ - struct minimal_symbol *msymbol_hash[MINIMAL_SYMBOL_HASH_SIZE]; + minimal_symbol *msymbol_hash[MINIMAL_SYMBOL_HASH_SIZE] {}; /* This hash table is used to index the minimal symbols by their demangled names. */ - struct minimal_symbol *msymbol_demangled_hash[MINIMAL_SYMBOL_HASH_SIZE]; + minimal_symbol *msymbol_demangled_hash[MINIMAL_SYMBOL_HASH_SIZE] {}; }; /* Master structure for keeping track of each file from which diff --git a/gdb/opencl-lang.c b/gdb/opencl-lang.c index 54c19af..18f2cd2 100644 --- a/gdb/opencl-lang.c +++ b/gdb/opencl-lang.c @@ -1043,7 +1043,7 @@ const struct exp_descriptor exp_descriptor_opencl = evaluate_subexp_opencl }; -const struct language_defn opencl_language_defn = +extern const struct language_defn opencl_language_defn = { "opencl", /* Language name */ "OpenCL C", @@ -1077,7 +1077,7 @@ const struct language_defn opencl_language_defn = 1, /* c-style arrays */ 0, /* String lower bound */ default_word_break_characters, - default_make_symbol_completion_list, + default_collect_symbol_completion_matches, opencl_language_arch_info, default_print_array_index, default_pass_by_reference, @@ -1186,5 +1186,4 @@ void _initialize_opencl_language (void) { opencl_type_data = gdbarch_data_register_post_init (build_opencl_types); - add_language (&opencl_language_defn); } diff --git a/gdb/osdata.c b/gdb/osdata.c index b9014dd..5458e2f 100644 --- a/gdb/osdata.c +++ b/gdb/osdata.c @@ -337,8 +337,7 @@ info_osdata (const char *type) } } - make_cleanup_ui_out_table_begin_end (uiout, ncols, nrows, - "OSDataTable"); + ui_out_emit_table table_emitter (uiout, ncols, nrows, "OSDataTable"); /* With no columns/items, we just output an empty table, but we still output the table. This matters for MI. */ diff --git a/gdb/p-lang.c b/gdb/p-lang.c index 5ff9c22..cd8a2ab 100644 --- a/gdb/p-lang.c +++ b/gdb/p-lang.c @@ -32,9 +32,6 @@ #include <ctype.h> #include "c-lang.h" -extern void _initialize_pascal_language (void); - - /* All GPC versions until now (2007-09-27) also define a symbol called '_p_initialize'. Check for the presence of this symbol first. */ static const char GPC_P_INITIALIZE[] = "_p_initialize"; @@ -418,7 +415,7 @@ static const char *p_extensions[] = ".pas", ".p", ".pp", NULL }; -const struct language_defn pascal_language_defn = +extern const struct language_defn pascal_language_defn = { "pascal", /* Language name */ "Pascal", @@ -451,7 +448,7 @@ const struct language_defn pascal_language_defn = 1, /* c-style arrays */ 0, /* String lower bound */ default_word_break_characters, - default_make_symbol_completion_list, + default_collect_symbol_completion_matches, pascal_language_arch_info, default_print_array_index, default_pass_by_reference, @@ -465,9 +462,3 @@ const struct language_defn pascal_language_defn = NULL, LANG_MAGIC }; - -void -_initialize_pascal_language (void) -{ - add_language (&pascal_language_defn); -} diff --git a/gdb/parse.c b/gdb/parse.c index 3dd7075..abf59d7 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -50,6 +50,7 @@ #include "objfiles.h" #include "user-regs.h" #include <algorithm> +#include "common/gdb_optional.h" /* Standard set of definitions for printing, dumping, prefixifying, * and evaluating expressions. */ @@ -1136,7 +1137,7 @@ parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc, const struct block *block, int comma, int void_context_p, int *out_subexp) { - struct cleanup *old_chain, *inner_chain; + struct cleanup *old_chain; const struct language_defn *lang = NULL; struct parser_state ps; int subexp; @@ -1214,7 +1215,8 @@ parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc, to the value matching SELECTED_FRAME as set by get_current_arch. */ initialize_expout (&ps, 10, lang, get_current_arch ()); - inner_chain = make_cleanup_restore_current_language (); + + scoped_restore_current_language lang_saver; set_language (lang->la_language); TRY @@ -1250,7 +1252,6 @@ parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc, if (expressiondebug) dump_prefix_expression (ps.expout, gdb_stdlog); - do_cleanups (inner_chain); discard_cleanups (old_chain); *stringptr = lexptr; @@ -1275,19 +1276,14 @@ parse_expression (const char *string) expression_up parse_expression_with_language (const char *string, enum language lang) { - struct cleanup *old_chain = NULL; - + gdb::optional<scoped_restore_current_language> lang_saver; if (current_language->la_language != lang) { - old_chain = make_cleanup_restore_current_language (); + lang_saver.emplace (); set_language (lang); } - expression_up expr = parse_expression (string); - - if (old_chain != NULL) - do_cleanups (old_chain); - return expr; + return parse_expression (string); } /* Parse STRING as an expression. If parsing ends in the middle of a diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index 5b86e15..324b29d 100644 --- a/gdb/ppc-linux-tdep.c +++ b/gdb/ppc-linux-tdep.c @@ -1350,7 +1350,7 @@ ppu2spu_sniffer (const struct frame_unwind *self, info.bfd_arch_info = bfd_lookup_arch (bfd_arch_spu, bfd_mach_spu); info.byte_order = BFD_ENDIAN_BIG; info.osabi = GDB_OSABI_LINUX; - info.tdep_info = &data.id; + info.id = &data.id; data.gdbarch = gdbarch_find_by_info (info); if (!data.gdbarch) return 0; @@ -1650,8 +1650,7 @@ ppc_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - struct tdesc_arch_data *tdesc_data - = (struct tdesc_arch_data *) info.tdep_info; + struct tdesc_arch_data *tdesc_data = info.tdesc_data; static const char *const stap_integer_prefixes[] = { "i", NULL }; static const char *const stap_register_indirection_prefixes[] = { "(", NULL }; diff --git a/gdb/printcmd.c b/gdb/printcmd.c index f392e6d..a1231d4 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -413,7 +413,9 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type, && (options->format == 'o' || options->format == 'x' || options->format == 't' - || options->format == 'z')) + || options->format == 'z' + || options->format == 'd' + || options->format == 'u')) { LONGEST val_long = unpack_long (type, valaddr); converted_float_bytes.resize (TYPE_LENGTH (type)); @@ -427,11 +429,13 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type, case 'o': print_octal_chars (stream, valaddr, len, byte_order); break; + case 'd': + print_decimal_chars (stream, valaddr, len, true, byte_order); + break; case 'u': print_decimal_chars (stream, valaddr, len, false, byte_order); break; case 0: - case 'd': if (TYPE_CODE (type) != TYPE_CODE_FLT) { print_decimal_chars (stream, valaddr, len, !TYPE_UNSIGNED (type), @@ -898,8 +902,6 @@ find_string_backward (struct gdbarch *gdbarch, int *strings_counted) { const int chunk_size = 0x20; - gdb_byte *buffer = NULL; - struct cleanup *cleanup = NULL; int read_error = 0; int chars_read = 0; int chars_to_read = chunk_size; @@ -908,14 +910,13 @@ find_string_backward (struct gdbarch *gdbarch, CORE_ADDR string_start_addr = addr; gdb_assert (char_size == 1 || char_size == 2 || char_size == 4); - buffer = (gdb_byte *) xmalloc (chars_to_read * char_size); - cleanup = make_cleanup (xfree, buffer); + gdb::byte_vector buffer (chars_to_read * char_size); while (count > 0 && read_error == 0) { int i; addr -= chars_to_read * char_size; - chars_read = read_memory_backward (gdbarch, addr, buffer, + chars_read = read_memory_backward (gdbarch, addr, buffer.data (), chars_to_read * char_size); chars_read /= char_size; read_error = (chars_read == chars_to_read) ? 0 : 1; @@ -924,7 +925,7 @@ find_string_backward (struct gdbarch *gdbarch, { int offset = (chars_to_read - i - 1) * char_size; - if (integer_is_zero (buffer + offset, char_size) + if (integer_is_zero (&buffer[offset], char_size) || chars_counted == options->print_max) { /* Found '\0' or reached print_max. As OFFSET is the offset to @@ -947,7 +948,6 @@ find_string_backward (struct gdbarch *gdbarch, string_start_addr -= chars_counted * char_size; } - do_cleanups (cleanup); return string_start_addr; } @@ -2255,8 +2255,6 @@ printf_wide_c_string (struct ui_file *stream, const char *format, "wchar_t", NULL, 0); int wcwidth = TYPE_LENGTH (wctype); gdb_byte *buf = (gdb_byte *) alloca (wcwidth); - struct obstack output; - struct cleanup *inner_cleanup; tem = value_as_address (value); @@ -2275,8 +2273,7 @@ printf_wide_c_string (struct ui_file *stream, const char *format, read_memory (tem, str, j); memset (&str[j], 0, wcwidth); - obstack_init (&output); - inner_cleanup = make_cleanup_obstack_free (&output); + auto_obstack output; convert_between_encodings (target_wide_charset (gdbarch), host_charset (), @@ -2285,7 +2282,6 @@ printf_wide_c_string (struct ui_file *stream, const char *format, obstack_grow_str0 (&output, ""); fprintf_filtered (stream, format, obstack_base (&output)); - do_cleanups (inner_cleanup); } /* Subroutine of ui_printf to simplify it. @@ -2531,8 +2527,6 @@ ui_printf (const char *arg, struct ui_file *stream) struct type *wctype = lookup_typename (current_language, gdbarch, "wchar_t", NULL, 0); struct type *valtype; - struct obstack output; - struct cleanup *inner_cleanup; const gdb_byte *bytes; valtype = value_type (val_args[i]); @@ -2542,8 +2536,7 @@ ui_printf (const char *arg, struct ui_file *stream) bytes = value_contents (val_args[i]); - obstack_init (&output); - inner_cleanup = make_cleanup_obstack_free (&output); + auto_obstack output; convert_between_encodings (target_wide_charset (gdbarch), host_charset (), @@ -2554,7 +2547,6 @@ ui_printf (const char *arg, struct ui_file *stream) fprintf_filtered (stream, current_substring, obstack_base (&output)); - do_cleanups (inner_cleanup); } break; case double_arg: diff --git a/gdb/procfs.c b/gdb/procfs.c index b03809c..4b965ea 100644 --- a/gdb/procfs.c +++ b/gdb/procfs.c @@ -5100,7 +5100,6 @@ procfs_info_proc (struct target_ops *ops, const char *args, struct cleanup *old_chain; procinfo *process = NULL; procinfo *thread = NULL; - char **argv = NULL; char *tmp = NULL; int pid = 0; int tid = 0; @@ -5121,24 +5120,19 @@ procfs_info_proc (struct target_ops *ops, const char *args, } old_chain = make_cleanup (null_cleanup, 0); - if (args) - { - argv = gdb_buildargv (args); - make_cleanup_freeargv (argv); - } - while (argv != NULL && *argv != NULL) + gdb_argv built_argv (args); + for (char *arg : argv) { - if (isdigit (argv[0][0])) + if (isdigit (arg[0])) { - pid = strtoul (argv[0], &tmp, 10); + pid = strtoul (arg, &tmp, 10); if (*tmp == '/') tid = strtoul (++tmp, NULL, 10); } - else if (argv[0][0] == '/') + else if (arg[0] == '/') { - tid = strtoul (argv[0] + 1, NULL, 10); + tid = strtoul (arg + 1, NULL, 10); } - argv++; } if (pid == 0) pid = ptid_get_pid (inferior_ptid); diff --git a/gdb/progspace.c b/gdb/progspace.c index f6602b7..0f3ac81 100644 --- a/gdb/progspace.c +++ b/gdb/progspace.c @@ -259,7 +259,6 @@ print_program_space (struct ui_out *uiout, int requested) { struct program_space *pspace; int count = 0; - struct cleanup *old_chain; /* Compute number of pspaces we will print. */ ALL_PSPACES (pspace) @@ -273,7 +272,7 @@ print_program_space (struct ui_out *uiout, int requested) /* There should always be at least one. */ gdb_assert (count > 0); - old_chain = make_cleanup_ui_out_table_begin_end (uiout, 3, count, "pspaces"); + ui_out_emit_table table_emitter (uiout, 3, count, "pspaces"); uiout->table_header (1, ui_left, "current", ""); uiout->table_header (4, ui_left, "id", "Id"); uiout->table_header (17, ui_left, "exec", "Executable"); @@ -325,8 +324,6 @@ print_program_space (struct ui_out *uiout, int requested) uiout->text ("\n"); } - - do_cleanups (old_chain); } /* Boolean test for an already-known program space id. */ diff --git a/gdb/psymtab.c b/gdb/psymtab.c index bb482ee..8283545 100644 --- a/gdb/psymtab.c +++ b/gdb/psymtab.c @@ -529,10 +529,10 @@ psym_lookup_symbol (struct objfile *objfile, information (but NAME might contain it). */ if (sym != NULL - && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0) + && SYMBOL_MATCHES_SEARCH_NAME (sym, name)) return stab; if (with_opaque != NULL - && strcmp_iw (SYMBOL_SEARCH_NAME (with_opaque), name) == 0) + && SYMBOL_MATCHES_SEARCH_NAME (with_opaque, name)) stab_best = stab; /* Keep looking through other psymtabs. */ @@ -1905,9 +1905,7 @@ dump_psymtab_addrmap (struct objfile *objfile, struct partial_symtab *psymtab, static void maintenance_print_psymbols (char *args, int from_tty) { - char **argv; struct ui_file *outfile = gdb_stdout; - struct cleanup *cleanups; char *address_arg = NULL, *source_arg = NULL, *objfile_arg = NULL; struct objfile *objfile; struct partial_symtab *ps; @@ -1917,8 +1915,7 @@ maintenance_print_psymbols (char *args, int from_tty) dont_repeat (); - argv = gdb_buildargv (args); - cleanups = make_cleanup_freeargv (argv); + gdb_argv argv (args); for (i = 0; argv != NULL && argv[i] != NULL; ++i) { @@ -1963,14 +1960,12 @@ maintenance_print_psymbols (char *args, int from_tty) if (argv != NULL && argv[outfile_idx] != NULL) { - char *outfile_name; - if (argv[outfile_idx + 1] != NULL) error (_("Junk at end of command")); - outfile_name = tilde_expand (argv[outfile_idx]); - make_cleanup (xfree, outfile_name); - if (!arg_outfile.open (outfile_name, FOPEN_WT)) - perror_with_name (outfile_name); + gdb::unique_xmalloc_ptr<char> outfile_name + (tilde_expand (argv[outfile_idx])); + if (!arg_outfile.open (outfile_name.get (), FOPEN_WT)) + perror_with_name (outfile_name.get ()); outfile = &arg_outfile; } @@ -2061,8 +2056,6 @@ maintenance_print_psymbols (char *args, int from_tty) if (source_arg != NULL) error (_("No partial symtab for source file: %s"), source_arg); } - - do_cleanups (cleanups); } /* List all the partial symbol tables whose names match REGEXP (optional). */ diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c index 64de803..6156eb6 100644 --- a/gdb/python/py-breakpoint.c +++ b/gdb/python/py-breakpoint.c @@ -1026,15 +1026,12 @@ local_setattro (PyObject *self, PyObject *name, PyObject *v) extlang = get_breakpoint_cond_ext_lang (obj->bp, EXT_LANG_PYTHON); if (extlang != NULL) { - char *error_text; - - error_text - = xstrprintf (_("Only one stop condition allowed. There is" - " currently a %s stop condition defined for" - " this breakpoint."), - ext_lang_capitalized_name (extlang)); - PyErr_SetString (PyExc_RuntimeError, error_text); - xfree (error_text); + std::string error_text + = string_printf (_("Only one stop condition allowed. There is" + " currently a %s stop condition defined for" + " this breakpoint."), + ext_lang_capitalized_name (extlang)); + PyErr_SetString (PyExc_RuntimeError, error_text.c_str ()); return -1; } } diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c index 6203211..2a7c613 100644 --- a/gdb/python/py-cmd.c +++ b/gdb/python/py-cmd.c @@ -44,7 +44,7 @@ static const struct cmdpy_completer completers[] = { "COMPLETE_FILENAME", filename_completer }, { "COMPLETE_LOCATION", location_completer }, { "COMPLETE_COMMAND", command_completer }, - { "COMPLETE_SYMBOL", make_symbol_completion_list_fn }, + { "COMPLETE_SYMBOL", symbol_completer }, { "COMPLETE_EXPRESSION", expression_completer }, }; @@ -242,10 +242,21 @@ cmdpy_completer_helper (struct cmd_list_element *command, NULL)); if (textobj == NULL) error (_("Could not convert argument to Python string.")); - gdbpy_ref<> wordobj (PyUnicode_Decode (word, strlen (word), host_charset (), - NULL)); - if (wordobj == NULL) - error (_("Could not convert argument to Python string.")); + + gdbpy_ref<> wordobj; + if (word == NULL) + { + /* "brkchars" phase. */ + wordobj.reset (Py_None); + Py_INCREF (Py_None); + } + else + { + wordobj.reset (PyUnicode_Decode (word, strlen (word), host_charset (), + NULL)); + if (wordobj == NULL) + error (_("Could not convert argument to Python string.")); + } gdbpy_ref<> resultobj (PyObject_CallMethodObjArgs ((PyObject *) obj, complete_cst, @@ -267,6 +278,7 @@ cmdpy_completer_helper (struct cmd_list_element *command, static void cmdpy_completer_handle_brkchars (struct cmd_list_element *command, + completion_tracker &tracker, const char *text, const char *word) { gdbpy_enter enter_py (get_current_arch (), current_language); @@ -293,23 +305,25 @@ cmdpy_completer_handle_brkchars (struct cmd_list_element *command, } else if (value >= 0 && value < (long) N_COMPLETERS) { + completer_handle_brkchars_ftype *brkchars_fn; + /* This is the core of this function. Depending on which completer type the Python function returns, we have to adjust the break characters accordingly. */ - set_gdb_completion_word_break_characters - (completers[value].completer); + brkchars_fn = (completer_handle_brkchars_func_for_completer + (completers[value].completer)); + brkchars_fn (command, tracker, text, word); } } } /* Called by gdb for command completion. */ -static VEC (char_ptr) * +static void cmdpy_completer (struct cmd_list_element *command, + completion_tracker &tracker, const char *text, const char *word) { - VEC (char_ptr) *result = NULL; - gdbpy_enter enter_py (get_current_arch (), current_language); /* Calling our helper to obtain the PyObject of the Python @@ -317,12 +331,10 @@ cmdpy_completer (struct cmd_list_element *command, gdbpy_ref<> resultobj (cmdpy_completer_helper (command, text, word)); /* If the result object of calling the Python function is NULL, it - means that there was an error. In this case, just give up and - return NULL. */ + means that there was an error. In this case, just give up. */ if (resultobj == NULL) - return NULL; + return; - result = NULL; if (PyInt_Check (resultobj.get ())) { /* User code may also return one of the completion constants, @@ -335,15 +347,16 @@ cmdpy_completer (struct cmd_list_element *command, PyErr_Clear (); } else if (value >= 0 && value < (long) N_COMPLETERS) - result = completers[value].completer (command, text, word); + completers[value].completer (command, tracker, text, word); } else { gdbpy_ref<> iter (PyObject_GetIter (resultobj.get ())); if (iter == NULL) - return NULL; + return; + bool got_matches = false; while (true) { gdbpy_ref<> elt (PyIter_Next (iter.get ())); @@ -363,16 +376,15 @@ cmdpy_completer (struct cmd_list_element *command, PyErr_Clear (); continue; } - VEC_safe_push (char_ptr, result, item.release ()); + tracker.add_completion (std::move (item)); + got_matches = true; } /* If we got some results, ignore problems. Otherwise, report the problem. */ - if (result != NULL && PyErr_Occurred ()) + if (got_matches && PyErr_Occurred ()) PyErr_Clear (); } - - return result; } /* Helper for cmdpy_init which locates the command list to use and @@ -763,22 +775,16 @@ gdbpy_string_to_argv (PyObject *self, PyObject *args) if (*input != '\0') { - char **c_argv = gdb_buildargv (input); - int i; + gdb_argv c_argv (input); - for (i = 0; c_argv[i] != NULL; ++i) + for (char *arg : c_argv) { - gdbpy_ref<> argp (PyString_FromString (c_argv[i])); + gdbpy_ref<> argp (PyString_FromString (arg)); if (argp == NULL || PyList_Append (py_argv.get (), argp.get ()) < 0) - { - freeargv (c_argv); - return NULL; - } + return NULL; } - - freeargv (c_argv); } return py_argv.release (); diff --git a/gdb/python/py-param.c b/gdb/python/py-param.c index f0d3423..455c99e 100644 --- a/gdb/python/py-param.c +++ b/gdb/python/py-param.c @@ -555,7 +555,6 @@ static int compute_enum_values (parmpy_object *self, PyObject *enum_values) { Py_ssize_t size, i; - struct cleanup *back_to; if (! enum_values) { @@ -581,36 +580,27 @@ compute_enum_values (parmpy_object *self, PyObject *enum_values) return 0; } - self->enumeration = XCNEWVEC (const char *, size + 1); - back_to = make_cleanup (free_current_contents, &self->enumeration); + gdb_argv holder (XCNEWVEC (char *, size + 1)); + char **enumeration = holder.get (); for (i = 0; i < size; ++i) { gdbpy_ref<> item (PySequence_GetItem (enum_values, i)); if (item == NULL) - { - do_cleanups (back_to); - return 0; - } + return 0; if (! gdbpy_is_string (item.get ())) { - do_cleanups (back_to); PyErr_SetString (PyExc_RuntimeError, _("The enumeration item not a string.")); return 0; } - self->enumeration[i] - = python_string_to_host_string (item.get ()).release (); - if (self->enumeration[i] == NULL) - { - do_cleanups (back_to); - return 0; - } - make_cleanup (xfree, (char *) self->enumeration[i]); + enumeration[i] = python_string_to_host_string (item.get ()).release (); + if (enumeration[i] == NULL) + return 0; } - discard_cleanups (back_to); + self->enumeration = const_cast<const char**> (holder.release ()); return 1; } diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c index aa20d4c..51184ca 100644 --- a/gdb/python/py-type.c +++ b/gdb/python/py-type.c @@ -761,7 +761,6 @@ typy_lookup_type (struct demangle_component *demangled, const struct block *block) { struct type *type, *rtype = NULL; - char *type_name = NULL; enum demangle_component_type demangled_type; /* Save the type: typy_lookup_type() may (indirectly) overwrite @@ -816,11 +815,8 @@ typy_lookup_type (struct demangle_component *demangled, return rtype; /* We don't have a type, so lookup the type. */ - type_name = cp_comp_to_string (demangled, 10); - type = typy_lookup_typename (type_name, block); - xfree (type_name); - - return type; + gdb::unique_xmalloc_ptr<char> type_name = cp_comp_to_string (demangled, 10); + return typy_lookup_typename (type_name.get (), block); } /* This is a helper function for typy_template_argument that is used diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c index 1d800a7..acfce7d 100644 --- a/gdb/python/py-unwind.c +++ b/gdb/python/py-unwind.c @@ -595,7 +595,7 @@ pyuw_dealloc_cache (struct frame_info *this_frame, void *cache) TRACE_PY_UNWIND (3, "%s: enter", __FUNCTION__); cached_frame_info *cached_frame = (cached_frame_info *) cache; - for (int i = 0; cached_frame->reg_count; i++) + for (int i = 0; i < cached_frame->reg_count; i++) xfree (cached_frame->reg[i].data); xfree (cache); diff --git a/gdb/python/py-varobj.c b/gdb/python/py-varobj.c index e858556..5f6ab64 100644 --- a/gdb/python/py-varobj.c +++ b/gdb/python/py-varobj.c @@ -71,7 +71,6 @@ py_varobj_iter_next (struct varobj_iter *self) if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error)) { PyObject *type, *value, *trace; - char *name_str; PyErr_Fetch (&type, &value, &trace); gdb::unique_xmalloc_ptr<char> @@ -85,10 +84,10 @@ py_varobj_iter_next (struct varobj_iter *self) return NULL; } - name_str = xstrprintf ("<error at %d>", - self->next_raw_index++); - item.reset (Py_BuildValue ("(ss)", name_str, value_str.get ())); - xfree (name_str); + std::string name_str = string_printf ("<error at %d>", + self->next_raw_index++); + item.reset (Py_BuildValue ("(ss)", name_str.c_str (), + value_str.get ())); if (item == NULL) { gdbpy_print_stack (); diff --git a/gdb/python/python.c b/gdb/python/python.c index be92f36..c53e10f 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -365,32 +365,19 @@ python_run_simple_file (FILE *file, const char *filename) } /* Given a command_line, return a command string suitable for passing - to Python. Lines in the string are separated by newlines. The - return value is allocated using xmalloc and the caller is - responsible for freeing it. */ + to Python. Lines in the string are separated by newlines. */ -static char * +static std::string compute_python_string (struct command_line *l) { struct command_line *iter; - char *script = NULL; - int size = 0; - int here; + std::string script; for (iter = l; iter; iter = iter->next) - size += strlen (iter->line) + 1; - - script = (char *) xmalloc (size + 1); - here = 0; - for (iter = l; iter; iter = iter->next) { - int len = strlen (iter->line); - - strcpy (&script[here], iter->line); - here += len; - script[here++] = '\n'; + script += iter->line; + script += '\n'; } - script[here] = '\0'; return script; } @@ -402,16 +389,14 @@ gdbpy_eval_from_control_command (const struct extension_language_defn *extlang, struct command_line *cmd) { int ret; - char *script; if (cmd->body_count != 1) error (_("Invalid \"python\" block structure.")); gdbpy_enter enter_py (get_current_arch (), current_language); - script = compute_python_string (cmd->body_list[0]); - ret = PyRun_SimpleString (script); - xfree (script); + std::string script = compute_python_string (cmd->body_list[0]); + ret = PyRun_SimpleString (script.c_str ()); if (ret) error (_("Error while executing Python code.")); } @@ -667,7 +652,6 @@ gdbpy_decode_line (PyObject *self, PyObject *args) appease gcc. */ struct symtab_and_line sal; char *arg = NULL; - struct cleanup *cleanups; gdbpy_ref<> result; gdbpy_ref<> unparsed; event_location_up location; @@ -675,8 +659,6 @@ gdbpy_decode_line (PyObject *self, PyObject *args) if (! PyArg_ParseTuple (args, "|s", &arg)) return NULL; - cleanups = make_cleanup (null_cleanup, NULL); - sals.sals = NULL; if (arg != NULL) @@ -700,12 +682,13 @@ gdbpy_decode_line (PyObject *self, PyObject *args) } END_CATCH + /* Ensure that the sals data is freed, when needed. */ + gdb::unique_xmalloc_ptr<struct symtab_and_line> free_sals; if (sals.sals != NULL && sals.sals != &sal) - make_cleanup (xfree, sals.sals); + free_sals.reset (sals.sals); if (except.reason < 0) { - do_cleanups (cleanups); /* We know this will always throw. */ gdbpy_convert_exception (except); return NULL; @@ -717,20 +700,14 @@ gdbpy_decode_line (PyObject *self, PyObject *args) result.reset (PyTuple_New (sals.nelts)); if (result == NULL) - { - do_cleanups (cleanups); - return NULL; - } + return NULL; for (i = 0; i < sals.nelts; ++i) { PyObject *obj; obj = symtab_and_line_to_sal_object (sals.sals[i]); if (! obj) - { - do_cleanups (cleanups); - return NULL; - } + return NULL; PyTuple_SetItem (result.get (), i, obj); } @@ -743,19 +720,13 @@ gdbpy_decode_line (PyObject *self, PyObject *args) gdbpy_ref<> return_result (PyTuple_New (2)); if (return_result == NULL) - { - do_cleanups (cleanups); - return NULL; - } + return NULL; if (arg != NULL && strlen (arg) > 0) { unparsed.reset (PyString_FromString (arg)); if (unparsed == NULL) - { - do_cleanups (cleanups); - return NULL; - } + return NULL; } else { @@ -766,8 +737,6 @@ gdbpy_decode_line (PyObject *self, PyObject *args) PyTuple_SetItem (return_result.get (), 0, unparsed.release ()); PyTuple_SetItem (return_result.get (), 1, result.release ()); - do_cleanups (cleanups); - return return_result.release (); } @@ -1532,7 +1501,6 @@ do_start_initialization () #ifdef IS_PY3K int i; size_t progsize, count; - char *oldloc; wchar_t *progname_copy; #endif @@ -1546,25 +1514,22 @@ do_start_initialization () progname = concat (ldirname (python_libdir).c_str (), SLASH_STRING, "bin", SLASH_STRING, "python", (char *) NULL); #ifdef IS_PY3K - oldloc = xstrdup (setlocale (LC_ALL, NULL)); + std::string oldloc = setlocale (LC_ALL, NULL); setlocale (LC_ALL, ""); progsize = strlen (progname); progname_copy = (wchar_t *) PyMem_Malloc ((progsize + 1) * sizeof (wchar_t)); if (!progname_copy) { - xfree (oldloc); fprintf (stderr, "out of memory\n"); return false; } count = mbstowcs (progname_copy, progname, progsize + 1); if (count == (size_t) -1) { - xfree (oldloc); fprintf (stderr, "Could not convert python path to string\n"); return false; } - setlocale (LC_ALL, oldloc); - xfree (oldloc); + setlocale (LC_ALL, oldloc.c_str ()); /* Note that Py_SetProgramName expects the string it is passed to remain alive for the duration of the program's execution, so diff --git a/gdb/regcache.c b/gdb/regcache.c index 7eeb737..e8f92d6 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -388,36 +388,9 @@ regcache_cpy (struct regcache *dst, struct regcache *src) gdb_assert (src != NULL && dst != NULL); gdb_assert (src->m_descr->gdbarch == dst->m_descr->gdbarch); gdb_assert (src != dst); - gdb_assert (src->m_readonly_p || dst->m_readonly_p); + gdb_assert (src->m_readonly_p && !dst->m_readonly_p); - if (!src->m_readonly_p) - regcache_save (dst, do_cooked_read, src); - else if (!dst->m_readonly_p) - dst->restore (src); - else - dst->cpy_no_passthrough (src); -} - -/* Copy/duplicate the contents of a register cache. Unlike regcache_cpy, - which is pass-through, this does not go through to the target. - Only values values already in the cache are transferred. The SRC and DST - buffers must not overlap. */ - -void -regcache::cpy_no_passthrough (struct regcache *src) -{ - gdb_assert (src != NULL); - gdb_assert (src->m_descr->gdbarch == m_descr->gdbarch); - /* NOTE: cagney/2002-05-17: Don't let the caller do a no-passthrough - move of data into a thread's regcache. Doing this would be silly - - it would mean that regcache->register_status would be - completely invalid. */ - gdb_assert (m_readonly_p && src->m_readonly_p); - - memcpy (m_registers, src->m_registers, - m_descr->sizeof_cooked_registers); - memcpy (m_register_status, src->m_register_status, - m_descr->sizeof_cooked_register_status); + dst->restore (src); } struct regcache * diff --git a/gdb/regcache.h b/gdb/regcache.h index b416d5e..aa64a00 100644 --- a/gdb/regcache.h +++ b/gdb/regcache.h @@ -369,8 +369,6 @@ private: void restore (struct regcache *src); - void cpy_no_passthrough (struct regcache *src); - enum register_status xfer_part (int regnum, int offset, int len, void *in, const void *out, decltype (regcache_raw_read) read, @@ -415,13 +413,12 @@ private: regcache_cpy (struct regcache *dst, struct regcache *src); }; -/* Copy/duplicate the contents of a register cache. By default, the - operation is pass-through. Writes to DST and reads from SRC will - go through to the target. See also regcache_cpy_no_passthrough. - - regcache_cpy can not have overlapping SRC and DST buffers. */ - +/* Duplicate the contents of a register cache to a read-only register + cache. The operation is pass-through. */ extern struct regcache *regcache_dup (struct regcache *regcache); + +/* Writes to DEST will go through to the target. SRC is a read-only + register cache. */ extern void regcache_cpy (struct regcache *dest, struct regcache *src); extern void registers_changed (void); diff --git a/gdb/regformats/i386/amd64-avx-avx512.dat b/gdb/regformats/i386/amd64-avx-avx512.dat deleted file mode 100644 index b7938e6..0000000 --- a/gdb/regformats/i386/amd64-avx-avx512.dat +++ /dev/null @@ -1,150 +0,0 @@ -# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: -# Generated from: i386/amd64-avx-avx512.xml -name:amd64_avx_avx512 -xmltarget:amd64-avx-avx512.xml -expedite:rbp,rsp,rip -64:rax -64:rbx -64:rcx -64:rdx -64:rsi -64:rdi -64:rbp -64:rsp -64:r8 -64:r9 -64:r10 -64:r11 -64:r12 -64:r13 -64:r14 -64:r15 -64:rip -32:eflags -32:cs -32:ss -32:ds -32:es -32:fs -32:gs -80:st0 -80:st1 -80:st2 -80:st3 -80:st4 -80:st5 -80:st6 -80:st7 -32:fctrl -32:fstat -32:ftag -32:fiseg -32:fioff -32:foseg -32:fooff -32:fop -128:xmm0 -128:xmm1 -128:xmm2 -128:xmm3 -128:xmm4 -128:xmm5 -128:xmm6 -128:xmm7 -128:xmm8 -128:xmm9 -128:xmm10 -128:xmm11 -128:xmm12 -128:xmm13 -128:xmm14 -128:xmm15 -32:mxcsr -128:ymm0h -128:ymm1h -128:ymm2h -128:ymm3h -128:ymm4h -128:ymm5h -128:ymm6h -128:ymm7h -128:ymm8h -128:ymm9h -128:ymm10h -128:ymm11h -128:ymm12h -128:ymm13h -128:ymm14h -128:ymm15h -128:xmm16 -128:xmm17 -128:xmm18 -128:xmm19 -128:xmm20 -128:xmm21 -128:xmm22 -128:xmm23 -128:xmm24 -128:xmm25 -128:xmm26 -128:xmm27 -128:xmm28 -128:xmm29 -128:xmm30 -128:xmm31 -128:ymm16h -128:ymm17h -128:ymm18h -128:ymm19h -128:ymm20h -128:ymm21h -128:ymm22h -128:ymm23h -128:ymm24h -128:ymm25h -128:ymm26h -128:ymm27h -128:ymm28h -128:ymm29h -128:ymm30h -128:ymm31h -64:k0 -64:k1 -64:k2 -64:k3 -64:k4 -64:k5 -64:k6 -64:k7 -256:zmm0h -256:zmm1h -256:zmm2h -256:zmm3h -256:zmm4h -256:zmm5h -256:zmm6h -256:zmm7h -256:zmm8h -256:zmm9h -256:zmm10h -256:zmm11h -256:zmm12h -256:zmm13h -256:zmm14h -256:zmm15h -256:zmm16h -256:zmm17h -256:zmm18h -256:zmm19h -256:zmm20h -256:zmm21h -256:zmm22h -256:zmm23h -256:zmm24h -256:zmm25h -256:zmm26h -256:zmm27h -256:zmm28h -256:zmm29h -256:zmm30h -256:zmm31h diff --git a/gdb/regformats/i386/amd64-avx-mpx-avx512-pku.dat b/gdb/regformats/i386/amd64-avx-mpx-avx512-pku.dat deleted file mode 100644 index b3340d3..0000000 --- a/gdb/regformats/i386/amd64-avx-mpx-avx512-pku.dat +++ /dev/null @@ -1,157 +0,0 @@ -# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: -# Generated from: i386/amd64-avx-mpx-avx512-pku.xml -name:amd64_avx_mpx_avx512_pku -xmltarget:amd64-avx-mpx-avx512-pku.xml -expedite:rbp,rsp,rip -64:rax -64:rbx -64:rcx -64:rdx -64:rsi -64:rdi -64:rbp -64:rsp -64:r8 -64:r9 -64:r10 -64:r11 -64:r12 -64:r13 -64:r14 -64:r15 -64:rip -32:eflags -32:cs -32:ss -32:ds -32:es -32:fs -32:gs -80:st0 -80:st1 -80:st2 -80:st3 -80:st4 -80:st5 -80:st6 -80:st7 -32:fctrl -32:fstat -32:ftag -32:fiseg -32:fioff -32:foseg -32:fooff -32:fop -128:xmm0 -128:xmm1 -128:xmm2 -128:xmm3 -128:xmm4 -128:xmm5 -128:xmm6 -128:xmm7 -128:xmm8 -128:xmm9 -128:xmm10 -128:xmm11 -128:xmm12 -128:xmm13 -128:xmm14 -128:xmm15 -32:mxcsr -128:ymm0h -128:ymm1h -128:ymm2h -128:ymm3h -128:ymm4h -128:ymm5h -128:ymm6h -128:ymm7h -128:ymm8h -128:ymm9h -128:ymm10h -128:ymm11h -128:ymm12h -128:ymm13h -128:ymm14h -128:ymm15h -128:bnd0raw -128:bnd1raw -128:bnd2raw -128:bnd3raw -64:bndcfgu -64:bndstatus -128:xmm16 -128:xmm17 -128:xmm18 -128:xmm19 -128:xmm20 -128:xmm21 -128:xmm22 -128:xmm23 -128:xmm24 -128:xmm25 -128:xmm26 -128:xmm27 -128:xmm28 -128:xmm29 -128:xmm30 -128:xmm31 -128:ymm16h -128:ymm17h -128:ymm18h -128:ymm19h -128:ymm20h -128:ymm21h -128:ymm22h -128:ymm23h -128:ymm24h -128:ymm25h -128:ymm26h -128:ymm27h -128:ymm28h -128:ymm29h -128:ymm30h -128:ymm31h -64:k0 -64:k1 -64:k2 -64:k3 -64:k4 -64:k5 -64:k6 -64:k7 -256:zmm0h -256:zmm1h -256:zmm2h -256:zmm3h -256:zmm4h -256:zmm5h -256:zmm6h -256:zmm7h -256:zmm8h -256:zmm9h -256:zmm10h -256:zmm11h -256:zmm12h -256:zmm13h -256:zmm14h -256:zmm15h -256:zmm16h -256:zmm17h -256:zmm18h -256:zmm19h -256:zmm20h -256:zmm21h -256:zmm22h -256:zmm23h -256:zmm24h -256:zmm25h -256:zmm26h -256:zmm27h -256:zmm28h -256:zmm29h -256:zmm30h -256:zmm31h -32:pkru diff --git a/gdb/regformats/i386/amd64-avx-mpx.dat b/gdb/regformats/i386/amd64-avx-mpx.dat deleted file mode 100644 index d985641..0000000 --- a/gdb/regformats/i386/amd64-avx-mpx.dat +++ /dev/null @@ -1,84 +0,0 @@ -# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: -# Generated from: i386/amd64-avx-mpx.xml -name:amd64_avx_mpx -xmltarget:amd64-avx-mpx.xml -expedite:rbp,rsp,rip -64:rax -64:rbx -64:rcx -64:rdx -64:rsi -64:rdi -64:rbp -64:rsp -64:r8 -64:r9 -64:r10 -64:r11 -64:r12 -64:r13 -64:r14 -64:r15 -64:rip -32:eflags -32:cs -32:ss -32:ds -32:es -32:fs -32:gs -80:st0 -80:st1 -80:st2 -80:st3 -80:st4 -80:st5 -80:st6 -80:st7 -32:fctrl -32:fstat -32:ftag -32:fiseg -32:fioff -32:foseg -32:fooff -32:fop -128:xmm0 -128:xmm1 -128:xmm2 -128:xmm3 -128:xmm4 -128:xmm5 -128:xmm6 -128:xmm7 -128:xmm8 -128:xmm9 -128:xmm10 -128:xmm11 -128:xmm12 -128:xmm13 -128:xmm14 -128:xmm15 -32:mxcsr -128:ymm0h -128:ymm1h -128:ymm2h -128:ymm3h -128:ymm4h -128:ymm5h -128:ymm6h -128:ymm7h -128:ymm8h -128:ymm9h -128:ymm10h -128:ymm11h -128:ymm12h -128:ymm13h -128:ymm14h -128:ymm15h -128:bnd0raw -128:bnd1raw -128:bnd2raw -128:bnd3raw -64:bndcfgu -64:bndstatus diff --git a/gdb/regformats/i386/amd64-avx.dat b/gdb/regformats/i386/amd64-avx.dat deleted file mode 100644 index 2232336..0000000 --- a/gdb/regformats/i386/amd64-avx.dat +++ /dev/null @@ -1,78 +0,0 @@ -# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: -# Generated from: i386/amd64-avx.xml -name:amd64_avx -xmltarget:amd64-avx.xml -expedite:rbp,rsp,rip -64:rax -64:rbx -64:rcx -64:rdx -64:rsi -64:rdi -64:rbp -64:rsp -64:r8 -64:r9 -64:r10 -64:r11 -64:r12 -64:r13 -64:r14 -64:r15 -64:rip -32:eflags -32:cs -32:ss -32:ds -32:es -32:fs -32:gs -80:st0 -80:st1 -80:st2 -80:st3 -80:st4 -80:st5 -80:st6 -80:st7 -32:fctrl -32:fstat -32:ftag -32:fiseg -32:fioff -32:foseg -32:fooff -32:fop -128:xmm0 -128:xmm1 -128:xmm2 -128:xmm3 -128:xmm4 -128:xmm5 -128:xmm6 -128:xmm7 -128:xmm8 -128:xmm9 -128:xmm10 -128:xmm11 -128:xmm12 -128:xmm13 -128:xmm14 -128:xmm15 -32:mxcsr -128:ymm0h -128:ymm1h -128:ymm2h -128:ymm3h -128:ymm4h -128:ymm5h -128:ymm6h -128:ymm7h -128:ymm8h -128:ymm9h -128:ymm10h -128:ymm11h -128:ymm12h -128:ymm13h -128:ymm14h -128:ymm15h diff --git a/gdb/regformats/i386/amd64-mpx.dat b/gdb/regformats/i386/amd64-mpx.dat deleted file mode 100644 index 43b8776..0000000 --- a/gdb/regformats/i386/amd64-mpx.dat +++ /dev/null @@ -1,68 +0,0 @@ -# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: -# Generated from: i386/amd64-mpx.xml -name:amd64_mpx -xmltarget:amd64-mpx.xml -expedite:rbp,rsp,rip -64:rax -64:rbx -64:rcx -64:rdx -64:rsi -64:rdi -64:rbp -64:rsp -64:r8 -64:r9 -64:r10 -64:r11 -64:r12 -64:r13 -64:r14 -64:r15 -64:rip -32:eflags -32:cs -32:ss -32:ds -32:es -32:fs -32:gs -80:st0 -80:st1 -80:st2 -80:st3 -80:st4 -80:st5 -80:st6 -80:st7 -32:fctrl -32:fstat -32:ftag -32:fiseg -32:fioff -32:foseg -32:fooff -32:fop -128:xmm0 -128:xmm1 -128:xmm2 -128:xmm3 -128:xmm4 -128:xmm5 -128:xmm6 -128:xmm7 -128:xmm8 -128:xmm9 -128:xmm10 -128:xmm11 -128:xmm12 -128:xmm13 -128:xmm14 -128:xmm15 -32:mxcsr -128:bnd0raw -128:bnd1raw -128:bnd2raw -128:bnd3raw -64:bndcfgu -64:bndstatus diff --git a/gdb/regformats/i386/amd64.dat b/gdb/regformats/i386/amd64.dat index 0ff9170..66f26ad 100644 --- a/gdb/regformats/i386/amd64.dat +++ b/gdb/regformats/i386/amd64.dat @@ -60,3 +60,5 @@ expedite:rbp,rsp,rip 128:xmm14 128:xmm15 32:mxcsr +64:fs_base +64:gs_base diff --git a/gdb/regformats/i386/i386-avx-avx512.dat b/gdb/regformats/i386/i386-avx-avx512.dat deleted file mode 100644 index 45b6f6c..0000000 --- a/gdb/regformats/i386/i386-avx-avx512.dat +++ /dev/null @@ -1,70 +0,0 @@ -# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: -# Generated from: i386/i386-avx-avx512.xml -name:i386_avx_avx512 -xmltarget:i386-avx-avx512.xml -expedite:ebp,esp,eip -32:eax -32:ecx -32:edx -32:ebx -32:esp -32:ebp -32:esi -32:edi -32:eip -32:eflags -32:cs -32:ss -32:ds -32:es -32:fs -32:gs -80:st0 -80:st1 -80:st2 -80:st3 -80:st4 -80:st5 -80:st6 -80:st7 -32:fctrl -32:fstat -32:ftag -32:fiseg -32:fioff -32:foseg -32:fooff -32:fop -128:xmm0 -128:xmm1 -128:xmm2 -128:xmm3 -128:xmm4 -128:xmm5 -128:xmm6 -128:xmm7 -32:mxcsr -128:ymm0h -128:ymm1h -128:ymm2h -128:ymm3h -128:ymm4h -128:ymm5h -128:ymm6h -128:ymm7h -64:k0 -64:k1 -64:k2 -64:k3 -64:k4 -64:k5 -64:k6 -64:k7 -256:zmm0h -256:zmm1h -256:zmm2h -256:zmm3h -256:zmm4h -256:zmm5h -256:zmm6h -256:zmm7h diff --git a/gdb/regformats/i386/i386-avx-mpx-avx512-pku.dat b/gdb/regformats/i386/i386-avx-mpx-avx512-pku.dat deleted file mode 100644 index 17094b4..0000000 --- a/gdb/regformats/i386/i386-avx-mpx-avx512-pku.dat +++ /dev/null @@ -1,77 +0,0 @@ -# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: -# Generated from: i386/i386-avx-mpx-avx512-pku.xml -name:i386_avx_mpx_avx512_pku -xmltarget:i386-avx-mpx-avx512-pku.xml -expedite:ebp,esp,eip -32:eax -32:ecx -32:edx -32:ebx -32:esp -32:ebp -32:esi -32:edi -32:eip -32:eflags -32:cs -32:ss -32:ds -32:es -32:fs -32:gs -80:st0 -80:st1 -80:st2 -80:st3 -80:st4 -80:st5 -80:st6 -80:st7 -32:fctrl -32:fstat -32:ftag -32:fiseg -32:fioff -32:foseg -32:fooff -32:fop -128:xmm0 -128:xmm1 -128:xmm2 -128:xmm3 -128:xmm4 -128:xmm5 -128:xmm6 -128:xmm7 -32:mxcsr -128:ymm0h -128:ymm1h -128:ymm2h -128:ymm3h -128:ymm4h -128:ymm5h -128:ymm6h -128:ymm7h -128:bnd0raw -128:bnd1raw -128:bnd2raw -128:bnd3raw -64:bndcfgu -64:bndstatus -64:k0 -64:k1 -64:k2 -64:k3 -64:k4 -64:k5 -64:k6 -64:k7 -256:zmm0h -256:zmm1h -256:zmm2h -256:zmm3h -256:zmm4h -256:zmm5h -256:zmm6h -256:zmm7h -32:pkru diff --git a/gdb/regformats/i386/i386-avx-mpx.dat b/gdb/regformats/i386/i386-avx-mpx.dat deleted file mode 100644 index 8caef75..0000000 --- a/gdb/regformats/i386/i386-avx-mpx.dat +++ /dev/null @@ -1,60 +0,0 @@ -# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: -# Generated from: i386/i386-avx-mpx.xml -name:i386_avx_mpx -xmltarget:i386-avx-mpx.xml -expedite:ebp,esp,eip -32:eax -32:ecx -32:edx -32:ebx -32:esp -32:ebp -32:esi -32:edi -32:eip -32:eflags -32:cs -32:ss -32:ds -32:es -32:fs -32:gs -80:st0 -80:st1 -80:st2 -80:st3 -80:st4 -80:st5 -80:st6 -80:st7 -32:fctrl -32:fstat -32:ftag -32:fiseg -32:fioff -32:foseg -32:fooff -32:fop -128:xmm0 -128:xmm1 -128:xmm2 -128:xmm3 -128:xmm4 -128:xmm5 -128:xmm6 -128:xmm7 -32:mxcsr -128:ymm0h -128:ymm1h -128:ymm2h -128:ymm3h -128:ymm4h -128:ymm5h -128:ymm6h -128:ymm7h -128:bnd0raw -128:bnd1raw -128:bnd2raw -128:bnd3raw -64:bndcfgu -64:bndstatus diff --git a/gdb/regformats/i386/i386-mmx.dat b/gdb/regformats/i386/i386-mmx.dat deleted file mode 100644 index 2d2ba85..0000000 --- a/gdb/regformats/i386/i386-mmx.dat +++ /dev/null @@ -1,37 +0,0 @@ -# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: -# Generated from: i386/i386-mmx.xml -name:i386_mmx -xmltarget:i386-mmx.xml -expedite:ebp,esp,eip -32:eax -32:ecx -32:edx -32:ebx -32:esp -32:ebp -32:esi -32:edi -32:eip -32:eflags -32:cs -32:ss -32:ds -32:es -32:fs -32:gs -80:st0 -80:st1 -80:st2 -80:st3 -80:st4 -80:st5 -80:st6 -80:st7 -32:fctrl -32:fstat -32:ftag -32:fiseg -32:fioff -32:foseg -32:fooff -32:fop diff --git a/gdb/regformats/i386/i386-mpx.dat b/gdb/regformats/i386/i386-mpx.dat deleted file mode 100644 index dda5164..0000000 --- a/gdb/regformats/i386/i386-mpx.dat +++ /dev/null @@ -1,52 +0,0 @@ -# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: -# Generated from: i386/i386-mpx.xml -name:i386_mpx -xmltarget:i386-mpx.xml -expedite:ebp,esp,eip -32:eax -32:ecx -32:edx -32:ebx -32:esp -32:ebp -32:esi -32:edi -32:eip -32:eflags -32:cs -32:ss -32:ds -32:es -32:fs -32:gs -80:st0 -80:st1 -80:st2 -80:st3 -80:st4 -80:st5 -80:st6 -80:st7 -32:fctrl -32:fstat -32:ftag -32:fiseg -32:fioff -32:foseg -32:fooff -32:fop -128:xmm0 -128:xmm1 -128:xmm2 -128:xmm3 -128:xmm4 -128:xmm5 -128:xmm6 -128:xmm7 -32:mxcsr -128:bnd0raw -128:bnd1raw -128:bnd2raw -128:bnd3raw -64:bndcfgu -64:bndstatus diff --git a/gdb/regformats/i386/x32-avx-avx512.dat b/gdb/regformats/i386/x32-avx-avx512.dat deleted file mode 100644 index 3f96035..0000000 --- a/gdb/regformats/i386/x32-avx-avx512.dat +++ /dev/null @@ -1,150 +0,0 @@ -# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: -# Generated from: i386/x32-avx-avx512.xml -name:x32_avx_avx512 -xmltarget:x32-avx-avx512.xml -expedite:rbp,rsp,rip -64:rax -64:rbx -64:rcx -64:rdx -64:rsi -64:rdi -64:rbp -64:rsp -64:r8 -64:r9 -64:r10 -64:r11 -64:r12 -64:r13 -64:r14 -64:r15 -64:rip -32:eflags -32:cs -32:ss -32:ds -32:es -32:fs -32:gs -80:st0 -80:st1 -80:st2 -80:st3 -80:st4 -80:st5 -80:st6 -80:st7 -32:fctrl -32:fstat -32:ftag -32:fiseg -32:fioff -32:foseg -32:fooff -32:fop -128:xmm0 -128:xmm1 -128:xmm2 -128:xmm3 -128:xmm4 -128:xmm5 -128:xmm6 -128:xmm7 -128:xmm8 -128:xmm9 -128:xmm10 -128:xmm11 -128:xmm12 -128:xmm13 -128:xmm14 -128:xmm15 -32:mxcsr -128:ymm0h -128:ymm1h -128:ymm2h -128:ymm3h -128:ymm4h -128:ymm5h -128:ymm6h -128:ymm7h -128:ymm8h -128:ymm9h -128:ymm10h -128:ymm11h -128:ymm12h -128:ymm13h -128:ymm14h -128:ymm15h -128:xmm16 -128:xmm17 -128:xmm18 -128:xmm19 -128:xmm20 -128:xmm21 -128:xmm22 -128:xmm23 -128:xmm24 -128:xmm25 -128:xmm26 -128:xmm27 -128:xmm28 -128:xmm29 -128:xmm30 -128:xmm31 -128:ymm16h -128:ymm17h -128:ymm18h -128:ymm19h -128:ymm20h -128:ymm21h -128:ymm22h -128:ymm23h -128:ymm24h -128:ymm25h -128:ymm26h -128:ymm27h -128:ymm28h -128:ymm29h -128:ymm30h -128:ymm31h -64:k0 -64:k1 -64:k2 -64:k3 -64:k4 -64:k5 -64:k6 -64:k7 -256:zmm0h -256:zmm1h -256:zmm2h -256:zmm3h -256:zmm4h -256:zmm5h -256:zmm6h -256:zmm7h -256:zmm8h -256:zmm9h -256:zmm10h -256:zmm11h -256:zmm12h -256:zmm13h -256:zmm14h -256:zmm15h -256:zmm16h -256:zmm17h -256:zmm18h -256:zmm19h -256:zmm20h -256:zmm21h -256:zmm22h -256:zmm23h -256:zmm24h -256:zmm25h -256:zmm26h -256:zmm27h -256:zmm28h -256:zmm29h -256:zmm30h -256:zmm31h diff --git a/gdb/regformats/i386/x32-avx.dat b/gdb/regformats/i386/x32-avx.dat deleted file mode 100644 index d367412..0000000 --- a/gdb/regformats/i386/x32-avx.dat +++ /dev/null @@ -1,78 +0,0 @@ -# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: -# Generated from: i386/x32-avx.xml -name:x32_avx -xmltarget:x32-avx.xml -expedite:rbp,rsp,rip -64:rax -64:rbx -64:rcx -64:rdx -64:rsi -64:rdi -64:rbp -64:rsp -64:r8 -64:r9 -64:r10 -64:r11 -64:r12 -64:r13 -64:r14 -64:r15 -64:rip -32:eflags -32:cs -32:ss -32:ds -32:es -32:fs -32:gs -80:st0 -80:st1 -80:st2 -80:st3 -80:st4 -80:st5 -80:st6 -80:st7 -32:fctrl -32:fstat -32:ftag -32:fiseg -32:fioff -32:foseg -32:fooff -32:fop -128:xmm0 -128:xmm1 -128:xmm2 -128:xmm3 -128:xmm4 -128:xmm5 -128:xmm6 -128:xmm7 -128:xmm8 -128:xmm9 -128:xmm10 -128:xmm11 -128:xmm12 -128:xmm13 -128:xmm14 -128:xmm15 -32:mxcsr -128:ymm0h -128:ymm1h -128:ymm2h -128:ymm3h -128:ymm4h -128:ymm5h -128:ymm6h -128:ymm7h -128:ymm8h -128:ymm9h -128:ymm10h -128:ymm11h -128:ymm12h -128:ymm13h -128:ymm14h -128:ymm15h diff --git a/gdb/regformats/i386/x32.dat b/gdb/regformats/i386/x32.dat deleted file mode 100644 index 99e6ad3..0000000 --- a/gdb/regformats/i386/x32.dat +++ /dev/null @@ -1,62 +0,0 @@ -# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: -# Generated from: i386/x32.xml -name:x32 -xmltarget:x32.xml -expedite:rbp,rsp,rip -64:rax -64:rbx -64:rcx -64:rdx -64:rsi -64:rdi -64:rbp -64:rsp -64:r8 -64:r9 -64:r10 -64:r11 -64:r12 -64:r13 -64:r14 -64:r15 -64:rip -32:eflags -32:cs -32:ss -32:ds -32:es -32:fs -32:gs -80:st0 -80:st1 -80:st2 -80:st3 -80:st4 -80:st5 -80:st6 -80:st7 -32:fctrl -32:fstat -32:ftag -32:fiseg -32:fioff -32:foseg -32:fooff -32:fop -128:xmm0 -128:xmm1 -128:xmm2 -128:xmm3 -128:xmm4 -128:xmm5 -128:xmm6 -128:xmm7 -128:xmm8 -128:xmm9 -128:xmm10 -128:xmm11 -128:xmm12 -128:xmm13 -128:xmm14 -128:xmm15 -32:mxcsr diff --git a/gdb/regformats/regdat.sh b/gdb/regformats/regdat.sh index 4c73352..651f703 100755 --- a/gdb/regformats/regdat.sh +++ b/gdb/regformats/regdat.sh @@ -179,8 +179,11 @@ init_registers_${name} (void) result->reg_defs = regs_${name}; result->num_registers = sizeof (regs_${name}) / sizeof (regs_${name}[0]); + +#ifndef IN_PROCESS_AGENT result->expedite_regs = expedite_regs_${name}; result->xmltarget = xmltarget_${name}; +#endif init_target_desc (result); diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c index fd1bc66..ca824d7 100644 --- a/gdb/remote-sim.c +++ b/gdb/remote-sim.c @@ -40,6 +40,7 @@ #include "arch-utils.h" #include "readline/readline.h" #include "gdbthread.h" +#include "common/byte-vector.h" /* Prototypes */ @@ -448,38 +449,31 @@ gdbsim_fetch_register (struct target_ops *ops, { /* For moment treat a `does not exist' register the same way as an ``unavailable'' register. */ - gdb_byte buf[MAX_REGISTER_SIZE]; - int nr_bytes; - - memset (buf, 0, MAX_REGISTER_SIZE); - regcache_raw_supply (regcache, regno, buf); + regcache->raw_supply_zeroed (regno); break; } default: { static int warn_user = 1; - gdb_byte buf[MAX_REGISTER_SIZE]; + int regsize = register_size (gdbarch, regno); + gdb::byte_vector buf (regsize, 0); int nr_bytes; gdb_assert (regno >= 0 && regno < gdbarch_num_regs (gdbarch)); - memset (buf, 0, MAX_REGISTER_SIZE); nr_bytes = sim_fetch_register (sim_data->gdbsim_desc, gdbarch_register_sim_regno (gdbarch, regno), - buf, - register_size (gdbarch, regno)); - if (nr_bytes > 0 - && nr_bytes != register_size (gdbarch, regno) && warn_user) + buf.data (), regsize); + if (nr_bytes > 0 && nr_bytes != regsize && warn_user) { fprintf_unfiltered (gdb_stderr, "Size of register %s (%d/%d) " "incorrect (%d instead of %d))", gdbarch_register_name (gdbarch, regno), regno, - gdbarch_register_sim_regno - (gdbarch, regno), - nr_bytes, register_size (gdbarch, regno)); + gdbarch_register_sim_regno (gdbarch, regno), + nr_bytes, regsize); warn_user = 0; } /* FIXME: cagney/2002-05-27: Should check `nr_bytes == 0' @@ -487,13 +481,13 @@ gdbsim_fetch_register (struct target_ops *ops, which registers are fetchable. */ /* Else if (nr_bytes < 0): an old simulator, that doesn't think to return the register size. Just assume all is ok. */ - regcache_raw_supply (regcache, regno, buf); + regcache->raw_supply (regno, buf.data ()); if (remote_debug) { fprintf_unfiltered (gdb_stdlog, "gdbsim_fetch_register: %d", regno); /* FIXME: We could print something more intelligible. */ - dump_mem (buf, register_size (gdbarch, regno)); + dump_mem (buf.data (), regsize); } break; } @@ -518,15 +512,17 @@ gdbsim_store_register (struct target_ops *ops, } else if (gdbarch_register_sim_regno (gdbarch, regno) >= 0) { - gdb_byte tmp[MAX_REGISTER_SIZE]; + int regsize = register_size (gdbarch, regno); + gdb::byte_vector tmp (regsize); int nr_bytes; - regcache_cooked_read (regcache, regno, tmp); + regcache->cooked_read (regno, tmp.data ()); nr_bytes = sim_store_register (sim_data->gdbsim_desc, gdbarch_register_sim_regno (gdbarch, regno), - tmp, register_size (gdbarch, regno)); - if (nr_bytes > 0 && nr_bytes != register_size (gdbarch, regno)) + tmp.data (), regsize); + + if (nr_bytes > 0 && nr_bytes != regsize) internal_error (__FILE__, __LINE__, _("Register size different to expected")); if (nr_bytes < 0) @@ -540,7 +536,7 @@ gdbsim_store_register (struct target_ops *ops, { fprintf_unfiltered (gdb_stdlog, "gdbsim_store_register: %d", regno); /* FIXME: We could print something more intelligible. */ - dump_mem (tmp, register_size (gdbarch, regno)); + dump_mem (tmp.data (), regsize); } } } @@ -566,7 +562,6 @@ gdbsim_kill (struct target_ops *ops) static void gdbsim_load (struct target_ops *self, const char *args, int fromtty) { - char **argv; const char *prog; struct sim_inferior_data *sim_data = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED); @@ -574,8 +569,7 @@ gdbsim_load (struct target_ops *self, const char *args, int fromtty) if (args == NULL) error_no_arg (_("program to load")); - argv = gdb_buildargv (args); - make_cleanup_freeargv (argv); + gdb_argv argv (args); prog = tilde_expand (argv[0]); @@ -613,7 +607,7 @@ gdbsim_create_inferior (struct target_ops *target, const char *exec_file, struct sim_inferior_data *sim_data = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED); int len; - char *arg_buf, **argv; + char *arg_buf; const char *args = allargs.c_str (); if (exec_file == 0 || exec_bfd == 0) @@ -632,6 +626,7 @@ gdbsim_create_inferior (struct target_ops *target, const char *exec_file, remove_breakpoints (); init_wait_for_inferior (); + gdb_argv built_argv; if (exec_file != NULL) { len = strlen (exec_file) + 1 + allargs.size () + 1 + /*slop */ 10; @@ -640,16 +635,14 @@ gdbsim_create_inferior (struct target_ops *target, const char *exec_file, strcat (arg_buf, exec_file); strcat (arg_buf, " "); strcat (arg_buf, args); - argv = gdb_buildargv (arg_buf); - make_cleanup_freeargv (argv); + built_argv.reset (arg_buf); } - else - argv = NULL; if (!have_inferiors ()) init_thread_list (); - if (sim_create_inferior (sim_data->gdbsim_desc, exec_bfd, argv, env) + if (sim_create_inferior (sim_data->gdbsim_desc, exec_bfd, + built_argv.get (), env) != SIM_RC_OK) error (_("Unable to create sim inferior.")); @@ -732,18 +725,21 @@ gdbsim_open (const char *args, int from_tty) strcat (arg_buf, " "); /* 1 */ strcat (arg_buf, args); } - sim_argv = gdb_buildargv (arg_buf); + + gdb_argv argv (arg_buf); + sim_argv = argv.get (); init_callbacks (); gdbsim_desc = sim_open (SIM_OPEN_DEBUG, &gdb_callback, exec_bfd, sim_argv); if (gdbsim_desc == 0) { - freeargv (sim_argv); sim_argv = NULL; error (_("unable to create simulator instance")); } + argv.release (); + /* Reset the pid numberings for this batch of sim instances. */ next_pid = INITIAL_PID; @@ -1224,30 +1220,48 @@ simulator_command (char *args, int from_tty) registers_changed (); } -static VEC (char_ptr) * -sim_command_completer (struct cmd_list_element *ignore, const char *text, - const char *word) +static void +sim_command_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, + const char *text, const char *word) { struct sim_inferior_data *sim_data; - char **tmp; - int i; - VEC (char_ptr) *result = NULL; sim_data = ((struct sim_inferior_data *) inferior_data (current_inferior (), sim_inferior_data_key)); if (sim_data == NULL || sim_data->gdbsim_desc == NULL) - return NULL; + return; - tmp = sim_complete_command (sim_data->gdbsim_desc, text, word); - if (tmp == NULL) - return NULL; + /* sim_complete_command returns a NULL-terminated malloc'ed array of + malloc'ed strings. */ + struct sim_completions_deleter + { + void operator() (char **ptr) const + { + for (size_t i = 0; ptr[i] != NULL; i++) + xfree (ptr[i]); + xfree (ptr); + } + }; + + std::unique_ptr<char *[], sim_completions_deleter> sim_completions + (sim_complete_command (sim_data->gdbsim_desc, text, word)); + if (sim_completions == NULL) + return; - /* Transform the array into a VEC, and then free the array. */ - for (i = 0; tmp[i] != NULL; i++) - VEC_safe_push (char_ptr, result, tmp[i]); - xfree (tmp); + /* Count the elements and add completions from tail to head because + below we'll swap elements out of the array in case add_completion + throws and the deleter deletes until it finds a NULL element. */ + size_t count = 0; + while (sim_completions[count] != NULL) + count++; - return result; + for (size_t i = count; i > 0; i--) + { + gdb::unique_xmalloc_ptr<char> match (sim_completions[i - 1]); + sim_completions[i - 1] = NULL; + tracker.add_completion (std::move (match)); + } } /* Check to see if a thread is still alive. */ diff --git a/gdb/remote.c b/gdb/remote.c index 8e8ee6f..ff59a0f 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -72,6 +72,7 @@ #include "btrace.h" #include "record-btrace.h" #include <algorithm> +#include "common/scoped_restore.h" /* Temp hacks for tracepoint encoding migration. */ static char *target_buf; @@ -7844,8 +7845,6 @@ store_registers_using_G (const struct regcache *regcache) each byte encoded as two hex characters. */ p = rs->buf; *p++ = 'G'; - /* remote_prepare_to_store insures that rsa->sizeof_g_packet gets - updated. */ bin2hex (regs, p, rsa->sizeof_g_packet); putpkt (rs->buf); getpkt (&rs->buf, &rs->buf_size, 0); @@ -8471,14 +8470,6 @@ remote_send_printf (const char *format, ...) return packet_check_result (rs->buf); } -static void -restore_remote_timeout (void *p) -{ - int value = *(int *)p; - - remote_timeout = value; -} - /* Flash writing can take quite some time. We'll set effectively infinite timeout for flash operations. In future, we'll need to decide on a better approach. */ @@ -8489,12 +8480,9 @@ remote_flash_erase (struct target_ops *ops, ULONGEST address, LONGEST length) { int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8; - int saved_remote_timeout = remote_timeout; enum packet_result ret; - struct cleanup *back_to = make_cleanup (restore_remote_timeout, - &saved_remote_timeout); - - remote_timeout = remote_flash_timeout; + scoped_restore restore_timeout + = make_scoped_restore (&remote_timeout, remote_flash_timeout); ret = remote_send_printf ("vFlashErase:%s,%s", phex (address, addr_size), @@ -8508,8 +8496,6 @@ remote_flash_erase (struct target_ops *ops, default: break; } - - do_cleanups (back_to); } static enum target_xfer_status @@ -8517,30 +8503,21 @@ remote_flash_write (struct target_ops *ops, ULONGEST address, ULONGEST length, ULONGEST *xfered_len, const gdb_byte *data) { - int saved_remote_timeout = remote_timeout; - enum target_xfer_status ret; - struct cleanup *back_to = make_cleanup (restore_remote_timeout, - &saved_remote_timeout); - - remote_timeout = remote_flash_timeout; - ret = remote_write_bytes_aux ("vFlashWrite:", address, data, length, 1, - xfered_len,'X', 0); - do_cleanups (back_to); - - return ret; + scoped_restore restore_timeout + = make_scoped_restore (&remote_timeout, remote_flash_timeout); + return remote_write_bytes_aux ("vFlashWrite:", address, data, length, 1, + xfered_len,'X', 0); } static void remote_flash_done (struct target_ops *ops) { - int saved_remote_timeout = remote_timeout; int ret; - struct cleanup *back_to = make_cleanup (restore_remote_timeout, - &saved_remote_timeout); - remote_timeout = remote_flash_timeout; + scoped_restore restore_timeout + = make_scoped_restore (&remote_timeout, remote_flash_timeout); + ret = remote_send_printf ("vFlashDone"); - do_cleanups (back_to); switch (ret) { @@ -8588,18 +8565,18 @@ readchar (int timeout) { int ch; struct remote_state *rs = get_remote_state (); - struct cleanup *old_chain; - old_chain = make_cleanup_override_quit_handler (remote_serial_quit_handler); + { + scoped_restore restore_quit + = make_scoped_restore (&quit_handler, remote_serial_quit_handler); - rs->got_ctrlc_during_io = 0; + rs->got_ctrlc_during_io = 0; - ch = serial_readchar (rs->remote_desc, timeout); + ch = serial_readchar (rs->remote_desc, timeout); - if (rs->got_ctrlc_during_io) - set_quit_flag (); - - do_cleanups (old_chain); + if (rs->got_ctrlc_during_io) + set_quit_flag (); + } if (ch >= 0) return ch; @@ -8630,9 +8607,9 @@ static void remote_serial_write (const char *str, int len) { struct remote_state *rs = get_remote_state (); - struct cleanup *old_chain; - old_chain = make_cleanup_override_quit_handler (remote_serial_quit_handler); + scoped_restore restore_quit + = make_scoped_restore (&quit_handler, remote_serial_quit_handler); rs->got_ctrlc_during_io = 0; @@ -8644,8 +8621,6 @@ remote_serial_write (const char *str, int len) if (rs->got_ctrlc_during_io) set_quit_flag (); - - do_cleanups (old_chain); } /* Send the command in *BUF to the remote machine, and read the reply @@ -9544,12 +9519,9 @@ extended_remote_run (const std::string &args) if (!args.empty ()) { - struct cleanup *back_to; int i; - char **argv; - argv = gdb_buildargv (args.c_str ()); - back_to = make_cleanup_freeargv (argv); + gdb_argv argv (args.c_str ()); for (i = 0; argv[i] != NULL; i++) { if (strlen (argv[i]) * 2 + 1 + len >= get_remote_packet_size ()) @@ -9558,7 +9530,6 @@ extended_remote_run (const std::string &args) len += 2 * bin2hex ((gdb_byte *) argv[i], rs->buf + len, strlen (argv[i])); } - do_cleanups (back_to); } rs->buf[len++] = '\0'; @@ -11904,7 +11875,6 @@ remote_file_put (const char *local_file, const char *remote_file, int from_tty) { struct cleanup *back_to, *close_cleanup; int retcode, fd, remote_errno, bytes, io_size; - FILE *file; gdb_byte *buffer; int bytes_in_buffer; int saw_eof; @@ -11914,10 +11884,9 @@ remote_file_put (const char *local_file, const char *remote_file, int from_tty) if (!rs->remote_desc) error (_("command can only be used with remote target")); - file = gdb_fopen_cloexec (local_file, "rb"); + gdb_file_up file = gdb_fopen_cloexec (local_file, "rb"); if (file == NULL) perror_with_name (local_file); - back_to = make_cleanup_fclose (file); fd = remote_hostio_open (find_target_at (process_stratum), NULL, remote_file, (FILEIO_O_WRONLY | FILEIO_O_CREAT @@ -11930,7 +11899,7 @@ remote_file_put (const char *local_file, const char *remote_file, int from_tty) remote packet limit, so we'll transfer slightly fewer. */ io_size = get_remote_packet_size (); buffer = (gdb_byte *) xmalloc (io_size); - make_cleanup (xfree, buffer); + back_to = make_cleanup (xfree, buffer); close_cleanup = make_cleanup (remote_hostio_close_cleanup, &fd); @@ -11943,10 +11912,10 @@ remote_file_put (const char *local_file, const char *remote_file, int from_tty) { bytes = fread (buffer + bytes_in_buffer, 1, io_size - bytes_in_buffer, - file); + file.get ()); if (bytes == 0) { - if (ferror (file)) + if (ferror (file.get ())) error (_("Error reading %s."), local_file); else { @@ -11997,7 +11966,6 @@ remote_file_get (const char *remote_file, const char *local_file, int from_tty) { struct cleanup *back_to, *close_cleanup; int fd, remote_errno, bytes, io_size; - FILE *file; gdb_byte *buffer; ULONGEST offset; struct remote_state *rs = get_remote_state (); @@ -12011,16 +11979,15 @@ remote_file_get (const char *remote_file, const char *local_file, int from_tty) if (fd == -1) remote_hostio_error (remote_errno); - file = gdb_fopen_cloexec (local_file, "wb"); + gdb_file_up file = gdb_fopen_cloexec (local_file, "wb"); if (file == NULL) perror_with_name (local_file); - back_to = make_cleanup_fclose (file); /* Send up to this many bytes at once. They won't all fit in the remote packet limit, so we'll transfer slightly fewer. */ io_size = get_remote_packet_size (); buffer = (gdb_byte *) xmalloc (io_size); - make_cleanup (xfree, buffer); + back_to = make_cleanup (xfree, buffer); close_cleanup = make_cleanup (remote_hostio_close_cleanup, &fd); @@ -12037,7 +12004,7 @@ remote_file_get (const char *remote_file, const char *local_file, int from_tty) offset += bytes; - bytes = fwrite (buffer, 1, bytes, file); + bytes = fwrite (buffer, 1, bytes, file.get ()); if (bytes == 0) perror_with_name (local_file); } @@ -12072,58 +12039,40 @@ remote_file_delete (const char *remote_file, int from_tty) static void remote_put_command (char *args, int from_tty) { - struct cleanup *back_to; - char **argv; - if (args == NULL) error_no_arg (_("file to put")); - argv = gdb_buildargv (args); - back_to = make_cleanup_freeargv (argv); + gdb_argv argv (args); if (argv[0] == NULL || argv[1] == NULL || argv[2] != NULL) error (_("Invalid parameters to remote put")); remote_file_put (argv[0], argv[1], from_tty); - - do_cleanups (back_to); } static void remote_get_command (char *args, int from_tty) { - struct cleanup *back_to; - char **argv; - if (args == NULL) error_no_arg (_("file to get")); - argv = gdb_buildargv (args); - back_to = make_cleanup_freeargv (argv); + gdb_argv argv (args); if (argv[0] == NULL || argv[1] == NULL || argv[2] != NULL) error (_("Invalid parameters to remote get")); remote_file_get (argv[0], argv[1], from_tty); - - do_cleanups (back_to); } static void remote_delete_command (char *args, int from_tty) { - struct cleanup *back_to; - char **argv; - if (args == NULL) error_no_arg (_("file to delete")); - argv = gdb_buildargv (args); - back_to = make_cleanup_freeargv (argv); + gdb_argv argv (args); if (argv[0] == NULL || argv[1] != NULL) error (_("Invalid parameters to remote delete")); remote_file_delete (argv[0], from_tty); - - do_cleanups (back_to); } static void diff --git a/gdb/reverse.c b/gdb/reverse.c index 4080616..c8f3811 100644 --- a/gdb/reverse.c +++ b/gdb/reverse.c @@ -30,13 +30,6 @@ /* User interface: reverse-step, reverse-next etc. */ -static void -exec_direction_default (void *notused) -{ - /* Return execution direction to default state. */ - execution_direction = EXEC_FORWARD; -} - /* exec_reverse_once -- accepts an arbitrary gdb command (string), and executes it with exec-direction set to 'reverse'. @@ -45,9 +38,7 @@ exec_direction_default (void *notused) static void exec_reverse_once (const char *cmd, char *args, int from_tty) { - char *reverse_command; enum exec_direction_kind dir = execution_direction; - struct cleanup *old_chain; if (dir == EXEC_REVERSE) error (_("Already in reverse mode. Use '%s' or 'set exec-dir forward'."), @@ -56,12 +47,10 @@ exec_reverse_once (const char *cmd, char *args, int from_tty) if (!target_can_execute_reverse) error (_("Target %s does not support this command."), target_shortname); - reverse_command = xstrprintf ("%s %s", cmd, args ? args : ""); - old_chain = make_cleanup (exec_direction_default, NULL); - make_cleanup (xfree, reverse_command); - execution_direction = EXEC_REVERSE; - execute_command (reverse_command, from_tty); - do_cleanups (old_chain); + std::string reverse_command = string_printf ("%s %s", cmd, args ? args : ""); + scoped_restore restore_exec_dir + = make_scoped_restore (&execution_direction, EXEC_REVERSE); + execute_command (&reverse_command[0], from_tty); } static void diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 97a975e..59d6896 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -6529,7 +6529,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Hook in ABI-specific overrides, if they have been registered. */ info.target_desc = tdesc; - info.tdep_info = tdesc_data; + info.tdesc_data = tdesc_data; gdbarch_init_osabi (info, gdbarch); switch (info.osabi) diff --git a/gdb/rust-exp.y b/gdb/rust-exp.y index 64b7c55..30c0cb4 100644 --- a/gdb/rust-exp.y +++ b/gdb/rust-exp.y @@ -42,8 +42,7 @@ extern initialize_file_ftype _initialize_rust_exp; struct rust_op; -typedef const struct rust_op *rust_op_ptr; -DEF_VEC_P (rust_op_ptr); +typedef std::vector<const struct rust_op *> rust_op_vector; /* A typed integer constant. */ @@ -70,10 +69,7 @@ struct set_field const struct rust_op *init; }; -typedef struct set_field set_field; - -DEF_VEC_O (set_field); - +typedef std::vector<set_field> rust_set_vector; static int rustyylex (void); static void rust_push_back (char c); @@ -110,12 +106,12 @@ static const struct rust_op *ast_cast (const struct rust_op *expr, const struct rust_op *type); static const struct rust_op *ast_call_ish (enum exp_opcode opcode, const struct rust_op *expr, - VEC (rust_op_ptr) **params); + rust_op_vector *params); static const struct rust_op *ast_path (struct stoken name, - VEC (rust_op_ptr) **params); + rust_op_vector *params); static const struct rust_op *ast_string (struct stoken str); static const struct rust_op *ast_struct (const struct rust_op *name, - VEC (set_field) **fields); + rust_set_vector *fields); static const struct rust_op *ast_range (const struct rust_op *lhs, const struct rust_op *rhs); static const struct rust_op *ast_array_type (const struct rust_op *lhs, @@ -125,13 +121,13 @@ static const struct rust_op *ast_reference_type (const struct rust_op *type); static const struct rust_op *ast_pointer_type (const struct rust_op *type, int is_mut); static const struct rust_op *ast_function_type (const struct rust_op *result, - VEC (rust_op_ptr) **params); -static const struct rust_op *ast_tuple_type (VEC (rust_op_ptr) **params); + rust_op_vector *params); +static const struct rust_op *ast_tuple_type (rust_op_vector *params); -/* The state of the parser, used internally when we are parsing the - expression. */ +/* The current rust parser. */ -static struct parser_state *pstate = NULL; +struct rust_parser; +static rust_parser *current_parser; /* A regular expression for matching Rust numbers. This is split up since it is very long and this gives us a way to comment the @@ -183,13 +179,76 @@ static regex_t number_regex; static int unit_testing; -/* Obstack for data temporarily allocated during parsing. */ - -static struct obstack work_obstack; - -/* Result of parsing. Points into work_obstack. */ - -static const struct rust_op *rust_ast; +/* Obstack for data temporarily allocated during parsing. Points to + the obstack in the rust_parser, or to a temporary obstack during + unit testing. */ + +static auto_obstack *work_obstack; + +/* An instance of this is created before parsing, and destroyed when + parsing is finished. */ + +struct rust_parser +{ + rust_parser (struct parser_state *state) + : rust_ast (nullptr), + pstate (state) + { + gdb_assert (current_parser == nullptr); + current_parser = this; + work_obstack = &obstack; + } + + ~rust_parser () + { + /* Clean up the globals we set. */ + current_parser = nullptr; + work_obstack = nullptr; + } + + /* Create a new rust_set_vector. The storage for the new vector is + managed by this class. */ + rust_set_vector *new_set_vector () + { + rust_set_vector *result = new rust_set_vector; + set_vectors.push_back (std::unique_ptr<rust_set_vector> (result)); + return result; + } + + /* Create a new rust_ops_vector. The storage for the new vector is + managed by this class. */ + rust_op_vector *new_op_vector () + { + rust_op_vector *result = new rust_op_vector; + op_vectors.push_back (std::unique_ptr<rust_op_vector> (result)); + return result; + } + + /* Return the parser's language. */ + const struct language_defn *language () const + { + return parse_language (pstate); + } + + /* Return the parser's gdbarch. */ + struct gdbarch *arch () const + { + return parse_gdbarch (pstate); + } + + /* A pointer to this is installed globally. */ + auto_obstack obstack; + + /* Result of parsing. Points into obstack. */ + const struct rust_op *rust_ast; + + /* This keeps track of the various vectors we allocate. */ + std::vector<std::unique_ptr<rust_set_vector>> set_vectors; + std::vector<std::unique_ptr<rust_op_vector>> op_vectors; + + /* The parser state gdb gave us. */ + struct parser_state *pstate; +}; %} @@ -209,10 +268,10 @@ static const struct rust_op *rust_ast; /* A list of expressions; for example, the arguments to a function call. */ - VEC (rust_op_ptr) **params; + rust_op_vector *params; /* A list of field initializers. */ - VEC (set_field) **field_inits; + rust_set_vector *field_inits; /* A single field initializer. */ struct set_field one_field_init; @@ -354,8 +413,8 @@ start: { /* If we are completing and see a valid parse, rust_ast will already have been set. */ - if (rust_ast == NULL) - rust_ast = $1; + if (current_parser->rust_ast == NULL) + current_parser->rust_ast = $1; } ; @@ -381,7 +440,7 @@ expr: tuple_expr: '(' expr ',' maybe_expr_list ')' { - VEC_safe_insert (rust_op_ptr, *$4, 0, $2); + $4->push_back ($2); error (_("Tuple expressions not supported yet")); } ; @@ -392,8 +451,8 @@ unit_expr: struct typed_val_int val; val.type - = language_lookup_primitive_type (parse_language (pstate), - parse_gdbarch (pstate), + = language_lookup_primitive_type (current_parser->language (), + current_parser->arch (), "()"); val.val = 0; $$ = ast_literal (val); @@ -432,18 +491,12 @@ struct_expr_tail: struct_expr_list: /* %empty */ { - VEC (set_field) **result - = OBSTACK_ZALLOC (&work_obstack, VEC (set_field) *); - $$ = result; + $$ = current_parser->new_set_vector (); } | struct_expr_tail { - VEC (set_field) **result - = OBSTACK_ZALLOC (&work_obstack, VEC (set_field) *); - - make_cleanup (VEC_cleanup (set_field), result); - VEC_safe_push (set_field, *result, &$1); - + rust_set_vector *result = current_parser->new_set_vector (); + result->push_back ($1); $$ = result; } | IDENT ':' expr ',' struct_expr_list @@ -452,7 +505,7 @@ struct_expr_list: sf.name = $1; sf.init = $3; - VEC_safe_push (set_field, *$5, &sf); + $5->push_back (sf); $$ = $5; } ; @@ -489,19 +542,17 @@ literal: | STRING { const struct rust_op *str = ast_string ($1); - VEC (set_field) **fields; struct set_field field; struct typed_val_int val; struct stoken token; - fields = OBSTACK_ZALLOC (&work_obstack, VEC (set_field) *); - make_cleanup (VEC_cleanup (set_field), fields); + rust_set_vector *fields = current_parser->new_set_vector (); /* Wrap the raw string in the &str struct. */ field.name.ptr = "data_ptr"; field.name.length = strlen (field.name.ptr); field.init = ast_unary (UNOP_ADDR, ast_string ($1)); - VEC_safe_push (set_field, *fields, &field); + fields->push_back (field); val.type = rust_type ("usize"); val.val = $1.length; @@ -509,7 +560,7 @@ literal: field.name.ptr = "length"; field.name.length = strlen (field.name.ptr); field.init = ast_literal (val); - VEC_safe_push (set_field, *fields, &field); + fields->push_back (field); token.ptr = "&str"; token.length = strlen (token.ptr); @@ -521,8 +572,8 @@ literal: { struct typed_val_int val; - val.type = language_bool_type (parse_language (pstate), - parse_gdbarch (pstate)); + val.type = language_bool_type (current_parser->language (), + current_parser->arch ()); val.val = 1; $$ = ast_literal (val); } @@ -530,8 +581,8 @@ literal: { struct typed_val_int val; - val.type = language_bool_type (parse_language (pstate), - parse_gdbarch (pstate)); + val.type = language_bool_type (current_parser->language (), + current_parser->arch ()); val.val = 0; $$ = ast_literal (val); } @@ -543,7 +594,7 @@ field_expr: | expr '.' COMPLETE { $$ = ast_structop ($1, $3.ptr, 1); - rust_ast = $$; + current_parser->rust_ast = $$; } | expr '.' DECIMAL_INTEGER { $$ = ast_structop_anonymous ($1, $3); } @@ -672,13 +723,12 @@ paren_expr: expr_list: expr { - $$ = OBSTACK_ZALLOC (&work_obstack, VEC (rust_op_ptr) *); - make_cleanup (VEC_cleanup (rust_op_ptr), $$); - VEC_safe_push (rust_op_ptr, *$$, $1); + $$ = current_parser->new_op_vector (); + $$->push_back ($1); } | expr_list ',' expr { - VEC_safe_push (rust_op_ptr, *$1, $3); + $1->push_back ($3); $$ = $1; } ; @@ -687,8 +737,7 @@ maybe_expr_list: /* %empty */ { /* The result can't be NULL. */ - $$ = OBSTACK_ZALLOC (&work_obstack, VEC (rust_op_ptr) *); - make_cleanup (VEC_cleanup (rust_op_ptr), $$); + $$ = current_parser->new_op_vector (); } | expr_list { $$ = $1; } @@ -835,16 +884,13 @@ maybe_type_list: type_list: type { - VEC (rust_op_ptr) **result - = OBSTACK_ZALLOC (&work_obstack, VEC (rust_op_ptr) *); - - make_cleanup (VEC_cleanup (rust_op_ptr), result); - VEC_safe_push (rust_op_ptr, *result, $1); + rust_op_vector *result = current_parser->new_op_vector (); + result->push_back ($1); $$ = result; } | type_list ',' type { - VEC_safe_push (rust_op_ptr, *$1, $3); + $1->push_back ($3); $$ = $1; } ; @@ -911,7 +957,7 @@ static const struct token_info operator_tokens[] = static const char * rust_copy_name (const char *name, int len) { - return (const char *) obstack_copy0 (&work_obstack, name, len); + return (const char *) obstack_copy0 (work_obstack, name, len); } /* Helper function to make an stoken from a C string. */ @@ -932,7 +978,7 @@ make_stoken (const char *p) static struct stoken rust_concat3 (const char *s1, const char *s2, const char *s3) { - return make_stoken (obconcat (&work_obstack, s1, s2, s3, (char *) NULL)); + return make_stoken (obconcat (work_obstack, s1, s2, s3, (char *) NULL)); } /* Return an AST node referring to NAME, but relative to the crate's @@ -948,7 +994,7 @@ crate_name (const struct rust_op *name) if (crate.empty ()) error (_("Could not find crate for current location")); - result = make_stoken (obconcat (&work_obstack, "::", crate.c_str (), "::", + result = make_stoken (obconcat (work_obstack, "::", crate.c_str (), "::", name->left.sval.ptr, (char *) NULL)); return ast_path (result, name->right.params); @@ -996,12 +1042,12 @@ super_name (const struct rust_op *ident, unsigned int n_supers) else offset = strlen (scope); - obstack_grow (&work_obstack, "::", 2); - obstack_grow (&work_obstack, scope, offset); - obstack_grow (&work_obstack, "::", 2); - obstack_grow0 (&work_obstack, ident->left.sval.ptr, ident->left.sval.length); + obstack_grow (work_obstack, "::", 2); + obstack_grow (work_obstack, scope, offset); + obstack_grow (work_obstack, "::", 2); + obstack_grow0 (work_obstack, ident->left.sval.ptr, ident->left.sval.length); - return ast_path (make_stoken ((const char *) obstack_finish (&work_obstack)), + return ast_path (make_stoken ((const char *) obstack_finish (work_obstack)), ident->right.params); } @@ -1029,8 +1075,8 @@ rust_type (const char *name) if (unit_testing) return NULL; - type = language_lookup_primitive_type (parse_language (pstate), - parse_gdbarch (pstate), + type = language_lookup_primitive_type (current_parser->language (), + current_parser->arch (), name); if (type == NULL) error (_("Could not find Rust type %s"), name); @@ -1243,7 +1289,7 @@ lex_string (void) value = lexptr[0] & 0xff; if (is_byte && value > 127) error (_("Non-ASCII value in raw byte string")); - obstack_1grow (&work_obstack, value); + obstack_1grow (work_obstack, value); ++lexptr; } @@ -1258,11 +1304,11 @@ lex_string (void) value = lex_escape (is_byte); if (is_byte) - obstack_1grow (&work_obstack, value); + obstack_1grow (work_obstack, value); else convert_between_encodings ("UTF-32", "UTF-8", (gdb_byte *) &value, sizeof (value), sizeof (value), - &work_obstack, translit_none); + work_obstack, translit_none); } else if (lexptr[0] == '\0') error (_("Unexpected EOF in string")); @@ -1271,13 +1317,13 @@ lex_string (void) value = lexptr[0] & 0xff; if (is_byte && value > 127) error (_("Non-ASCII value in byte string")); - obstack_1grow (&work_obstack, value); + obstack_1grow (work_obstack, value); ++lexptr; } } - rustyylval.sval.length = obstack_object_size (&work_obstack); - rustyylval.sval.ptr = (const char *) obstack_finish (&work_obstack); + rustyylval.sval.length = obstack_object_size (work_obstack); + rustyylval.sval.ptr = (const char *) obstack_finish (work_obstack); return is_byte ? BYTESTRING : STRING; } @@ -1627,7 +1673,7 @@ static const struct rust_op * ast_operation (enum exp_opcode opcode, const struct rust_op *left, const struct rust_op *right) { - struct rust_op *result = OBSTACK_ZALLOC (&work_obstack, struct rust_op); + struct rust_op *result = OBSTACK_ZALLOC (work_obstack, struct rust_op); result->opcode = opcode; result->left.op = left; @@ -1642,7 +1688,7 @@ static const struct rust_op * ast_compound_assignment (enum exp_opcode opcode, const struct rust_op *left, const struct rust_op *right) { - struct rust_op *result = OBSTACK_ZALLOC (&work_obstack, struct rust_op); + struct rust_op *result = OBSTACK_ZALLOC (work_obstack, struct rust_op); result->opcode = opcode; result->compound_assignment = 1; @@ -1657,7 +1703,7 @@ ast_compound_assignment (enum exp_opcode opcode, const struct rust_op *left, static const struct rust_op * ast_literal (struct typed_val_int val) { - struct rust_op *result = OBSTACK_ZALLOC (&work_obstack, struct rust_op); + struct rust_op *result = OBSTACK_ZALLOC (work_obstack, struct rust_op); result->opcode = OP_LONG; result->left.typed_val_int = val; @@ -1670,7 +1716,7 @@ ast_literal (struct typed_val_int val) static const struct rust_op * ast_dliteral (struct typed_val_float val) { - struct rust_op *result = OBSTACK_ZALLOC (&work_obstack, struct rust_op); + struct rust_op *result = OBSTACK_ZALLOC (work_obstack, struct rust_op); result->opcode = OP_DOUBLE; result->left.typed_val_float = val; @@ -1691,7 +1737,7 @@ ast_unary (enum exp_opcode opcode, const struct rust_op *expr) static const struct rust_op * ast_cast (const struct rust_op *expr, const struct rust_op *type) { - struct rust_op *result = OBSTACK_ZALLOC (&work_obstack, struct rust_op); + struct rust_op *result = OBSTACK_ZALLOC (work_obstack, struct rust_op); result->opcode = UNOP_CAST; result->left.op = expr; @@ -1706,9 +1752,9 @@ ast_cast (const struct rust_op *expr, const struct rust_op *type) static const struct rust_op * ast_call_ish (enum exp_opcode opcode, const struct rust_op *expr, - VEC (rust_op_ptr) **params) + rust_op_vector *params) { - struct rust_op *result = OBSTACK_ZALLOC (&work_obstack, struct rust_op); + struct rust_op *result = OBSTACK_ZALLOC (work_obstack, struct rust_op); result->opcode = opcode; result->left.op = expr; @@ -1720,9 +1766,9 @@ ast_call_ish (enum exp_opcode opcode, const struct rust_op *expr, /* Make a structure creation operation. */ static const struct rust_op * -ast_struct (const struct rust_op *name, VEC (set_field) **fields) +ast_struct (const struct rust_op *name, rust_set_vector *fields) { - struct rust_op *result = OBSTACK_ZALLOC (&work_obstack, struct rust_op); + struct rust_op *result = OBSTACK_ZALLOC (work_obstack, struct rust_op); result->opcode = OP_AGGREGATE; result->left.op = name; @@ -1734,9 +1780,9 @@ ast_struct (const struct rust_op *name, VEC (set_field) **fields) /* Make an identifier path. */ static const struct rust_op * -ast_path (struct stoken path, VEC (rust_op_ptr) **params) +ast_path (struct stoken path, rust_op_vector *params) { - struct rust_op *result = OBSTACK_ZALLOC (&work_obstack, struct rust_op); + struct rust_op *result = OBSTACK_ZALLOC (work_obstack, struct rust_op); result->opcode = OP_VAR_VALUE; result->left.sval = path; @@ -1750,7 +1796,7 @@ ast_path (struct stoken path, VEC (rust_op_ptr) **params) static const struct rust_op * ast_string (struct stoken str) { - struct rust_op *result = OBSTACK_ZALLOC (&work_obstack, struct rust_op); + struct rust_op *result = OBSTACK_ZALLOC (work_obstack, struct rust_op); result->opcode = OP_STRING; result->left.sval = str; @@ -1763,7 +1809,7 @@ ast_string (struct stoken str) static const struct rust_op * ast_structop (const struct rust_op *left, const char *name, int completing) { - struct rust_op *result = OBSTACK_ZALLOC (&work_obstack, struct rust_op); + struct rust_op *result = OBSTACK_ZALLOC (work_obstack, struct rust_op); result->opcode = STRUCTOP_STRUCT; result->completing = completing; @@ -1779,7 +1825,7 @@ static const struct rust_op * ast_structop_anonymous (const struct rust_op *left, struct typed_val_int number) { - struct rust_op *result = OBSTACK_ZALLOC (&work_obstack, struct rust_op); + struct rust_op *result = OBSTACK_ZALLOC (work_obstack, struct rust_op); result->opcode = STRUCTOP_ANONYMOUS; result->left.op = left; @@ -1793,7 +1839,7 @@ ast_structop_anonymous (const struct rust_op *left, static const struct rust_op * ast_range (const struct rust_op *lhs, const struct rust_op *rhs) { - struct rust_op *result = OBSTACK_ZALLOC (&work_obstack, struct rust_op); + struct rust_op *result = OBSTACK_ZALLOC (work_obstack, struct rust_op); result->opcode = OP_RANGE; result->left.op = lhs; @@ -1807,7 +1853,7 @@ ast_range (const struct rust_op *lhs, const struct rust_op *rhs) static struct rust_op * ast_basic_type (enum type_code typecode) { - struct rust_op *result = OBSTACK_ZALLOC (&work_obstack, struct rust_op); + struct rust_op *result = OBSTACK_ZALLOC (work_obstack, struct rust_op); result->opcode = OP_TYPE; result->typecode = typecode; @@ -1864,7 +1910,7 @@ ast_pointer_type (const struct rust_op *type, int is_mut) /* Create an AST node describing a function type. */ static const struct rust_op * -ast_function_type (const struct rust_op *rtype, VEC (rust_op_ptr) **params) +ast_function_type (const struct rust_op *rtype, rust_op_vector *params) { struct rust_op *result = ast_basic_type (TYPE_CODE_FUNC); @@ -1876,7 +1922,7 @@ ast_function_type (const struct rust_op *rtype, VEC (rust_op_ptr) **params) /* Create an AST node describing a tuple type. */ static const struct rust_op * -ast_tuple_type (VEC (rust_op_ptr) **params) +ast_tuple_type (rust_op_vector *params) { struct rust_op *result = ast_basic_type (TYPE_CODE_STRUCT); @@ -1933,14 +1979,14 @@ rust_lookup_type (const char *name, const struct block *block) return SYMBOL_TYPE (result.symbol); } - type = lookup_typename (parse_language (pstate), parse_gdbarch (pstate), + type = lookup_typename (current_parser->language (), current_parser->arch (), name, NULL, 1); if (type != NULL) return type; /* Last chance, try a built-in type. */ - return language_lookup_primitive_type (parse_language (pstate), - parse_gdbarch (pstate), + return language_lookup_primitive_type (current_parser->language (), + current_parser->arch (), name); } @@ -1953,13 +1999,11 @@ static const char *convert_name (struct parser_state *state, types. */ static std::vector<struct type *> -convert_params_to_types (struct parser_state *state, VEC (rust_op_ptr) *params) +convert_params_to_types (struct parser_state *state, rust_op_vector *params) { - int i; - const struct rust_op *op; std::vector<struct type *> result; - for (i = 0; VEC_iterate (rust_op_ptr, params, i, op); ++i) + for (const rust_op *op : *params) result.push_back (convert_ast_to_type (state, op)); return result; @@ -2014,7 +2058,7 @@ convert_ast_to_type (struct parser_state *state, case TYPE_CODE_FUNC: { std::vector<struct type *> args - (convert_params_to_types (state, *operation->right.params)); + (convert_params_to_types (state, operation->right.params)); struct type **argtypes = NULL; type = convert_ast_to_type (state, operation->left.op); @@ -2031,23 +2075,23 @@ convert_ast_to_type (struct parser_state *state, case TYPE_CODE_STRUCT: { std::vector<struct type *> args - (convert_params_to_types (state, *operation->left.params)); + (convert_params_to_types (state, operation->left.params)); int i; struct type *type; const char *name; - obstack_1grow (&work_obstack, '('); + obstack_1grow (work_obstack, '('); for (i = 0; i < args.size (); ++i) { std::string type_name = type_to_string (args[i]); if (i > 0) - obstack_1grow (&work_obstack, ','); - obstack_grow_str (&work_obstack, type_name.c_str ()); + obstack_1grow (work_obstack, ','); + obstack_grow_str (work_obstack, type_name.c_str ()); } - obstack_grow_str0 (&work_obstack, ")"); - name = (const char *) obstack_finish (&work_obstack); + obstack_grow_str0 (work_obstack, ")"); + name = (const char *) obstack_finish (work_obstack); /* We don't allow creating new tuple types (yet), but we do allow looking up existing tuple types. */ @@ -2080,40 +2124,38 @@ convert_name (struct parser_state *state, const struct rust_op *operation) return operation->left.sval.ptr; std::vector<struct type *> types - (convert_params_to_types (state, *operation->right.params)); + (convert_params_to_types (state, operation->right.params)); - obstack_grow_str (&work_obstack, operation->left.sval.ptr); - obstack_1grow (&work_obstack, '<'); + obstack_grow_str (work_obstack, operation->left.sval.ptr); + obstack_1grow (work_obstack, '<'); for (i = 0; i < types.size (); ++i) { std::string type_name = type_to_string (types[i]); if (i > 0) - obstack_1grow (&work_obstack, ','); + obstack_1grow (work_obstack, ','); - obstack_grow_str (&work_obstack, type_name.c_str ()); + obstack_grow_str (work_obstack, type_name.c_str ()); } - obstack_grow_str0 (&work_obstack, ">"); + obstack_grow_str0 (work_obstack, ">"); - return (const char *) obstack_finish (&work_obstack); + return (const char *) obstack_finish (work_obstack); } static void convert_ast_to_expression (struct parser_state *state, const struct rust_op *operation, - const struct rust_op *top); + const struct rust_op *top, + bool want_type = false); /* A helper function that converts a vec of rust_ops to a gdb expression. */ static void convert_params_to_expression (struct parser_state *state, - VEC (rust_op_ptr) *params, + rust_op_vector *params, const struct rust_op *top) { - int i; - rust_op_ptr elem; - - for (i = 0; VEC_iterate (rust_op_ptr, params, i, elem); ++i) + for (const rust_op *elem : *params) convert_ast_to_expression (state, elem, top); } @@ -2121,12 +2163,16 @@ convert_params_to_expression (struct parser_state *state, OPERATION is the operation to lower. TOP is a pointer to the top-most operation; it is used to handle the special case where the top-most expression is an identifier and can be optionally lowered - to OP_TYPE. */ + to OP_TYPE. WANT_TYPE is a flag indicating that, if the expression + is the name of a type, then emit an OP_TYPE for it (rather than + erroring). If WANT_TYPE is set, then the similar TOP handling is + not done. */ static void convert_ast_to_expression (struct parser_state *state, const struct rust_op *operation, - const struct rust_op *top) + const struct rust_op *top, + bool want_type) { switch (operation->opcode) { @@ -2166,12 +2212,16 @@ convert_ast_to_expression (struct parser_state *state, } break; + case UNOP_SIZEOF: + convert_ast_to_expression (state, operation->left.op, top, true); + write_exp_elt_opcode (state, UNOP_SIZEOF); + break; + case UNOP_PLUS: case UNOP_NEG: case UNOP_COMPLEMENT: case UNOP_IND: case UNOP_ADDR: - case UNOP_SIZEOF: convert_ast_to_expression (state, operation->left.op, top); write_exp_elt_opcode (state, operation->opcode); break; @@ -2250,18 +2300,14 @@ convert_ast_to_expression (struct parser_state *state, { /* This is actually a tuple struct expression, not a call expression. */ - rust_op_ptr elem; - int i; - VEC (rust_op_ptr) *params = *operation->right.params; + rust_op_vector *params = operation->right.params; if (TYPE_CODE (type) != TYPE_CODE_NAMESPACE) { if (!rust_tuple_struct_type_p (type)) error (_("Type %s is not a tuple struct"), varname); - for (i = 0; - VEC_iterate (rust_op_ptr, params, i, elem); - ++i) + for (int i = 0; i < params->size (); ++i) { char *cell = get_print_cell (); @@ -2270,35 +2316,31 @@ convert_ast_to_expression (struct parser_state *state, write_exp_string (state, make_stoken (cell)); write_exp_elt_opcode (state, OP_NAME); - convert_ast_to_expression (state, elem, top); + convert_ast_to_expression (state, (*params)[i], top); } write_exp_elt_opcode (state, OP_AGGREGATE); write_exp_elt_type (state, type); - write_exp_elt_longcst (state, - 2 * VEC_length (rust_op_ptr, - params)); + write_exp_elt_longcst (state, 2 * params->size ()); write_exp_elt_opcode (state, OP_AGGREGATE); break; } } } convert_ast_to_expression (state, operation->left.op, top); - convert_params_to_expression (state, *operation->right.params, top); + convert_params_to_expression (state, operation->right.params, top); write_exp_elt_opcode (state, OP_FUNCALL); - write_exp_elt_longcst (state, VEC_length (rust_op_ptr, - *operation->right.params)); + write_exp_elt_longcst (state, operation->right.params->size ()); write_exp_elt_longcst (state, OP_FUNCALL); } break; case OP_ARRAY: gdb_assert (operation->left.op == NULL); - convert_params_to_expression (state, *operation->right.params, top); + convert_params_to_expression (state, operation->right.params, top); write_exp_elt_opcode (state, OP_ARRAY); write_exp_elt_longcst (state, 0); - write_exp_elt_longcst (state, VEC_length (rust_op_ptr, - *operation->right.params) - 1); + write_exp_elt_longcst (state, operation->right.params->size () - 1); write_exp_elt_longcst (state, OP_ARRAY); break; @@ -2316,7 +2358,7 @@ convert_ast_to_expression (struct parser_state *state, varname = convert_name (state, operation); sym = rust_lookup_symbol (varname, expression_context_block, VAR_DOMAIN); - if (sym.symbol != NULL) + if (sym.symbol != NULL && SYMBOL_CLASS (sym.symbol) != LOC_TYPEDEF) { write_exp_elt_opcode (state, OP_VAR_VALUE); write_exp_elt_block (state, sym.block); @@ -2325,13 +2367,20 @@ convert_ast_to_expression (struct parser_state *state, } else { - struct type *type; + struct type *type = NULL; - type = rust_lookup_type (varname, expression_context_block); + if (sym.symbol != NULL) + { + gdb_assert (SYMBOL_CLASS (sym.symbol) == LOC_TYPEDEF); + type = SYMBOL_TYPE (sym.symbol); + } + if (type == NULL) + type = rust_lookup_type (varname, expression_context_block); if (type == NULL) error (_("No symbol '%s' in current context"), varname); - if (TYPE_CODE (type) == TYPE_CODE_STRUCT + if (!want_type + && TYPE_CODE (type) == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 0) { /* A unit-like struct. */ @@ -2340,13 +2389,16 @@ convert_ast_to_expression (struct parser_state *state, write_exp_elt_longcst (state, 0); write_exp_elt_opcode (state, OP_AGGREGATE); } - else if (operation == top) + else if (want_type || operation == top) { write_exp_elt_opcode (state, OP_TYPE); write_exp_elt_type (state, type); write_exp_elt_opcode (state, OP_TYPE); - break; } + else + error (_("Found type '%s', which can't be " + "evaluated in this context"), + varname); } } break; @@ -2355,26 +2407,25 @@ convert_ast_to_expression (struct parser_state *state, { int i; int length; - struct set_field *init; - VEC (set_field) *fields = *operation->right.field_inits; + rust_set_vector *fields = operation->right.field_inits; struct type *type; const char *name; length = 0; - for (i = 0; VEC_iterate (set_field, fields, i, init); ++i) + for (const set_field &init : *fields) { - if (init->name.ptr != NULL) + if (init.name.ptr != NULL) { write_exp_elt_opcode (state, OP_NAME); - write_exp_string (state, init->name); + write_exp_string (state, init.name); write_exp_elt_opcode (state, OP_NAME); ++length; } - convert_ast_to_expression (state, init->init, top); + convert_ast_to_expression (state, init.init, top); ++length; - if (init->name.ptr == NULL) + if (init.name.ptr == NULL) { /* This is handled differently from Ada in our evaluator. */ @@ -2446,25 +2497,16 @@ int rust_parse (struct parser_state *state) { int result; - struct cleanup *cleanup; - obstack_init (&work_obstack); - cleanup = make_cleanup_obstack_free (&work_obstack); - rust_ast = NULL; + /* This sets various globals and also clears them on + destruction. */ + rust_parser parser (state); - pstate = state; result = rustyyparse (); - if (!result || (parse_completion && rust_ast != NULL)) - { - const struct rust_op *ast = rust_ast; + if (!result || (parse_completion && parser.rust_ast != NULL)) + convert_ast_to_expression (state, parser.rust_ast, parser.rust_ast); - rust_ast = NULL; - gdb_assert (ast != NULL); - convert_ast_to_expression (state, ast, ast); - } - - do_cleanups (cleanup); return result; } @@ -2631,7 +2673,10 @@ rust_lex_tests (void) { int i; - obstack_init (&work_obstack); + auto_obstack test_obstack; + scoped_restore obstack_holder = make_scoped_restore (&work_obstack, + &test_obstack); + unit_testing = 1; rust_lex_test_one ("", 0); @@ -2722,7 +2767,6 @@ rust_lex_tests (void) rust_lex_test_completion (); rust_lex_test_push_back (); - obstack_free (&work_obstack, NULL); unit_testing = 0; } diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c index 4b1e3ec..2934d9b 100644 --- a/gdb/rust-lang.c +++ b/gdb/rust-lang.c @@ -35,8 +35,6 @@ #include <string> #include <vector> -extern initialize_file_ftype _initialize_rust_language; - /* Returns the last segment of a Rust path like foo::bar::baz. Will not handle cases where the last segment contains generics. This will return NULL if the last segment cannot be found. */ @@ -2150,7 +2148,7 @@ static const char *rust_extensions[] = ".rs", NULL }; -static const struct language_defn rust_language_defn = +extern const struct language_defn rust_language_defn = { "rust", "Rust", @@ -2184,7 +2182,7 @@ static const struct language_defn rust_language_defn = 1, /* c-style arrays */ 0, /* String lower bound */ default_word_break_characters, - default_make_symbol_completion_list, + default_collect_symbol_completion_matches, rust_language_arch_info, default_print_array_index, default_pass_by_reference, @@ -2198,9 +2196,3 @@ static const struct language_defn rust_language_defn = NULL, LANG_MAGIC }; - -void -_initialize_rust_language (void) -{ - add_language (&rust_language_defn); -} diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c index 8840c2f..5682c4a 100644 --- a/gdb/s390-linux-tdep.c +++ b/gdb/s390-linux-tdep.c @@ -4992,6 +4992,8 @@ ex: case 0xb9e9: /* SGRK - subtract */ case 0xb9ea: /* ALGRK - add logical */ case 0xb9eb: /* SLGRK - subtract logical */ + case 0xb9ed: /* MSGRKC - multiply single 64x64 -> 64 */ + case 0xb9fd: /* MSRKC - multiply single 32x32 -> 32 */ /* 64-bit gpr destination + flags */ if (s390_record_gpr_g (gdbarch, regcache, inib[6])) return -1; @@ -5019,7 +5021,7 @@ ex: case 0xb914: /* LGFR - load */ case 0xb916: /* LLGFR - load logical */ case 0xb917: /* LLGTR - load logical thirty one bits */ - case 0xb91c: /* MSGFR - load */ + case 0xb91c: /* MSGFR - multiply single 64<32 */ case 0xb946: /* BCTGR - branch on count */ case 0xb984: /* LLGCR - load logical character */ case 0xb985: /* LLGHR - load logical halfword */ @@ -5038,6 +5040,7 @@ ex: case 0xb91d: /* DSGFR - divide single */ case 0xb986: /* MLGR - multiply logical */ case 0xb987: /* DLGR - divide logical */ + case 0xb9ec: /* MGRK - multiply 64x64 -> 128 */ /* 64-bit gpr pair destination */ if (s390_record_gpr_g (gdbarch, regcache, inib[6])) return -1; @@ -5106,8 +5109,8 @@ ex: /* 0xb922-0xb924 undefined */ /* 0xb925 privileged */ /* 0xb928 privileged */ - /* 0xb929 undefined */ + case 0xb929: /* KMA - cipher message with authentication */ case 0xb92a: /* KMF - cipher message with cipher feedback [partial] */ case 0xb92b: /* KMO - cipher message with output feedback [partial] */ case 0xb92f: /* KMC - cipher message with chaining [partial] */ @@ -5170,6 +5173,15 @@ ex: if (record_full_arch_list_add_reg (regcache, S390_R0_REGNUM + (inib[7] | 1))) return -1; } + if (tmp != 0 && insn[0] == 0xb929) + { + if (record_full_arch_list_add_reg (regcache, + S390_R0_REGNUM + inib[4])) + return -1; + if (record_full_arch_list_add_reg (regcache, + S390_R0_REGNUM + (inib[4] | 1))) + return -1; + } if (record_full_arch_list_add_reg (regcache, S390_PSWM_REGNUM)) return -1; break; @@ -5571,10 +5583,11 @@ ex: /* 0xb9e3 undefined */ /* 0xb9e5 undefined */ - /* 0xb9ec-0xb9f1 undefined */ + /* 0xb9ee-0xb9f1 undefined */ /* 0xb9f3 undefined */ /* 0xb9f5 undefined */ - /* 0xb9fc-0xb9ff undefined */ + /* 0xb9fc undefined */ + /* 0xb9fe -0xb9ff undefined */ default: goto UNKNOWN_OP; @@ -5962,6 +5975,7 @@ ex: break; case 0xe3: + case 0xe6: case 0xe7: case 0xeb: case 0xed: @@ -6006,6 +6020,7 @@ ex: case 0xe31c: /* MSGF - multiply single */ case 0xe32a: /* LZRG - load and zero rightmost byte */ case 0xe33a: /* LLZRGF - load logical and zero rightmost byte */ + case 0xe33c: /* MGH - multiply halfword 64x16mem -> 64 */ case 0xe346: /* BCTG - branch on count */ case 0xe377: /* LGB - load byte */ case 0xe390: /* LLGC - load logical character */ @@ -6036,6 +6051,7 @@ ex: case 0xe30d: /* DSG - divide single */ case 0xe31d: /* DSGF - divide single */ + case 0xe384: /* MG - multiply 64x64mem -> 128 */ case 0xe386: /* MLG - multiply logical */ case 0xe387: /* DLG - divide logical */ case 0xe38f: /* LPQ - load pair from quadword */ @@ -6057,6 +6073,9 @@ ex: /* 0xe310-0xe311 undefined */ case 0xe312: /* LT - load and test */ + case 0xe338: /* AGH - add halfword to 64 bit value */ + case 0xe339: /* SGH - subtract halfword from 64 bit value */ + case 0xe353: /* MSC - multiply single 32x32mem -> 32 */ case 0xe354: /* NY - and */ case 0xe356: /* OY - or */ case 0xe357: /* XY - xor */ @@ -6066,13 +6085,14 @@ ex: case 0xe35f: /* SLY - subtract logical */ case 0xe37a: /* AHY - add halfword */ case 0xe37b: /* SHY - subtract halfword */ + case 0xe383: /* MSGC - multiply single 64x64mem -> 64 */ case 0xe398: /* ALC - add logical with carry */ case 0xe399: /* SLB - subtract logical with borrow */ case 0xe727: /* LCBB - load count to block bounduary */ case 0xeb81: /* ICMY - insert characters under mask */ case 0xebdc: /* SRAK - shift left single */ case 0xebdd: /* SLAK - shift left single */ - /* 32-bit gpr destination + flags */ + /* 32/64-bit gpr destination + flags */ if (record_full_arch_list_add_reg (regcache, S390_R0_REGNUM + inib[2])) return -1; if (record_full_arch_list_add_reg (regcache, S390_PSWM_REGNUM)) @@ -6160,7 +6180,7 @@ ex: case 0xe336: /* PFD - prefetch data */ break; - /* 0xe337-0xe339 undefined */ + /* 0xe337 undefined */ /* 0xe33c-0xe33d undefined */ case 0xe33e: /* STRV - store reversed */ @@ -6183,8 +6203,12 @@ ex: break; /* 0xe340-0xe345 undefined */ - /* 0xe347-0xe34f undefined */ - /* 0xe352-0xe353 undefined */ + + case 0xe347: /* BIC - branch indirect on condition */ + break; + + /* 0xe348-0xe34f undefined */ + /* 0xe352 undefined */ case 0xe35c: /* MFY - multiply */ case 0xe396: /* ML - multiply logical */ @@ -6216,11 +6240,12 @@ ex: break; /* 0xe37d-0xe37f undefined */ - /* 0xe383-0xe384 undefined */ case 0xe385: /* LGAT - load and trap */ case 0xe39c: /* LLGTAT - load logical thirty one bits and trap */ case 0xe39d: /* LLGFAT - load logical and trap */ + case 0xe650: /* VCVB - vector convert to binary 32 bit*/ + case 0xe652: /* VCVBG - vector convert to binary 64 bit*/ case 0xe721: /* VLGV - vector load gr from vr element */ /* 64-bit gpr destination + fpc for possible DXC write */ if (s390_record_gpr_g (gdbarch, regcache, inib[2])) @@ -6271,6 +6296,10 @@ ex: /* 0xe3ce undefined */ /* 0xe3d0-0xe3ff undefined */ + case 0xe634: /* VPKZ - vector pack zoned */ + case 0xe635: /* VLRL - vector load rightmost with immed. length */ + case 0xe637: /* VLRLR - vector load rightmost with length */ + case 0xe649: /* VLIP - vector load immediate decimal */ case 0xe700: /* VLEB - vector load element */ case 0xe701: /* VLEH - vector load element */ case 0xe702: /* VLEG - vector load element */ @@ -6311,7 +6340,10 @@ ex: case 0xe769: /* VNC - vector and with complement */ case 0xe76a: /* VO - vector or */ case 0xe76b: /* VNO - vector nor */ + case 0xe76c: /* VNX - vector not exclusive or */ case 0xe76d: /* VX - vector xor */ + case 0xe76e: /* VNN - vector nand */ + case 0xe76f: /* VOC - vector or with complement */ case 0xe770: /* VESLV - vector element shift left */ case 0xe772: /* VERIM - vector element rotate and insert under mask */ case 0xe773: /* VERLLV - vector element rotate left logical */ @@ -6325,11 +6357,14 @@ ex: case 0xe77e: /* VSRA - vector shift right arithmetic */ case 0xe77f: /* VSRAB - vector shift right arithmetic by byte */ case 0xe784: /* VPDI - vector permute doubleword immediate */ + case 0xe785: /* VBPERM - vector bit permute */ case 0xe78c: /* VPERM - vector permute */ case 0xe78d: /* VSEL - vector select */ case 0xe78e: /* VFMS - vector fp multiply and subtract */ case 0xe78f: /* VFMA - vector fp multiply and add */ case 0xe794: /* VPK - vector pack */ + case 0xe79e: /* VFNMS - vector fp negative multiply and subtract */ + case 0xe79f: /* VFNMA - vector fp negative multiply and add */ case 0xe7a1: /* VMLH - vector multiply logical high */ case 0xe7a2: /* VML - vector multiply low */ case 0xe7a3: /* VMH - vector multiply high */ @@ -6345,6 +6380,7 @@ ex: case 0xe7ae: /* VMAE - vector multiply and add even */ case 0xe7af: /* VMAO - vector multiply and add odd */ case 0xe7b4: /* VGFM - vector Galois field multiply sum */ + case 0xe7b8: /* VMSL - vector multiply sum logical */ case 0xe7b9: /* VACCC - vector add with carry compute carry */ case 0xe7bb: /* VAC - vector add with carry */ case 0xe7bc: /* VGFMA - vector Galois field multiply sum and accumulate */ @@ -6354,8 +6390,8 @@ ex: case 0xe7c1: /* VCDLG - vector convert from logical 64-bit */ case 0xe7c2: /* VCGD - vector convert to fixed 64-bit */ case 0xe7c3: /* VCDG - vector convert from fixed 64-bit */ - case 0xe7c4: /* VLDE - vector fp load lengthened */ - case 0xe7c5: /* VLED - vector fp load rounded */ + case 0xe7c4: /* VLDE/VFLL - vector fp load lengthened */ + case 0xe7c5: /* VLED/VFLR - vector fp load rounded */ case 0xe7c7: /* VFI - vector load fp integer */ case 0xe7cc: /* VFPSO - vector fp perform sign operation */ case 0xe7ce: /* VFSQ - vector fp square root */ @@ -6369,6 +6405,8 @@ ex: case 0xe7e3: /* VFA - vector fp add */ case 0xe7e5: /* VFD - vector fp divide */ case 0xe7e7: /* VFM - vector fp multiply */ + case 0xe7ee: /* VFMIN - vector fp minimum */ + case 0xe7ef: /* VFMAX - vector fp maximum */ case 0xe7f0: /* VAVGL - vector average logical */ case 0xe7f1: /* VACC - vector add and compute carry */ case 0xe7f2: /* VAVG - vector average */ @@ -6386,6 +6424,14 @@ ex: return -1; break; + case 0xe63d: /* VSTRL - vector store rightmost with immed. length */ + oaddr = s390_record_calc_disp (gdbarch, regcache, 0, insn[1], 0); + if (record_full_arch_list_add_mem (oaddr, inib[3] + 1)) + return -1; + if (record_full_arch_list_add_reg (regcache, S390_FPC_REGNUM)) + return -1; + break; + case 0xe708: /* VSTEB - vector store element */ oaddr = s390_record_calc_disp (gdbarch, regcache, inib[3], insn[1], 0); if (record_full_arch_list_add_mem (oaddr, 1)) @@ -6480,13 +6526,22 @@ ex: return -1; break; + case 0xe63c: /* VUPKZ - vector unpack zoned */ + oaddr = s390_record_calc_disp (gdbarch, regcache, 0, insn[1], 0); + if (record_full_arch_list_add_mem (oaddr, (ibyte[1] + 1) & 31)) + return -1; + if (record_full_arch_list_add_reg (regcache, S390_PSWM_REGNUM)) + return -1; + break; + + case 0xe63f: /* VSTRLR - vector store rightmost with length */ case 0xe73f: /* VSTL - vector store with length */ oaddr = s390_record_calc_disp (gdbarch, regcache, 0, insn[1], 0); regcache_raw_read_unsigned (regcache, S390_R0_REGNUM + inib[3], &tmp); tmp &= 0xffffffffu; - if (tmp > 16) - tmp = 16; - if (record_full_arch_list_add_mem (oaddr, tmp)) + if (tmp > 15) + tmp = 15; + if (record_full_arch_list_add_mem (oaddr, tmp + 1)) return -1; if (record_full_arch_list_add_reg (regcache, S390_FPC_REGNUM)) return -1; @@ -6494,6 +6549,17 @@ ex: /* 0xe747-0xe749 undefined */ + case 0xe658: /* VCVD - vector convert to decimal 32 bit */ + case 0xe659: /* VSRP - vector shift and round decimal */ + case 0xe65a: /* VCVDG - vector convert to decimal 64 bit*/ + case 0xe65b: /* VPSOP - vector perform sign operation decimal */ + case 0xe671: /* VAP - vector add decimal */ + case 0xe673: /* VSP - vector subtract decimal */ + case 0xe678: /* VMP - vector multiply decimal */ + case 0xe679: /* VMSP - vector multiply decimal */ + case 0xe67a: /* VDP - vector divide decimal */ + case 0xe67b: /* VRP - vector remainder decimal */ + case 0xe67e: /* VSDP - vector shift and divide decimal */ case 0xe74a: /* VFTCI - vector fp test data class immediate */ case 0xe75c: /* VISTR - vector isolate string */ case 0xe780: /* VFEE - vector find element equal */ @@ -6504,7 +6570,7 @@ ex: case 0xe797: /* VPKS - vector pack saturate */ case 0xe7e8: /* VFCE - vector fp compare equal */ case 0xe7ea: /* VFCHE - vector fp compare high or equal */ - case 0xe7eb: /* VFCE - vector fp compare high */ + case 0xe7eb: /* VFCH - vector fp compare high */ case 0xe7f8: /* VCEQ - vector compare equal */ case 0xe7f9: /* VCHL - vector compare high logical */ case 0xe7fb: /* VCH - vector compare high */ @@ -6517,6 +6583,14 @@ ex: return -1; break; + case 0xe65f: /* VTP - vector test decimal */ + /* flags + FPC */ + if (record_full_arch_list_add_reg (regcache, S390_PSWM_REGNUM)) + return -1; + if (record_full_arch_list_add_reg (regcache, S390_FPC_REGNUM)) + return -1; + break; + /* 0xe74b-0xe74c undefined */ /* 0xe74e-0xe74f undefined */ /* 0xe751 undefined */ @@ -6524,26 +6598,26 @@ ex: /* 0xe757-0xe75b undefined */ /* 0xe75d-0xe75e undefined */ /* 0xe763 undefined */ - /* 0xe76c undefined */ - /* 0xe76e-0xe76f undefined */ /* 0xe771 undefined */ /* 0xe776 undefined */ /* 0xe779 undefined */ /* 0xe77b undefined */ /* 0xe783 undefined */ - /* 0xe785-0xe789 undefined */ + /* 0xe786-0xe789 undefined */ /* 0xe78b undefined */ /* 0xe790-0xe793 undefined */ /* 0xe796 undefined */ - /* 0xe798-0xe7a0 undefined */ - /* 0xe7a8 undefined */ + /* 0xe798-0xe79d undefined */ + /* 0xe7a0 undefined */ + /* 0xe7a8 undefined */ /* 0xe7b0-0xe7b3 undefined */ - /* 0xe7b5-0xe7b8 undefined */ + /* 0xe7b5-0xe7b7 undefined */ /* 0xe7ba undefined */ /* 0xe7be undefined */ /* 0xe7c6 undefined */ /* 0xe7c8-0xe7c9 undefined */ + case 0xe677: /* VCP - vector compare decimal */ case 0xe7ca: /* WFK - vector fp compare and signal scalar */ case 0xe7cb: /* WFC - vector fp compare scalar */ case 0xe7d8: /* VTM - vector test under mask */ @@ -6568,7 +6642,7 @@ ex: /* 0xe7e4 undefined */ /* 0xe7e6 undefined */ /* 0xe7e9 undefined */ - /* 0xe7ec-0xe7ef undefined */ + /* 0xe7ec-0xe7ed undefined */ /* 0xe7f4 undefined */ /* 0xe7f6 undefined */ /* 0xe7fa undefined */ @@ -7048,8 +7122,6 @@ ex: } break; - /* 0xe6 undefined */ - case 0xec: /* RIE/RIS/RRS-format instruction */ switch (ibyte[0] << 8 | ibyte[5]) diff --git a/gdb/ser-mingw.c b/gdb/ser-mingw.c index 3f12458..0b78ba1 100644 --- a/gdb/ser-mingw.c +++ b/gdb/ser-mingw.c @@ -863,20 +863,18 @@ pipe_windows_open (struct serial *scb, const char *name) { struct pipe_state *ps; FILE *pex_stderr; - char **argv; struct cleanup *back_to; if (name == NULL) error_no_arg (_("child command")); - argv = gdb_buildargv (name); - back_to = make_cleanup_freeargv (argv); + gdb_argv argv (name); if (! argv[0] || argv[0][0] == '\0') error (_("missing child command")); ps = make_pipe_state (); - make_cleanup (cleanup_pipe_state, ps); + back_to = make_cleanup (cleanup_pipe_state, ps); ps->pex = pex_init (PEX_USE_PIPES, "target remote pipe", NULL); if (! ps->pex) @@ -890,7 +888,7 @@ pipe_windows_open (struct serial *scb, const char *name) const char *err_msg = pex_run (ps->pex, PEX_SEARCH | PEX_BINARY_INPUT | PEX_BINARY_OUTPUT | PEX_STDERR_TO_PIPE, - argv[0], argv, NULL, NULL, + argv[0], argv.get (), NULL, NULL, &err); if (err_msg) @@ -920,6 +918,7 @@ pipe_windows_open (struct serial *scb, const char *name) scb->state = (void *) ps; + argv.release (); discard_cleanups (back_to); return 0; @@ -35,98 +35,129 @@ #include "fnmatch.h" #include "gdb_regex.h" #include "common/gdb_optional.h" +#include <list> -struct skiplist_entry +class skiplist_entry { - int number; - - /* Non-zero if FILE is a glob-style pattern. - Otherewise it is the plain file name (possibly with directories). */ - int file_is_glob; - - /* The name of the file or NULL. - The skiplist entry owns this pointer. */ - char *file; - - /* Non-zero if FUNCTION is a regexp. +public: + /* Create a skiplist_entry object and add it to the chain. */ + static void add_entry (bool file_is_glob, + std::string &&file, + bool function_is_regexp, + std::string &&function); + + /* Return true if the skip entry has a file or glob-style file + pattern that matches FUNCTION_SAL. */ + bool skip_file_p (const symtab_and_line &function_sal) const; + + /* Return true if the skip entry has a function or function regexp + that matches FUNCTION_NAME. */ + bool skip_function_p (const char *function_name) const; + + /* Getters. */ + int number () const { return m_number; }; + bool enabled () const { return m_enabled; }; + bool file_is_glob () const { return m_file_is_glob; } + const std::string &file () const { return m_file; } + const std::string &function () const { return m_function; } + bool function_is_regexp () const { return m_function_is_regexp; } + + /* Setters. */ + void enable () { m_enabled = true; }; + void disable () { m_enabled = false; }; + + /* Disable copy. */ + skiplist_entry (const skiplist_entry &) = delete; + void operator= (const skiplist_entry &) = delete; + +private: + /* Key that grants access to the constructor. */ + struct private_key {}; +public: + /* Public so we can construct with container::emplace_back. Since + it requires a private class key, it can't be called from outside. + Use the add_entry static factory method to construct instead. */ + skiplist_entry (bool file_is_glob, std::string &&file, + bool function_is_regexp, std::string &&function, + private_key); + +private: + /* Return true if we're stopped at a file to be skipped. */ + bool do_skip_file_p (const symtab_and_line &function_sal) const; + + /* Return true if we're stopped at a globbed file to be skipped. */ + bool do_skip_gfile_p (const symtab_and_line &function_sal) const; + +private: /* data */ + int m_number = -1; + + /* True if FILE is a glob-style pattern. + Otherwise it is the plain file name (possibly with directories). */ + bool m_file_is_glob; + + /* The name of the file or empty if no name. */ + std::string m_file; + + /* True if FUNCTION is a regexp. Otherwise it is a plain function name (possibly with arguments, for C++). */ - int function_is_regexp; + bool m_function_is_regexp; - /* The name of the function or NULL. - The skiplist entry owns this pointer. */ - char *function; + /* The name of the function or empty if no name. */ + std::string m_function; /* If this is a function regexp, the compiled form. */ - gdb::optional<compiled_regex> compiled_function_regexp; + gdb::optional<compiled_regex> m_compiled_function_regexp; - int enabled; - - struct skiplist_entry *next; + /* Enabled/disabled state. */ + bool m_enabled = true; }; -static void add_skiplist_entry (struct skiplist_entry *e); - -static struct skiplist_entry *skiplist_entry_chain; -static int skiplist_entry_count; - -#define ALL_SKIPLIST_ENTRIES(E) \ - for (E = skiplist_entry_chain; E; E = E->next) - -#define ALL_SKIPLIST_ENTRIES_SAFE(E,TMP) \ - for (E = skiplist_entry_chain; \ - E ? (TMP = E->next, 1) : 0; \ - E = TMP) - -/* Create a skip object. */ - -static struct skiplist_entry * -make_skip_entry (int file_is_glob, const char *file, - int function_is_regexp, const char *function) +static std::list<skiplist_entry> skiplist_entries; +static int highest_skiplist_entry_num = 0; + +skiplist_entry::skiplist_entry (bool file_is_glob, + std::string &&file, + bool function_is_regexp, + std::string &&function, + private_key) + : m_file_is_glob (file_is_glob), + m_file (std::move (file)), + m_function_is_regexp (function_is_regexp), + m_function (std::move (function)) { - struct skiplist_entry *e = XCNEW (struct skiplist_entry); - - gdb_assert (file != NULL || function != NULL); - if (file_is_glob) - gdb_assert (file != NULL); - if (function_is_regexp) - gdb_assert (function != NULL); - - if (file != NULL) - e->file = xstrdup (file); - if (function != NULL) - e->function = xstrdup (function); - e->file_is_glob = file_is_glob; - e->function_is_regexp = function_is_regexp; - e->enabled = 1; - - return e; -} + gdb_assert (!m_file.empty () || !m_function.empty ()); -/* Free a skiplist entry. */ + if (m_file_is_glob) + gdb_assert (!m_file.empty ()); -static void -free_skiplist_entry (struct skiplist_entry *e) -{ - xfree (e->file); - xfree (e->function); - xfree (e); -} + if (m_function_is_regexp) + { + gdb_assert (!m_function.empty ()); -/* Wrapper to free_skiplist_entry for use as a cleanup. */ + int flags = REG_NOSUB; +#ifdef REG_EXTENDED + flags |= REG_EXTENDED; +#endif -static void -free_skiplist_entry_cleanup (void *e) -{ - free_skiplist_entry ((struct skiplist_entry *) e); + gdb_assert (!m_function.empty ()); + m_compiled_function_regexp.emplace (m_function.c_str (), flags, + _("regexp")); + } } -/* Create a cleanup to free skiplist entry E. */ - -static struct cleanup * -make_free_skiplist_entry_cleanup (struct skiplist_entry *e) +void +skiplist_entry::add_entry (bool file_is_glob, std::string &&file, + bool function_is_regexp, std::string &&function) { - return make_cleanup (free_skiplist_entry_cleanup, e); + skiplist_entries.emplace_back (file_is_glob, + std::move (file), + function_is_regexp, + std::move (function), + private_key {}); + + /* Incremented after push_back, in case push_back throws. */ + skiplist_entries.back ().m_number = ++highest_skiplist_entry_num; } static void @@ -150,7 +181,8 @@ skip_file_command (char *arg, int from_tty) else filename = arg; - add_skiplist_entry (make_skip_entry (0, filename, 0, NULL)); + skiplist_entry::add_entry (false, std::string (filename), + false, std::string ()); printf_filtered (_("File %s will be skipped when stepping.\n"), filename); } @@ -161,7 +193,7 @@ skip_file_command (char *arg, int from_tty) static void skip_function (const char *name) { - add_skiplist_entry (make_skip_entry (0, NULL, 0, name)); + skiplist_entry::add_entry (false, std::string (), false, std::string (name)); printf_filtered (_("Function %s will be skipped when stepping.\n"), name); } @@ -191,23 +223,6 @@ skip_function_command (char *arg, int from_tty) skip_function (arg); } -/* Compile the regexp in E. - An error is thrown if there's an error. - MESSAGE is used as a prefix of the error message. */ - -static void -compile_skip_regexp (struct skiplist_entry *e, const char *message) -{ - int flags = REG_NOSUB; - -#ifdef REG_EXTENDED - flags |= REG_EXTENDED; -#endif - - gdb_assert (e->function_is_regexp && e->function != NULL); - e->compiled_function_regexp.emplace (e->function, flags, message); -} - /* Process "skip ..." that does not match "skip file" or "skip function". */ static void @@ -217,9 +232,6 @@ skip_command (char *arg, int from_tty) const char *gfile = NULL; const char *function = NULL; const char *rfunction = NULL; - char **argv; - struct cleanup *cleanups; - struct skiplist_entry *e; int i; if (arg == NULL) @@ -228,8 +240,7 @@ skip_command (char *arg, int from_tty) return; } - argv = buildargv (arg); - cleanups = make_cleanup_freeargv (argv); + gdb_argv argv (arg); for (i = 0; argv[i] != NULL; ++i) { @@ -276,7 +287,6 @@ skip_command (char *arg, int from_tty) FUNCTION-NAME may be `foo (int)', and therefore we pass the complete original arg to skip_function command as if the user typed "skip function arg". */ - do_cleanups (cleanups); skip_function_command (arg, from_tty); return; } @@ -295,16 +305,20 @@ skip_command (char *arg, int from_tty) gdb_assert (file != NULL || gfile != NULL || function != NULL || rfunction != NULL); - e = make_skip_entry (gfile != NULL, file ? file : gfile, - rfunction != NULL, function ? function : rfunction); - if (rfunction != NULL) - { - struct cleanup *rf_cleanups = make_free_skiplist_entry_cleanup (e); + std::string entry_file; + if (file != NULL) + entry_file = file; + else if (gfile != NULL) + entry_file = gfile; - compile_skip_regexp (e, _("regexp")); - discard_cleanups (rf_cleanups); - } - add_skiplist_entry (e); + std::string entry_function; + if (function != NULL) + entry_function = function; + else if (rfunction != NULL) + entry_function = rfunction; + + skiplist_entry::add_entry (gfile != NULL, std::move (entry_file), + rfunction != NULL, std::move (entry_function)); /* I18N concerns drive some of the choices here (we can't piece together the output too much). OTOH we want to keep this simple. Therefore the @@ -336,24 +350,20 @@ skip_command (char *arg, int from_tty) lower_file_text, file_to_print); } } - - do_cleanups (cleanups); } static void skip_info (char *arg, int from_tty) { - struct skiplist_entry *e; int num_printable_entries = 0; struct value_print_options opts; - struct cleanup *tbl_chain; get_user_print_options (&opts); /* Count the number of rows in the table and see if we need space for a 64-bit address anywhere. */ - ALL_SKIPLIST_ENTRIES (e) - if (arg == NULL || number_is_in_list (arg, e->number)) + for (const skiplist_entry &e : skiplist_entries) + if (arg == NULL || number_is_in_list (arg, e.number ())) num_printable_entries++; if (num_printable_entries == 0) @@ -367,9 +377,8 @@ skip_info (char *arg, int from_tty) return; } - tbl_chain = make_cleanup_ui_out_table_begin_end (current_uiout, 6, - num_printable_entries, - "SkiplistTable"); + ui_out_emit_table table_emitter (current_uiout, 6, num_printable_entries, + "SkiplistTable"); current_uiout->table_header (5, ui_left, "number", "Num"); /* 1 */ current_uiout->table_header (3, ui_left, "enabled", "Enb"); /* 2 */ @@ -379,53 +388,51 @@ skip_info (char *arg, int from_tty) current_uiout->table_header (40, ui_noalign, "function", "Function"); /* 6 */ current_uiout->table_body (); - ALL_SKIPLIST_ENTRIES (e) + for (const skiplist_entry &e : skiplist_entries) { - QUIT; - if (arg != NULL && !number_is_in_list (arg, e->number)) + if (arg != NULL && !number_is_in_list (arg, e.number ())) continue; ui_out_emit_tuple tuple_emitter (current_uiout, "blklst-entry"); - current_uiout->field_int ("number", e->number); /* 1 */ + current_uiout->field_int ("number", e.number ()); /* 1 */ - if (e->enabled) + if (e.enabled ()) current_uiout->field_string ("enabled", "y"); /* 2 */ else current_uiout->field_string ("enabled", "n"); /* 2 */ - if (e->file_is_glob) + if (e.file_is_glob ()) current_uiout->field_string ("regexp", "y"); /* 3 */ else current_uiout->field_string ("regexp", "n"); /* 3 */ current_uiout->field_string ("file", - e->file ? e->file : "<none>"); /* 4 */ - if (e->function_is_regexp) + e.file ().empty () ? "<none>" + : e.file ().c_str ()); /* 4 */ + if (e.function_is_regexp ()) current_uiout->field_string ("regexp", "y"); /* 5 */ else current_uiout->field_string ("regexp", "n"); /* 5 */ - current_uiout->field_string ( - "function", e->function ? e->function : "<none>"); /* 6 */ + current_uiout->field_string ("function", + e.function ().empty () ? "<none>" + : e.function ().c_str ()); /* 6 */ current_uiout->text ("\n"); } - - do_cleanups (tbl_chain); } static void skip_enable_command (char *arg, int from_tty) { - struct skiplist_entry *e; - int found = 0; + bool found = false; - ALL_SKIPLIST_ENTRIES (e) - if (arg == NULL || number_is_in_list (arg, e->number)) + for (skiplist_entry &e : skiplist_entries) + if (arg == NULL || number_is_in_list (arg, e.number ())) { - e->enabled = 1; - found = 1; + e.enable (); + found = true; } if (!found) @@ -435,14 +442,13 @@ skip_enable_command (char *arg, int from_tty) static void skip_disable_command (char *arg, int from_tty) { - struct skiplist_entry *e; - int found = 0; + bool found = false; - ALL_SKIPLIST_ENTRIES (e) - if (arg == NULL || number_is_in_list (arg, e->number)) + for (skiplist_entry &e : skiplist_entries) + if (arg == NULL || number_is_in_list (arg, e.number ())) { - e->enabled = 0; - found = 1; + e.disable (); + found = true; } if (!found) @@ -452,103 +458,62 @@ skip_disable_command (char *arg, int from_tty) static void skip_delete_command (char *arg, int from_tty) { - struct skiplist_entry *e, *temp, *b_prev; - int found = 0; + bool found = false; - b_prev = 0; - ALL_SKIPLIST_ENTRIES_SAFE (e, temp) - if (arg == NULL || number_is_in_list (arg, e->number)) - { - if (b_prev != NULL) - b_prev->next = e->next; - else - skiplist_entry_chain = e->next; + for (auto it = skiplist_entries.begin (), + end = skiplist_entries.end (); + it != end;) + { + const skiplist_entry &e = *it; - free_skiplist_entry (e); - found = 1; - } - else - { - b_prev = e; - } + if (arg == NULL || number_is_in_list (arg, e.number ())) + { + it = skiplist_entries.erase (it); + found = true; + } + else + ++it; + } if (!found) error (_("No skiplist entries found with number %s."), arg); } -/* Add the given skiplist entry to our list, and set the entry's number. */ - -static void -add_skiplist_entry (struct skiplist_entry *e) -{ - struct skiplist_entry *e1; - - e->number = ++skiplist_entry_count; - - /* Add to the end of the chain so that the list of - skiplist entries will be in numerical order. */ - - e1 = skiplist_entry_chain; - if (e1 == NULL) - skiplist_entry_chain = e; - else - { - while (e1->next) - e1 = e1->next; - e1->next = e; - } -} - -/* Return non-zero if we're stopped at a file to be skipped. */ - -static int -skip_file_p (struct skiplist_entry *e, - const struct symtab_and_line *function_sal) +bool +skiplist_entry::do_skip_file_p (const symtab_and_line &function_sal) const { - gdb_assert (e->file != NULL && !e->file_is_glob); - - if (function_sal->symtab == NULL) - return 0; - /* Check first sole SYMTAB->FILENAME. It may not be a substring of symtab_to_fullname as it may contain "./" etc. */ - if (compare_filenames_for_search (function_sal->symtab->filename, e->file)) - return 1; + if (compare_filenames_for_search (function_sal.symtab->filename, + m_file.c_str ())) + return true; /* Before we invoke realpath, which can get expensive when many files are involved, do a quick comparison of the basenames. */ if (!basenames_may_differ - && filename_cmp (lbasename (function_sal->symtab->filename), - lbasename (e->file)) != 0) - return 0; + && filename_cmp (lbasename (function_sal.symtab->filename), + lbasename (m_file.c_str ())) != 0) + return false; /* Note: symtab_to_fullname caches its result, thus we don't have to. */ { - const char *fullname = symtab_to_fullname (function_sal->symtab); + const char *fullname = symtab_to_fullname (function_sal.symtab); - if (compare_filenames_for_search (fullname, e->file)) - return 1; + if (compare_filenames_for_search (fullname, m_file.c_str ())) + return true; } - return 0; + return false; } -/* Return non-zero if we're stopped at a globbed file to be skipped. */ - -static int -skip_gfile_p (struct skiplist_entry *e, - const struct symtab_and_line *function_sal) +bool +skiplist_entry::do_skip_gfile_p (const symtab_and_line &function_sal) const { - gdb_assert (e->file != NULL && e->file_is_glob); - - if (function_sal->symtab == NULL) - return 0; - /* Check first sole SYMTAB->FILENAME. It may not be a substring of symtab_to_fullname as it may contain "./" etc. */ - if (gdb_filename_fnmatch (e->file, function_sal->symtab->filename, + if (gdb_filename_fnmatch (m_file.c_str (), function_sal.symtab->filename, FNM_FILE_NAME | FNM_NOESCAPE) == 0) - return 1; + return true; /* Before we invoke symtab_to_fullname, which is expensive, do a quick comparison of the basenames. @@ -556,101 +521,83 @@ skip_gfile_p (struct skiplist_entry *e, If the basename of the glob pattern is something like "*.c" then this isn't much of a win. Oh well. */ if (!basenames_may_differ - && gdb_filename_fnmatch (lbasename (e->file), - lbasename (function_sal->symtab->filename), + && gdb_filename_fnmatch (lbasename (m_file.c_str ()), + lbasename (function_sal.symtab->filename), FNM_FILE_NAME | FNM_NOESCAPE) != 0) - return 0; + return false; /* Note: symtab_to_fullname caches its result, thus we don't have to. */ { - const char *fullname = symtab_to_fullname (function_sal->symtab); + const char *fullname = symtab_to_fullname (function_sal.symtab); - if (compare_glob_filenames_for_search (fullname, e->file)) - return 1; + if (compare_glob_filenames_for_search (fullname, m_file.c_str ())) + return true; } - return 0; + return false; } -/* Return non-zero if we're stopped at a function to be skipped. */ - -static int -skip_function_p (struct skiplist_entry *e, const char *function_name) +bool +skiplist_entry::skip_file_p (const symtab_and_line &function_sal) const { - gdb_assert (e->function != NULL && !e->function_is_regexp); - return strcmp_iw (function_name, e->function) == 0; -} + if (m_file.empty ()) + return false; -/* Return non-zero if we're stopped at a function regexp to be skipped. */ + if (function_sal.symtab == NULL) + return false; -static int -skip_rfunction_p (struct skiplist_entry *e, const char *function_name) + if (m_file_is_glob) + return do_skip_gfile_p (function_sal); + else + return do_skip_file_p (function_sal); +} + +bool +skiplist_entry::skip_function_p (const char *function_name) const { - gdb_assert (e->function != NULL && e->function_is_regexp - && e->compiled_function_regexp); - return (e->compiled_function_regexp->exec (function_name, 0, NULL, 0) - == 0); + if (m_function.empty ()) + return false; + + if (m_function_is_regexp) + { + gdb_assert (m_compiled_function_regexp); + return (m_compiled_function_regexp->exec (function_name, 0, NULL, 0) + == 0); + } + else + return strcmp_iw (function_name, m_function.c_str ()) == 0; } /* See skip.h. */ -int +bool function_name_is_marked_for_skip (const char *function_name, - const struct symtab_and_line *function_sal) + const symtab_and_line &function_sal) { - struct skiplist_entry *e; - if (function_name == NULL) - return 0; + return false; - ALL_SKIPLIST_ENTRIES (e) + for (const skiplist_entry &e : skiplist_entries) { - int skip_by_file = 0; - int skip_by_function = 0; - - if (!e->enabled) + if (!e.enabled ()) continue; - if (e->file != NULL) - { - if (e->file_is_glob) - { - if (skip_gfile_p (e, function_sal)) - skip_by_file = 1; - } - else - { - if (skip_file_p (e, function_sal)) - skip_by_file = 1; - } - } - if (e->function != NULL) - { - if (e->function_is_regexp) - { - if (skip_rfunction_p (e, function_name)) - skip_by_function = 1; - } - else - { - if (skip_function_p (e, function_name)) - skip_by_function = 1; - } - } + bool skip_by_file = e.skip_file_p (function_sal); + bool skip_by_function = e.skip_function_p (function_name); /* If both file and function must match, make sure we don't errantly exit if only one of them match. */ - if (e->file != NULL && e->function != NULL) + if (!e.file ().empty () && !e.function ().empty ()) { if (skip_by_file && skip_by_function) - return 1; + return true; } /* Only one of file/function is specified. */ else if (skip_by_file || skip_by_function) - return 1; + return true; } - return 0; + return false; } /* Provide a prototype to silence -Wmissing-prototypes. */ @@ -662,9 +609,6 @@ _initialize_step_skip (void) static struct cmd_list_element *skiplist = NULL; struct cmd_list_element *c; - skiplist_entry_chain = 0; - skiplist_entry_count = 0; - add_prefix_cmd ("skip", class_breakpoint, skip_command, _("\ Ignore a function while stepping.\n\ \n\ @@ -20,9 +20,9 @@ struct symtab_and_line; -/* Returns 1 if the given FUNCTION_NAME is marked for skip and shouldn't be - stepped into. Otherwise, returns 0. */ -int function_name_is_marked_for_skip (const char *function_name, - const struct symtab_and_line *function_sal); +/* Returns true if the given FUNCTION_NAME is marked for skip and + shouldn't be stepped into. Otherwise, returns false. */ +bool function_name_is_marked_for_skip (const char *function_name, + const symtab_and_line &function_sal); #endif /* !defined (SKIP_H) */ diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c index 3651929..c2b776d 100644 --- a/gdb/solib-darwin.c +++ b/gdb/solib-darwin.c @@ -67,7 +67,7 @@ struct gdb_dyld_all_image_infos /* Current all_image_infos version. */ #define DYLD_VERSION_MIN 1 -#define DYLD_VERSION_MAX 14 +#define DYLD_VERSION_MAX 15 /* Per PSPACE specific data. */ struct darwin_info diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 080fd79..f99e2e2 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -1350,21 +1350,15 @@ svr4_read_so_list (CORE_ADDR lm, CORE_ADDR prev_lm, for (; lm != 0; prev_lm = lm, lm = next_lm) { - struct so_list *newobj; - struct cleanup *old_chain; int errcode; char *buffer; - newobj = XCNEW (struct so_list); - old_chain = make_cleanup_free_so (newobj); + so_list_up newobj (XCNEW (struct so_list)); lm_info_svr4 *li = lm_info_read (lm); newobj->lm_info = li; if (li == NULL) - { - do_cleanups (old_chain); - return 0; - } + return 0; next_lm = li->l_next; @@ -1373,7 +1367,6 @@ svr4_read_so_list (CORE_ADDR lm, CORE_ADDR prev_lm, warning (_("Corrupted shared library list: %s != %s"), paddress (target_gdbarch (), prev_lm), paddress (target_gdbarch (), li->l_prev)); - do_cleanups (old_chain); return 0; } @@ -1388,7 +1381,6 @@ svr4_read_so_list (CORE_ADDR lm, CORE_ADDR prev_lm, first_l_name = li->l_name; info->main_lm_addr = li->lm_addr; - do_cleanups (old_chain); continue; } @@ -1404,7 +1396,6 @@ svr4_read_so_list (CORE_ADDR lm, CORE_ADDR prev_lm, if (first_l_name == 0 || li->l_name != first_l_name) warning (_("Can't read pathname for load map: %s."), safe_strerror (errcode)); - do_cleanups (old_chain); continue; } @@ -1416,15 +1407,12 @@ svr4_read_so_list (CORE_ADDR lm, CORE_ADDR prev_lm, /* If this entry has no name, or its name matches the name for the main executable, don't include it in the list. */ if (! newobj->so_name[0] || match_main (newobj->so_name)) - { - do_cleanups (old_chain); - continue; - } + continue; - discard_cleanups (old_chain); newobj->next = 0; - **link_ptr_ptr = newobj; - *link_ptr_ptr = &newobj->next; + /* Don't free it now. */ + **link_ptr_ptr = newobj.release (); + *link_ptr_ptr = &(**link_ptr_ptr)->next; } return 1; diff --git a/gdb/solib.c b/gdb/solib.c index 788cf15..c8fe4d2 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -546,14 +546,10 @@ static int solib_map_sections (struct so_list *so) { const struct target_so_ops *ops = solib_ops (target_gdbarch ()); - char *filename; struct target_section *p; - struct cleanup *old_chain; - filename = tilde_expand (so->so_name); - old_chain = make_cleanup (xfree, filename); - gdb_bfd_ref_ptr abfd (ops->bfd_open (filename)); - do_cleanups (old_chain); + gdb::unique_xmalloc_ptr<char> filename (tilde_expand (so->so_name)); + gdb_bfd_ref_ptr abfd (ops->bfd_open (filename.get ())); if (abfd == NULL) return 0; @@ -1045,7 +1041,6 @@ info_sharedlibrary_command (char *pattern, int from_tty) int so_missing_debug_info = 0; int addr_width; int nr_libs; - struct cleanup *table_cleanup; struct gdbarch *gdbarch = target_gdbarch (); struct ui_out *uiout = current_uiout; @@ -1062,8 +1057,8 @@ info_sharedlibrary_command (char *pattern, int from_tty) update_solib_list (from_tty); - /* make_cleanup_ui_out_table_begin_end needs to know the number of - rows, so we need to make two passes over the libs. */ + /* ui_out_emit_table table_emitter needs to know the number of rows, + so we need to make two passes over the libs. */ for (nr_libs = 0, so = so_list_head; so; so = so->next) { @@ -1075,54 +1070,52 @@ info_sharedlibrary_command (char *pattern, int from_tty) } } - table_cleanup = - make_cleanup_ui_out_table_begin_end (uiout, 4, nr_libs, - "SharedLibraryTable"); - - /* The "- 1" is because ui_out adds one space between columns. */ - uiout->table_header (addr_width - 1, ui_left, "from", "From"); - uiout->table_header (addr_width - 1, ui_left, "to", "To"); - uiout->table_header (12 - 1, ui_left, "syms-read", "Syms Read"); - uiout->table_header (0, ui_noalign, "name", "Shared Object Library"); - - uiout->table_body (); - - ALL_SO_LIBS (so) - { - if (! so->so_name[0]) - continue; - if (pattern && ! re_exec (so->so_name)) - continue; - - ui_out_emit_tuple tuple_emitter (uiout, "lib"); - - if (so->addr_high != 0) - { - uiout->field_core_addr ("from", gdbarch, so->addr_low); - uiout->field_core_addr ("to", gdbarch, so->addr_high); - } - else - { - uiout->field_skip ("from"); - uiout->field_skip ("to"); - } - - if (! interp_ui_out (top_level_interpreter ())->is_mi_like_p () - && so->symbols_loaded - && !objfile_has_symbols (so->objfile)) - { - so_missing_debug_info = 1; - uiout->field_string ("syms-read", "Yes (*)"); - } - else - uiout->field_string ("syms-read", so->symbols_loaded ? "Yes" : "No"); + { + ui_out_emit_table table_emitter (uiout, 4, nr_libs, "SharedLibraryTable"); - uiout->field_string ("name", so->so_name); + /* The "- 1" is because ui_out adds one space between columns. */ + uiout->table_header (addr_width - 1, ui_left, "from", "From"); + uiout->table_header (addr_width - 1, ui_left, "to", "To"); + uiout->table_header (12 - 1, ui_left, "syms-read", "Syms Read"); + uiout->table_header (0, ui_noalign, "name", "Shared Object Library"); - uiout->text ("\n"); - } + uiout->table_body (); - do_cleanups (table_cleanup); + ALL_SO_LIBS (so) + { + if (! so->so_name[0]) + continue; + if (pattern && ! re_exec (so->so_name)) + continue; + + ui_out_emit_tuple tuple_emitter (uiout, "lib"); + + if (so->addr_high != 0) + { + uiout->field_core_addr ("from", gdbarch, so->addr_low); + uiout->field_core_addr ("to", gdbarch, so->addr_high); + } + else + { + uiout->field_skip ("from"); + uiout->field_skip ("to"); + } + + if (! interp_ui_out (top_level_interpreter ())->is_mi_like_p () + && so->symbols_loaded + && !objfile_has_symbols (so->objfile)) + { + so_missing_debug_info = 1; + uiout->field_string ("syms-read", "Yes (*)"); + } + else + uiout->field_string ("syms-read", so->symbols_loaded ? "Yes" : "No"); + + uiout->field_string ("name", so->so_name); + + uiout->text ("\n"); + } + } if (nr_libs == 0) { @@ -1304,28 +1297,24 @@ static void reload_shared_libraries_1 (int from_tty) { struct so_list *so; - struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); if (print_symbol_loading_p (from_tty, 0, 0)) printf_unfiltered (_("Loading symbols for shared libraries.\n")); for (so = so_list_head; so != NULL; so = so->next) { - char *filename, *found_pathname = NULL; + char *found_pathname = NULL; int was_loaded = so->symbols_loaded; symfile_add_flags add_flags = SYMFILE_DEFER_BP_RESET; if (from_tty) add_flags |= SYMFILE_VERBOSE; - filename = tilde_expand (so->so_original_name); - make_cleanup (xfree, filename); - gdb_bfd_ref_ptr abfd (solib_bfd_open (filename)); + gdb::unique_xmalloc_ptr<char> filename + (tilde_expand (so->so_original_name)); + gdb_bfd_ref_ptr abfd (solib_bfd_open (filename.get ())); if (abfd != NULL) - { - found_pathname = xstrdup (bfd_get_filename (abfd.get ())); - make_cleanup (xfree, found_pathname); - } + found_pathname = bfd_get_filename (abfd.get ()); /* If this shared library is no longer associated with its previous symbol file, close that. */ @@ -1367,8 +1356,6 @@ reload_shared_libraries_1 (int from_tty) solib_read_symbols (so, add_flags); } } - - do_cleanups (old_chain); } static void diff --git a/gdb/solist.h b/gdb/solist.h index 54c9902..5eb2d39 100644 --- a/gdb/solist.h +++ b/gdb/solist.h @@ -179,6 +179,18 @@ struct target_so_ops /* Free the memory associated with a (so_list *). */ void free_so (struct so_list *so); +/* A deleter that calls free_so. */ +struct so_deleter +{ + void operator() (struct so_list *so) const + { + free_so (so); + } +}; + +/* A unique pointer to a so_list. */ +typedef std::unique_ptr<so_list, so_deleter> so_list_up; + /* Return address of first so_list entry in master shared object list. */ struct so_list *master_so_list (void); diff --git a/gdb/source.c b/gdb/source.c index 8926e547..769d9ef 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -484,16 +484,12 @@ add_path (char *dirname, char **which_path, int parse_separators) if (parse_separators) { - char **argv, **argvp; - /* This will properly parse the space and tab separators and any quotes that may exist. */ - argv = gdb_buildargv (dirname); - - for (argvp = argv; *argvp; argvp++) - dirnames_to_char_ptr_vec_append (&dir_vec, *argvp); + gdb_argv argv (dirname); - freeargv (argv); + for (char *arg : argv) + dirnames_to_char_ptr_vec_append (&dir_vec, arg); } else VEC_safe_push (char_ptr, dir_vec, xstrdup (dirname)); @@ -859,20 +855,18 @@ openp (const char *path, int opts, const char *string, { /* See whether we need to expand the tilde. */ int newlen; - char *tilde_expanded; - tilde_expanded = tilde_expand (dir); + gdb::unique_xmalloc_ptr<char> tilde_expanded (tilde_expand (dir)); /* First, realloc the filename buffer if too short. */ - len = strlen (tilde_expanded); + len = strlen (tilde_expanded.get ()); newlen = len + strlen (string) + 2; if (newlen > alloclen) { alloclen = newlen; filename = (char *) alloca (alloclen); } - strcpy (filename, tilde_expanded); - xfree (tilde_expanded); + strcpy (filename, tilde_expanded.get ()); } else { @@ -1353,9 +1347,7 @@ print_source_lines_base (struct symtab *s, int line, int stopline, int c; int desc; int noprint = 0; - FILE *stream; int nlines = stopline - line; - struct cleanup *cleanup; struct ui_out *uiout = current_uiout; /* Regardless of whether we can open the file, set current_source_symtab. */ @@ -1448,15 +1440,14 @@ print_source_lines_base (struct symtab *s, int line, int stopline, perror_with_name (symtab_to_filename_for_display (s)); } - stream = fdopen (desc, FDOPEN_MODE); - clearerr (stream); - cleanup = make_cleanup_fclose (stream); + gdb_file_up stream (fdopen (desc, FDOPEN_MODE)); + clearerr (stream.get ()); while (nlines-- > 0) { char buf[20]; - c = fgetc (stream); + c = fgetc (stream.get ()); if (c == EOF) break; last_line_listed = current_source_line; @@ -1479,12 +1470,12 @@ print_source_lines_base (struct symtab *s, int line, int stopline, else if (c == '\r') { /* Skip a \r character, but only before a \n. */ - int c1 = fgetc (stream); + int c1 = fgetc (stream.get ()); if (c1 != '\n') printf_filtered ("^%c", c + 0100); if (c1 != EOF) - ungetc (c1, stream); + ungetc (c1, stream.get ()); } else { @@ -1492,10 +1483,8 @@ print_source_lines_base (struct symtab *s, int line, int stopline, uiout->text (buf); } } - while (c != '\n' && (c = fgetc (stream)) >= 0); + while (c != '\n' && (c = fgetc (stream.get ())) >= 0); } - - do_cleanups (cleanup); } /* Show source lines from the file of symtab S, starting with line @@ -1630,7 +1619,6 @@ forward_search_command (char *regex, int from_tty) { int c; int desc; - FILE *stream; int line; char *msg; struct cleanup *cleanups; @@ -1659,9 +1647,8 @@ forward_search_command (char *regex, int from_tty) perror_with_name (symtab_to_filename_for_display (current_source_symtab)); discard_cleanups (cleanups); - stream = fdopen (desc, FDOPEN_MODE); - clearerr (stream); - cleanups = make_cleanup_fclose (stream); + gdb_file_up stream (fdopen (desc, FDOPEN_MODE)); + clearerr (stream.get ()); while (1) { static char *buf = NULL; @@ -1672,7 +1659,7 @@ forward_search_command (char *regex, int from_tty) buf = (char *) xmalloc (cursize); p = buf; - c = fgetc (stream); + c = fgetc (stream.get ()); if (c == EOF) break; do @@ -1686,7 +1673,7 @@ forward_search_command (char *regex, int from_tty) cursize = newsize; } } - while (c != '\n' && (c = fgetc (stream)) >= 0); + while (c != '\n' && (c = fgetc (stream.get ())) >= 0); /* Remove the \r, if any, at the end of the line, otherwise regular expressions that end with $ or \n won't work. */ @@ -1701,7 +1688,6 @@ forward_search_command (char *regex, int from_tty) if (re_exec (buf) > 0) { /* Match! */ - do_cleanups (cleanups); print_source_lines (current_source_symtab, line, line + 1, 0); set_internalvar_integer (lookup_internalvar ("_"), line); current_source_line = std::max (line - lines_to_list / 2, 1); @@ -1711,7 +1697,6 @@ forward_search_command (char *regex, int from_tty) } printf_filtered (_("Expression not found\n")); - do_cleanups (cleanups); } static void @@ -1719,7 +1704,6 @@ reverse_search_command (char *regex, int from_tty) { int c; int desc; - FILE *stream; int line; char *msg; struct cleanup *cleanups; @@ -1748,23 +1732,22 @@ reverse_search_command (char *regex, int from_tty) perror_with_name (symtab_to_filename_for_display (current_source_symtab)); discard_cleanups (cleanups); - stream = fdopen (desc, FDOPEN_MODE); - clearerr (stream); - cleanups = make_cleanup_fclose (stream); + gdb_file_up stream (fdopen (desc, FDOPEN_MODE)); + clearerr (stream.get ()); while (line > 1) { /* FIXME!!! We walk right off the end of buf if we get a long line!!! */ char buf[4096]; /* Should be reasonable??? */ char *p = buf; - c = fgetc (stream); + c = fgetc (stream.get ()); if (c == EOF) break; do { *p++ = c; } - while (c != '\n' && (c = fgetc (stream)) >= 0); + while (c != '\n' && (c = fgetc (stream.get ())) >= 0); /* Remove the \r, if any, at the end of the line, otherwise regular expressions that end with $ or \n won't work. */ @@ -1779,25 +1762,23 @@ reverse_search_command (char *regex, int from_tty) if (re_exec (buf) > 0) { /* Match! */ - do_cleanups (cleanups); print_source_lines (current_source_symtab, line, line + 1, 0); set_internalvar_integer (lookup_internalvar ("_"), line); current_source_line = std::max (line - lines_to_list / 2, 1); return; } line--; - if (fseek (stream, current_source_symtab->line_charpos[line - 1], 0) < 0) + if (fseek (stream.get (), + current_source_symtab->line_charpos[line - 1], 0) < 0) { const char *filename; - do_cleanups (cleanups); filename = symtab_to_filename_for_display (current_source_symtab); perror_with_name (filename); } } printf_filtered (_("Expression not found\n")); - do_cleanups (cleanups); return; } @@ -1896,12 +1877,9 @@ static void show_substitute_path_command (char *args, int from_tty) { struct substitute_path_rule *rule = substitute_path_rules; - char **argv; char *from = NULL; - struct cleanup *cleanup; - argv = gdb_buildargv (args); - cleanup = make_cleanup_freeargv (argv); + gdb_argv argv (args); /* We expect zero or one argument. */ @@ -1925,8 +1903,6 @@ show_substitute_path_command (char *args, int from_tty) printf_filtered (" `%s' -> `%s'.\n", rule->from, rule->to); rule = rule->next; } - - do_cleanups (cleanup); } /* Implement the "unset substitute-path" command. */ @@ -1935,14 +1911,12 @@ static void unset_substitute_path_command (char *args, int from_tty) { struct substitute_path_rule *rule = substitute_path_rules; - char **argv = gdb_buildargv (args); + gdb_argv argv (args); char *from = NULL; int rule_found = 0; - struct cleanup *cleanup; /* This function takes either 0 or 1 argument. */ - cleanup = make_cleanup_freeargv (argv); if (argv != NULL && argv[0] != NULL && argv[1] != NULL) error (_("Incorrect usage, too many arguments in command")); @@ -1980,8 +1954,6 @@ unset_substitute_path_command (char *args, int from_tty) error (_("No substitution rule defined for `%s'"), from); forget_cached_source_info (); - - do_cleanups (cleanup); } /* Add a new source path substitution rule. */ @@ -1989,12 +1961,9 @@ unset_substitute_path_command (char *args, int from_tty) static void set_substitute_path_command (char *args, int from_tty) { - char **argv; struct substitute_path_rule *rule; - struct cleanup *cleanup; - argv = gdb_buildargv (args); - cleanup = make_cleanup_freeargv (argv); + gdb_argv argv (args); if (argv == NULL || argv[0] == NULL || argv [1] == NULL) error (_("Incorrect usage, too few arguments in command")); @@ -2021,8 +1990,6 @@ set_substitute_path_command (char *args, int from_tty) add_substitute_path_rule (argv[0], argv[1]); forget_cached_source_info (); - - do_cleanups (cleanup); } diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c index dce8527..1f08865 100644 --- a/gdb/sparc-tdep.c +++ b/gdb/sparc-tdep.c @@ -1588,7 +1588,7 @@ sparc_execute_dwarf_cfa_vendor_op (struct gdbarch *gdbarch, gdb_byte op, uint64_t reg; int size = register_size (gdbarch, 0); - dwarf2_frame_state_alloc_regs (&fs->regs, 32); + fs->regs.alloc_regs (32); for (reg = 8; reg < 16; reg++) { fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_REG; @@ -1906,7 +1906,7 @@ sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } /* Target description may have changed. */ - info.tdep_info = tdesc_data; + info.tdesc_data = tdesc_data; tdesc_use_registers (gdbarch, tdesc, tdesc_data); } diff --git a/gdb/spu-multiarch.c b/gdb/spu-multiarch.c index abc4653..3da502c 100644 --- a/gdb/spu-multiarch.c +++ b/gdb/spu-multiarch.c @@ -107,7 +107,7 @@ spu_gdbarch (int spufs_fd) info.bfd_arch_info = bfd_lookup_arch (bfd_arch_spu, bfd_mach_spu); info.byte_order = BFD_ENDIAN_BIG; info.osabi = GDB_OSABI_LINUX; - info.tdep_info = &spufs_fd; + info.id = &spufs_fd; return gdbarch_find_by_info (info); } diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c index 1ab9a9c..ca1a3fc 100644 --- a/gdb/spu-tdep.c +++ b/gdb/spu-tdep.c @@ -2668,8 +2668,8 @@ spu_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) int id = -1; /* Which spufs ID was requested as address space? */ - if (info.tdep_info) - id = *(int *)info.tdep_info; + if (info.id) + id = *info.id; /* For objfile architectures of SPU solibs, decode the ID from the name. This assumes the filename convention employed by solib-spu.c. */ else if (info.abfd) diff --git a/gdb/stack.c b/gdb/stack.c index 7f8a51c..3e9dca2 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -1877,8 +1877,8 @@ backtrace_command (char *arg, int from_tty) char **argv; int i; - argv = gdb_buildargv (arg); - make_cleanup_freeargv (argv); + gdb_argv built_argv (arg); + argv = built_argv.get (); argc = 0; for (i = 0; argv[i]; i++) { diff --git a/gdb/symfile.c b/gdb/symfile.c index f936cf3..d600b61 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -859,7 +859,7 @@ static void read_symbols (struct objfile *objfile, symfile_add_flags add_flags) { (*objfile->sf->sym_read) (objfile, add_flags); - objfile->per_bfd->minsyms_read = 1; + objfile->per_bfd->minsyms_read = true; /* find_separate_debug_file_in_section should be called only if there is single binary with no existing separate debug info file. */ @@ -1639,7 +1639,6 @@ symbol_file_command (char *args, int from_tty) } else { - char **argv = gdb_buildargv (args); objfile_flags flags = OBJF_USERLOADED; symfile_add_flags add_flags = 0; struct cleanup *cleanups; @@ -1648,26 +1647,22 @@ symbol_file_command (char *args, int from_tty) if (from_tty) add_flags |= SYMFILE_VERBOSE; - cleanups = make_cleanup_freeargv (argv); - while (*argv != NULL) + gdb_argv built_argv (args); + for (char *arg : built_argv) { - if (strcmp (*argv, "-readnow") == 0) + if (strcmp (arg, "-readnow") == 0) flags |= OBJF_READNOW; - else if (**argv == '-') - error (_("unknown option `%s'"), *argv); + else if (*arg == '-') + error (_("unknown option `%s'"), arg); else { - symbol_file_add_main_1 (*argv, add_flags, flags); - name = *argv; + symbol_file_add_main_1 (arg, add_flags, flags); + name = arg; } - - argv++; } if (name == NULL) error (_("no symbol file name was specified")); - - do_cleanups (cleanups); } } @@ -1719,32 +1714,28 @@ symfile_bfd_open (const char *name) if (!is_target_filename (name)) { - char *expanded_name, *absolute_name; + char *absolute_name; - expanded_name = tilde_expand (name); /* Returns 1st new malloc'd copy. */ + gdb::unique_xmalloc_ptr<char> expanded_name (tilde_expand (name)); /* Look down path for it, allocate 2nd new malloc'd copy. */ desc = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, - expanded_name, O_RDONLY | O_BINARY, &absolute_name); + expanded_name.get (), O_RDONLY | O_BINARY, &absolute_name); #if defined(__GO32__) || defined(_WIN32) || defined (__CYGWIN__) if (desc < 0) { - char *exename = (char *) alloca (strlen (expanded_name) + 5); + char *exename = (char *) alloca (strlen (expanded_name.get ()) + 5); - strcat (strcpy (exename, expanded_name), ".exe"); + strcat (strcpy (exename, expanded_name.get ()), ".exe"); desc = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, exename, O_RDONLY | O_BINARY, &absolute_name); } #endif if (desc < 0) - { - make_cleanup (xfree, expanded_name); - perror_with_name (expanded_name); - } + perror_with_name (expanded_name.get ()); - xfree (expanded_name); make_cleanup (xfree, absolute_name); name = absolute_name; } @@ -2060,29 +2051,25 @@ static void print_transfer_performance (struct ui_file *stream, void generic_load (const char *args, int from_tty) { - char *filename; - struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0); + struct cleanup *old_cleanups; struct load_section_data cbdata; struct load_progress_data total_progress; struct ui_out *uiout = current_uiout; CORE_ADDR entry; - char **argv; memset (&cbdata, 0, sizeof (cbdata)); memset (&total_progress, 0, sizeof (total_progress)); cbdata.progress_data = &total_progress; - make_cleanup (clear_memory_write_data, &cbdata.requests); + old_cleanups = make_cleanup (clear_memory_write_data, &cbdata.requests); if (args == NULL) error_no_arg (_("file to load")); - argv = gdb_buildargv (args); - make_cleanup_freeargv (argv); + gdb_argv argv (args); - filename = tilde_expand (argv[0]); - make_cleanup (xfree, filename); + gdb::unique_xmalloc_ptr<char> filename (tilde_expand (argv[0])); if (argv[1] != NULL) { @@ -2100,16 +2087,13 @@ generic_load (const char *args, int from_tty) } /* Open the file for loading. */ - gdb_bfd_ref_ptr loadfile_bfd (gdb_bfd_open (filename, gnutarget, -1)); + gdb_bfd_ref_ptr loadfile_bfd (gdb_bfd_open (filename.get (), gnutarget, -1)); if (loadfile_bfd == NULL) - { - perror_with_name (filename); - return; - } + perror_with_name (filename.get ()); if (!bfd_check_format (loadfile_bfd.get (), bfd_object)) { - error (_("\"%s\" is not an object file: %s"), filename, + error (_("\"%s\" is not an object file: %s"), filename.get (), bfd_errmsg (bfd_get_error ())); } @@ -2219,15 +2203,12 @@ static void add_symbol_file_command (char *args, int from_tty) { struct gdbarch *gdbarch = get_current_arch (); - char *filename = NULL; + gdb::unique_xmalloc_ptr<char> filename; char *arg; - int section_index = 0; int argcnt = 0; int sec_num = 0; - int i; int expecting_sec_name = 0; int expecting_sec_addr = 0; - char **argv; struct objfile *objf; objfile_flags flags = OBJF_USERLOADED | OBJF_SHARED; symfile_add_flags add_flags = 0; @@ -2242,20 +2223,15 @@ add_symbol_file_command (char *args, int from_tty) }; struct section_addr_info *section_addrs; - struct sect_opt *sect_opts = NULL; - size_t num_sect_opts = 0; + std::vector<sect_opt> sect_opts; struct cleanup *my_cleanups = make_cleanup (null_cleanup, NULL); - num_sect_opts = 16; - sect_opts = XNEWVEC (struct sect_opt, num_sect_opts); - dont_repeat (); if (args == NULL) error (_("add-symbol-file takes a file name and an address")); - argv = gdb_buildargv (args); - make_cleanup_freeargv (argv); + gdb_argv argv (args); for (arg = argv[0], argcnt = 0; arg != NULL; arg = argv[++argcnt]) { @@ -2263,23 +2239,14 @@ add_symbol_file_command (char *args, int from_tty) if (argcnt == 0) { /* The first argument is the file name. */ - filename = tilde_expand (arg); - make_cleanup (xfree, filename); + filename.reset (tilde_expand (arg)); } else if (argcnt == 1) { /* The second argument is always the text address at which to load the program. */ - sect_opts[section_index].name = ".text"; - sect_opts[section_index].value = arg; - if (++section_index >= num_sect_opts) - { - num_sect_opts *= 2; - sect_opts = ((struct sect_opt *) - xrealloc (sect_opts, - num_sect_opts - * sizeof (struct sect_opt))); - } + sect_opt sect = { ".text", arg }; + sect_opts.push_back (sect); } else { @@ -2287,21 +2254,14 @@ add_symbol_file_command (char *args, int from_tty) to an option. */ if (expecting_sec_name) { - sect_opts[section_index].name = arg; + sect_opt sect = { arg, NULL }; + sect_opts.push_back (sect); expecting_sec_name = 0; } else if (expecting_sec_addr) { - sect_opts[section_index].value = arg; + sect_opts.back ().value = arg; expecting_sec_addr = 0; - if (++section_index >= num_sect_opts) - { - num_sect_opts *= 2; - sect_opts = ((struct sect_opt *) - xrealloc (sect_opts, - num_sect_opts - * sizeof (struct sect_opt))); - } } else if (strcmp (arg, "-readnow") == 0) flags |= OBJF_READNOW; @@ -2320,8 +2280,9 @@ add_symbol_file_command (char *args, int from_tty) filename, and the second is the address where this file has been loaded. Abort now if this address hasn't been provided by the user. */ - if (section_index < 1) - error (_("The address where %s has been loaded is missing"), filename); + if (sect_opts.empty ()) + error (_("The address where %s has been loaded is missing"), + filename.get ()); /* Print the prompt for the query below. And save the arguments into a sect_addr_info structure to be passed around to other @@ -2329,14 +2290,15 @@ add_symbol_file_command (char *args, int from_tty) statements because hex_string returns a local static string. */ - printf_unfiltered (_("add symbol table from file \"%s\" at\n"), filename); - section_addrs = alloc_section_addr_info (section_index); + printf_unfiltered (_("add symbol table from file \"%s\" at\n"), + filename.get ()); + section_addrs = alloc_section_addr_info (sect_opts.size ()); make_cleanup (xfree, section_addrs); - for (i = 0; i < section_index; i++) + for (sect_opt § : sect_opts) { CORE_ADDR addr; - const char *val = sect_opts[i].value; - const char *sec = sect_opts[i].name; + const char *val = sect.value; + const char *sec = sect.name; addr = parse_and_eval_address (val); @@ -2359,7 +2321,7 @@ add_symbol_file_command (char *args, int from_tty) if (from_tty && (!query ("%s", ""))) error (_("Not confirmed.")); - objf = symbol_file_add (filename, add_flags, section_addrs, flags); + objf = symbol_file_add (filename.get (), add_flags, section_addrs, flags); add_target_sections_of_objfile (objf); @@ -2375,9 +2337,7 @@ add_symbol_file_command (char *args, int from_tty) static void remove_symbol_file_command (char *args, int from_tty) { - char **argv; struct objfile *objf = NULL; - struct cleanup *my_cleanups; struct program_space *pspace = current_program_space; dont_repeat (); @@ -2385,9 +2345,7 @@ remove_symbol_file_command (char *args, int from_tty) if (args == NULL) error (_("remove-symbol-file: no symbol file provided")); - my_cleanups = make_cleanup (null_cleanup, NULL); - - argv = gdb_buildargv (args); + gdb_argv argv (args); if (strcmp (argv[0], "-a") == 0) { @@ -2413,20 +2371,18 @@ remove_symbol_file_command (char *args, int from_tty) else if (argv[0] != NULL) { /* Interpret the current argument as a file name. */ - char *filename; if (argv[1] != NULL) error (_("Junk after %s"), argv[0]); - filename = tilde_expand (argv[0]); - make_cleanup (xfree, filename); + gdb::unique_xmalloc_ptr<char> filename (tilde_expand (argv[0])); ALL_OBJFILES (objf) { if ((objf->flags & OBJF_USERLOADED) != 0 && (objf->flags & OBJF_SHARED) != 0 && objf->pspace == pspace - && filename_cmp (filename, objfile_name (objf)) == 0) + && filename_cmp (filename.get (), objfile_name (objf)) == 0) break; } } @@ -2441,8 +2397,6 @@ remove_symbol_file_command (char *args, int from_tty) free_objfile (objf); clear_symtab_users (0); - - do_cleanups (my_cleanups); } /* Re-read symbols if a symbol-file has changed. */ @@ -2587,6 +2541,9 @@ reread_symbols (void) /* Free the obstacks for non-reusable objfiles. */ psymbol_bcache_free (objfile->psymbol_cache); objfile->psymbol_cache = psymbol_bcache_init (); + + /* NB: after this call to obstack_free, objfiles_changed + will need to be called (see discussion below). */ obstack_free (&objfile->objfile_obstack, 0); objfile->sections = NULL; objfile->compunit_symtabs = NULL; @@ -2639,6 +2596,23 @@ reread_symbols (void) clear_complaints (&symfile_complaints, 1, 1); objfile->flags &= ~OBJF_PSYMTABS_READ; + + /* We are about to read new symbols and potentially also + DWARF information. Some targets may want to pass addresses + read from DWARF DIE's through an adjustment function before + saving them, like MIPS, which may call into + "find_pc_section". When called, that function will make + use of per-objfile program space data. + + Since we discarded our section information above, we have + dangling pointers in the per-objfile program space data + structure. Force GDB to update the section mapping + information by letting it know the objfile has changed, + making the dangling pointers point to correct data + again. */ + + objfiles_changed (); + read_symbols (objfile, 0); if (!objfile_has_symbols (objfile)) @@ -2671,9 +2645,6 @@ reread_symbols (void) if (!new_objfiles.empty ()) { - /* Notify objfiles that we've modified objfile sections. */ - objfiles_changed (); - clear_symtab_users (0); /* clear_objfile_data for each objfile was called before freeing it and diff --git a/gdb/symmisc.c b/gdb/symmisc.c index 32a5331..c85f0b7 100644 --- a/gdb/symmisc.c +++ b/gdb/symmisc.c @@ -407,16 +407,13 @@ dump_symtab (struct symtab *symtab, struct ui_file *outfile) static void maintenance_print_symbols (char *args, int from_tty) { - char **argv; struct ui_file *outfile = gdb_stdout; - struct cleanup *cleanups; char *address_arg = NULL, *source_arg = NULL, *objfile_arg = NULL; int i, outfile_idx; dont_repeat (); - argv = gdb_buildargv (args); - cleanups = make_cleanup_freeargv (argv); + gdb_argv argv (args); for (i = 0; argv != NULL && argv[i] != NULL; ++i) { @@ -461,14 +458,12 @@ maintenance_print_symbols (char *args, int from_tty) if (argv != NULL && argv[outfile_idx] != NULL) { - char *outfile_name; - if (argv[outfile_idx + 1] != NULL) error (_("Junk at end of command")); - outfile_name = tilde_expand (argv[outfile_idx]); - make_cleanup (xfree, outfile_name); - if (!arg_outfile.open (outfile_name, FOPEN_WT)) - perror_with_name (outfile_name); + gdb::unique_xmalloc_ptr<char> outfile_name + (tilde_expand (argv[outfile_idx])); + if (!arg_outfile.open (outfile_name.get (), FOPEN_WT)) + perror_with_name (outfile_name.get ()); outfile = &arg_outfile; } @@ -520,8 +515,6 @@ maintenance_print_symbols (char *args, int from_tty) if (source_arg != NULL && !found) error (_("No symtab for source file: %s"), source_arg); } - - do_cleanups (cleanups); } /* Print symbol ARGS->SYMBOL on ARGS->OUTFILE. ARGS->DEPTH says how @@ -709,17 +702,14 @@ print_symbol (void *args) static void maintenance_print_msymbols (char *args, int from_tty) { - char **argv; struct ui_file *outfile = gdb_stdout; - struct cleanup *cleanups; char *objfile_arg = NULL; struct objfile *objfile; int i, outfile_idx; dont_repeat (); - argv = gdb_buildargv (args); - cleanups = make_cleanup_freeargv (argv); + gdb_argv argv (args); for (i = 0; argv != NULL && argv[i] != NULL; ++i) { @@ -749,14 +739,12 @@ maintenance_print_msymbols (char *args, int from_tty) if (argv != NULL && argv[outfile_idx] != NULL) { - char *outfile_name; - if (argv[outfile_idx + 1] != NULL) error (_("Junk at end of command")); - outfile_name = tilde_expand (argv[outfile_idx]); - make_cleanup (xfree, outfile_name); - if (!arg_outfile.open (outfile_name, FOPEN_WT)) - perror_with_name (outfile_name); + gdb::unique_xmalloc_ptr<char> outfile_name + (tilde_expand (argv[outfile_idx])); + if (!arg_outfile.open (outfile_name.get (), FOPEN_WT)) + perror_with_name (outfile_name.get ()); outfile = &arg_outfile; } @@ -767,8 +755,6 @@ maintenance_print_msymbols (char *args, int from_tty) || compare_filenames_for_search (objfile_name (objfile), objfile_arg)) dump_msymbols (objfile, outfile); } - - do_cleanups (cleanups); } static void @@ -944,14 +930,11 @@ maintenance_expand_symtabs (char *args, int from_tty) { struct program_space *pspace; struct objfile *objfile; - struct cleanup *cleanups; - char **argv; char *regexp = NULL; /* We use buildargv here so that we handle spaces in the regexp in a way that allows adding more arguments later. */ - argv = gdb_buildargv (args); - cleanups = make_cleanup_freeargv (argv); + gdb_argv argv (args); if (argv != NULL) { @@ -988,8 +971,6 @@ maintenance_expand_symtabs (char *args, int from_tty) ALL_DOMAIN); } } - - do_cleanups (cleanups); } diff --git a/gdb/symtab.c b/gdb/symtab.c index c1fd5e6..11dce2c 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -63,6 +63,8 @@ #include "completer.h" #include "progspace-and-thread.h" #include "common/gdb_optional.h" +#include "filename-seen-cache.h" +#include "arch-utils.h" /* Forward declarations for local functions. */ @@ -2625,7 +2627,8 @@ symbol_matches_domain (enum language symbol_language, Similarly, any Ada type declaration implicitly defines a typedef. */ if (symbol_language == language_cplus || symbol_language == language_d - || symbol_language == language_ada) + || symbol_language == language_ada + || symbol_language == language_rust) { if ((domain == VAR_DOMAIN || domain == STRUCT_DOMAIN) && symbol_domain == STRUCT_DOMAIN) @@ -3627,7 +3630,7 @@ skip_prologue_sal (struct symtab_and_line *sal) if (gdbarch_skip_entrypoint_p (gdbarch)) pc = gdbarch_skip_entrypoint (gdbarch, pc); if (skip) - pc = gdbarch_skip_prologue (gdbarch, pc); + pc = gdbarch_skip_prologue_noexcept (gdbarch, pc); /* For overlays, map pc back into its mapped VMA range. */ pc = overlay_mapped_address (pc, section); @@ -3839,9 +3842,9 @@ static const char * operator_chars (const char *p, const char **end) { *end = ""; - if (!startswith (p, "operator")) + if (!startswith (p, CP_OPERATOR_STR)) return *end; - p += 8; + p += CP_OPERATOR_LEN; /* Don't get faked out by `operator' being part of a longer identifier. */ @@ -3969,74 +3972,6 @@ operator_chars (const char *p, const char **end) } -/* Cache to watch for file names already seen by filename_seen. */ - -struct filename_seen_cache -{ - /* Table of files seen so far. */ - htab_t tab; - /* Initial size of the table. It automagically grows from here. */ -#define INITIAL_FILENAME_SEEN_CACHE_SIZE 100 -}; - -/* filename_seen_cache constructor. */ - -static struct filename_seen_cache * -create_filename_seen_cache (void) -{ - struct filename_seen_cache *cache = XNEW (struct filename_seen_cache); - - cache->tab = htab_create_alloc (INITIAL_FILENAME_SEEN_CACHE_SIZE, - filename_hash, filename_eq, - NULL, xcalloc, xfree); - - return cache; -} - -/* Empty the cache, but do not delete it. */ - -static void -clear_filename_seen_cache (struct filename_seen_cache *cache) -{ - htab_empty (cache->tab); -} - -/* filename_seen_cache destructor. - This takes a void * argument as it is generally used as a cleanup. */ - -static void -delete_filename_seen_cache (void *ptr) -{ - struct filename_seen_cache *cache = (struct filename_seen_cache *) ptr; - - htab_delete (cache->tab); - xfree (cache); -} - -/* If FILE is not already in the table of files in CACHE, return zero; - otherwise return non-zero. Optionally add FILE to the table if ADD - is non-zero. - - NOTE: We don't manage space for FILE, we assume FILE lives as long - as the caller needs. */ - -static int -filename_seen (struct filename_seen_cache *cache, const char *file, int add) -{ - void **slot; - - /* Is FILE in tab? */ - slot = htab_find_slot (cache->tab, file, add ? INSERT : NO_INSERT); - if (*slot != NULL) - return 1; - - /* No; maybe add it to tab. */ - if (add) - *slot = (char *) file; - - return 0; -} - /* Data structure to maintain printing state for output_source_filename. */ struct output_source_filename_data @@ -4066,7 +4001,7 @@ output_source_filename (const char *name, symtabs; it doesn't hurt to check. */ /* Was NAME already seen? */ - if (filename_seen (data->filename_seen_cache, name, 1)) + if (data->filename_seen_cache->seen (name)) { /* Yes; don't print it again. */ return; @@ -4098,16 +4033,15 @@ sources_info (char *ignore, int from_tty) struct symtab *s; struct objfile *objfile; struct output_source_filename_data data; - struct cleanup *cleanups; if (!have_full_symbols () && !have_partial_symbols ()) { error (_("No symbol table is loaded. Use the \"file\" command.")); } - data.filename_seen_cache = create_filename_seen_cache (); - cleanups = make_cleanup (delete_filename_seen_cache, - data.filename_seen_cache); + filename_seen_cache filenames_seen; + + data.filename_seen_cache = &filenames_seen; printf_filtered ("Source files for which symbols have been read in:\n\n"); @@ -4123,13 +4057,11 @@ sources_info (char *ignore, int from_tty) printf_filtered ("Source files for which symbols " "will be read in on demand:\n\n"); - clear_filename_seen_cache (data.filename_seen_cache); + filenames_seen.clear (); data.first = 1; map_symbol_filenames (output_partial_symbol_filename, &data, 1 /*need_fullname*/); printf_filtered ("\n"); - - do_cleanups (cleanups); } /* Compare FILE against all the NFILES entries of FILES. If BASENAMES is @@ -4818,54 +4750,13 @@ compare_symbol_name (const char *name, const char *sym_text, int sym_text_len) return 1; } -/* Free any memory associated with a completion list. */ - -static void -free_completion_list (VEC (char_ptr) **list_ptr) -{ - int i; - char *p; - - for (i = 0; VEC_iterate (char_ptr, *list_ptr, i, p); ++i) - xfree (p); - VEC_free (char_ptr, *list_ptr); -} - -/* Callback for make_cleanup. */ - -static void -do_free_completion_list (void *list) -{ - free_completion_list ((VEC (char_ptr) **) list); -} - -/* Helper routine for make_symbol_completion_list. */ - -static VEC (char_ptr) *return_val; - -#define COMPLETION_LIST_ADD_SYMBOL(symbol, sym_text, len, text, word) \ - completion_list_add_name \ - (SYMBOL_NATURAL_NAME (symbol), (sym_text), (len), (text), (word)) - -#define MCOMPLETION_LIST_ADD_SYMBOL(symbol, sym_text, len, text, word) \ - completion_list_add_name \ - (MSYMBOL_NATURAL_NAME (symbol), (sym_text), (len), (text), (word)) - -/* Tracker for how many unique completions have been generated. Used - to terminate completion list generation early if the list has grown - to a size so large as to be useless. This helps avoid GDB seeming - to lock up in the event the user requests to complete on something - vague that necessitates the time consuming expansion of many symbol - tables. */ - -static completion_tracker_t completion_tracker; - /* Test to see if the symbol specified by SYMNAME (which is already demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN characters. If so, add it to the current completion list. */ static void -completion_list_add_name (const char *symname, +completion_list_add_name (completion_tracker &tracker, + const char *symname, const char *sym_text, int sym_text_len, const char *text, const char *word) { @@ -4878,7 +4769,6 @@ completion_list_add_name (const char *symname, { char *newobj; - enum maybe_add_completion_enum add_status; if (word == sym_text) { @@ -4900,31 +4790,42 @@ completion_list_add_name (const char *symname, strcat (newobj, symname); } - add_status = maybe_add_completion (completion_tracker, newobj); + gdb::unique_xmalloc_ptr<char> completion (newobj); - switch (add_status) - { - case MAYBE_ADD_COMPLETION_OK: - VEC_safe_push (char_ptr, return_val, newobj); - break; - case MAYBE_ADD_COMPLETION_OK_MAX_REACHED: - VEC_safe_push (char_ptr, return_val, newobj); - throw_max_completions_reached_error (); - case MAYBE_ADD_COMPLETION_MAX_REACHED: - xfree (newobj); - throw_max_completions_reached_error (); - case MAYBE_ADD_COMPLETION_DUPLICATE: - xfree (newobj); - break; - } + tracker.add_completion (std::move (completion)); } } +/* completion_list_add_name wrapper for struct symbol. */ + +static void +completion_list_add_symbol (completion_tracker &tracker, + symbol *sym, + const char *sym_text, int sym_text_len, + const char *text, const char *word) +{ + completion_list_add_name (tracker, SYMBOL_NATURAL_NAME (sym), + sym_text, sym_text_len, text, word); +} + +/* completion_list_add_name wrapper for struct minimal_symbol. */ + +static void +completion_list_add_msymbol (completion_tracker &tracker, + minimal_symbol *sym, + const char *sym_text, int sym_text_len, + const char *text, const char *word) +{ + completion_list_add_name (tracker, MSYMBOL_NATURAL_NAME (sym), + sym_text, sym_text_len, text, word); +} + /* ObjC: In case we are completing on a selector, look as the msymbol again and feed all the selectors into the mill. */ static void -completion_list_objc_symbol (struct minimal_symbol *msymbol, +completion_list_objc_symbol (completion_tracker &tracker, + struct minimal_symbol *msymbol, const char *sym_text, int sym_text_len, const char *text, const char *word) { @@ -4942,7 +4843,8 @@ completion_list_objc_symbol (struct minimal_symbol *msymbol, if (sym_text[0] == '[') /* Complete on shortened method method. */ - completion_list_add_name (method + 1, sym_text, sym_text_len, text, word); + completion_list_add_name (tracker, method + 1, + sym_text, sym_text_len, text, word); while ((strlen (method) + 1) >= tmplen) { @@ -4963,9 +4865,11 @@ completion_list_objc_symbol (struct minimal_symbol *msymbol, memcpy (tmp, method, (category - method)); tmp[category - method] = ' '; memcpy (tmp + (category - method) + 1, selector, strlen (selector) + 1); - completion_list_add_name (tmp, sym_text, sym_text_len, text, word); + completion_list_add_name (tracker, tmp, + sym_text, sym_text_len, text, word); if (sym_text[0] == '[') - completion_list_add_name (tmp + 1, sym_text, sym_text_len, text, word); + completion_list_add_name (tracker, tmp + 1, + sym_text, sym_text_len, text, word); } if (selector != NULL) @@ -4976,7 +4880,8 @@ completion_list_objc_symbol (struct minimal_symbol *msymbol, if (tmp2 != NULL) *tmp2 = '\0'; - completion_list_add_name (tmp, sym_text, sym_text_len, text, word); + completion_list_add_name (tracker, tmp, + sym_text, sym_text_len, text, word); } } @@ -5027,9 +4932,10 @@ language_search_unquoted_string (const char *text, const char *p) } static void -completion_list_add_fields (struct symbol *sym, const char *sym_text, - int sym_text_len, const char *text, - const char *word) +completion_list_add_fields (completion_tracker &tracker, + struct symbol *sym, + const char *sym_text, int sym_text_len, + const char *text, const char *word) { if (SYMBOL_CLASS (sym) == LOC_TYPEDEF) { @@ -5040,7 +4946,7 @@ completion_list_add_fields (struct symbol *sym, const char *sym_text, if (c == TYPE_CODE_UNION || c == TYPE_CODE_STRUCT) for (j = TYPE_N_BASECLASSES (t); j < TYPE_NFIELDS (t); j++) if (TYPE_FIELD_NAME (t, j)) - completion_list_add_name (TYPE_FIELD_NAME (t, j), + completion_list_add_name (tracker, TYPE_FIELD_NAME (t, j), sym_text, sym_text_len, text, word); } } @@ -5049,6 +4955,7 @@ completion_list_add_fields (struct symbol *sym, const char *sym_text, static void add_symtab_completions (struct compunit_symtab *cust, + completion_tracker &tracker, const char *sym_text, int sym_text_len, const char *text, const char *word, enum type_code code) @@ -5070,18 +4977,19 @@ add_symtab_completions (struct compunit_symtab *cust, if (code == TYPE_CODE_UNDEF || (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN && TYPE_CODE (SYMBOL_TYPE (sym)) == code)) - COMPLETION_LIST_ADD_SYMBOL (sym, + completion_list_add_symbol (tracker, sym, sym_text, sym_text_len, text, word); } } } -static void -default_make_symbol_completion_list_break_on_1 (const char *text, - const char *word, - const char *break_on, - enum type_code code) +void +default_collect_symbol_completion_matches_break_on + (completion_tracker &tracker, + complete_symbol_mode mode, + const char *text, const char *word, + const char *break_on, enum type_code code) { /* Problem: All of the symbols have to be copied because readline frees them. I'm not going to worry about this; hopefully there @@ -5098,9 +5006,11 @@ default_make_symbol_completion_list_break_on_1 (const char *text, const char *sym_text; /* Length of sym_text. */ int sym_text_len; - struct cleanup *cleanups; /* Now look for the symbol we are supposed to complete on. */ + if (mode == complete_symbol_mode::LINESPEC) + sym_text = text; + else { const char *p; char quote_found; @@ -5168,9 +5078,6 @@ default_make_symbol_completion_list_break_on_1 (const char *text, } gdb_assert (sym_text[sym_text_len] == '\0' || sym_text[sym_text_len] == '('); - completion_tracker = new_completion_tracker (); - cleanups = make_cleanup_free_completion_tracker (&completion_tracker); - /* At this point scan through the misc symbol vectors and add each symbol you find to the list. Eventually we want to ignore anything that isn't a text symbol (everything else will be @@ -5181,18 +5088,21 @@ default_make_symbol_completion_list_break_on_1 (const char *text, ALL_MSYMBOLS (objfile, msymbol) { QUIT; - MCOMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text, - word); - completion_list_objc_symbol (msymbol, sym_text, sym_text_len, text, - word); + completion_list_add_msymbol (tracker, + msymbol, sym_text, sym_text_len, + text, word); + + completion_list_objc_symbol (tracker, + msymbol, sym_text, sym_text_len, + text, word); } } /* Add completions for all currently loaded symbol tables. */ ALL_COMPUNITS (objfile, cust) - add_symtab_completions (cust, sym_text, sym_text_len, text, word, - code); + add_symtab_completions (cust, tracker, + sym_text, sym_text_len, text, word, code); /* Look through the partial symtabs for all symbols which begin by matching SYM_TEXT. Expand all CUs that you find to the list. */ @@ -5206,6 +5116,7 @@ default_make_symbol_completion_list_break_on_1 (const char *text, [&] (compunit_symtab *symtab) /* expansion notify */ { add_symtab_completions (symtab, + tracker, sym_text, sym_text_len, text, word, code); }, @@ -5228,14 +5139,17 @@ default_make_symbol_completion_list_break_on_1 (const char *text, { if (code == TYPE_CODE_UNDEF) { - COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, + completion_list_add_symbol (tracker, sym, + sym_text, sym_text_len, text, word); - completion_list_add_fields (sym, sym_text, sym_text_len, text, + completion_list_add_fields (tracker, sym, + sym_text, sym_text_len, text, word); } else if (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN && TYPE_CODE (SYMBOL_TYPE (sym)) == code) - COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, + completion_list_add_symbol (tracker, sym, + sym_text, sym_text_len, text, word); } @@ -5253,11 +5167,13 @@ default_make_symbol_completion_list_break_on_1 (const char *text, { if (surrounding_static_block != NULL) ALL_BLOCK_SYMBOLS (surrounding_static_block, iter, sym) - completion_list_add_fields (sym, sym_text, sym_text_len, text, word); + completion_list_add_fields (tracker, sym, + sym_text, sym_text_len, text, word); if (surrounding_global_block != NULL) ALL_BLOCK_SYMBOLS (surrounding_global_block, iter, sym) - completion_list_add_fields (sym, sym_text, sym_text_len, text, word); + completion_list_add_fields (tracker, sym, + sym_text, sym_text_len, text, word); } /* Skip macros if we are completing a struct tag -- arguable but @@ -5273,7 +5189,7 @@ default_make_symbol_completion_list_break_on_1 (const char *text, macro_source_file *, int) { - completion_list_add_name (macro_name, + completion_list_add_name (tracker, macro_name, sym_text, sym_text_len, text, word); }; @@ -5296,86 +5212,58 @@ default_make_symbol_completion_list_break_on_1 (const char *text, /* User-defined macros are always visible. */ macro_for_each (macro_user_macros, add_macro_name); } - - do_cleanups (cleanups); } -VEC (char_ptr) * -default_make_symbol_completion_list_break_on (const char *text, - const char *word, - const char *break_on, - enum type_code code) -{ - struct cleanup *back_to; - - return_val = NULL; - back_to = make_cleanup (do_free_completion_list, &return_val); - - TRY - { - default_make_symbol_completion_list_break_on_1 (text, word, - break_on, code); - } - CATCH (except, RETURN_MASK_ERROR) - { - if (except.error != MAX_COMPLETIONS_REACHED_ERROR) - throw_exception (except); - } - END_CATCH - - discard_cleanups (back_to); - return return_val; -} - -VEC (char_ptr) * -default_make_symbol_completion_list (const char *text, const char *word, - enum type_code code) +void +default_collect_symbol_completion_matches (completion_tracker &tracker, + complete_symbol_mode mode, + const char *text, const char *word, + enum type_code code) { - return default_make_symbol_completion_list_break_on (text, word, "", code); + return default_collect_symbol_completion_matches_break_on (tracker, mode, + text, word, "", + code); } -/* Return a vector of all symbols (regardless of class) which begin by - matching TEXT. If the answer is no symbols, then the return value - is NULL. */ +/* Collect all symbols (regardless of class) which begin by matching + TEXT. */ -VEC (char_ptr) * -make_symbol_completion_list (const char *text, const char *word) +void +collect_symbol_completion_matches (completion_tracker &tracker, + complete_symbol_mode mode, + const char *text, const char *word) { - return current_language->la_make_symbol_completion_list (text, word, - TYPE_CODE_UNDEF); + current_language->la_collect_symbol_completion_matches (tracker, mode, + text, word, + TYPE_CODE_UNDEF); } -/* Like make_symbol_completion_list, but only return STRUCT_DOMAIN - symbols whose type code is CODE. */ +/* Like collect_symbol_completion_matches, but only collect + STRUCT_DOMAIN symbols whose type code is CODE. */ -VEC (char_ptr) * -make_symbol_completion_type (const char *text, const char *word, - enum type_code code) +void +collect_symbol_completion_matches_type (completion_tracker &tracker, + const char *text, const char *word, + enum type_code code) { + complete_symbol_mode mode = complete_symbol_mode::EXPRESSION; + gdb_assert (code == TYPE_CODE_UNION || code == TYPE_CODE_STRUCT || code == TYPE_CODE_ENUM); - return current_language->la_make_symbol_completion_list (text, word, code); + current_language->la_collect_symbol_completion_matches (tracker, mode, + text, word, code); } -/* Like make_symbol_completion_list, but suitable for use as a - completion function. */ +/* Like collect_symbol_completion_matches, but collects a list of + symbols defined in all source files named SRCFILE. */ -VEC (char_ptr) * -make_symbol_completion_list_fn (struct cmd_list_element *ignore, - const char *text, const char *word) -{ - return make_symbol_completion_list (text, word); -} - -/* Like make_symbol_completion_list, but returns a list of symbols - defined in a source file FILE. */ - -static VEC (char_ptr) * -make_file_symbol_completion_list_1 (const char *text, const char *word, - const char *srcfile) +void +collect_file_symbol_completion_matches (completion_tracker &tracker, + complete_symbol_mode mode, + const char *text, const char *word, + const char *srcfile) { - struct symtab *s; /* The symbol we are completing on. Points in same buffer as text. */ const char *sym_text; /* Length of sym_text. */ @@ -5383,6 +5271,9 @@ make_file_symbol_completion_list_1 (const char *text, const char *word, /* Now look for the symbol we are supposed to complete on. FIXME: This should be language-specific. */ + if (mode == complete_symbol_mode::LINESPEC) + sym_text = text; + else { const char *p; char quote_found; @@ -5415,7 +5306,7 @@ make_file_symbol_completion_list_1 (const char *text, const char *word, /* A double-quoted string is never a symbol, nor does it make sense to complete it any other way. */ { - return NULL; + return; } else { @@ -5426,60 +5317,16 @@ make_file_symbol_completion_list_1 (const char *text, const char *word, sym_text_len = strlen (sym_text); - /* Find the symtab for SRCFILE (this loads it if it was not yet read - in). */ - s = lookup_symtab (srcfile); - if (s == NULL) - { - /* Maybe they typed the file with leading directories, while the - symbol tables record only its basename. */ - const char *tail = lbasename (srcfile); - - if (tail > srcfile) - s = lookup_symtab (tail); - } - - /* If we have no symtab for that file, return an empty list. */ - if (s == NULL) - return (return_val); - - /* Go through this symtab and check the externs and statics for - symbols which match. */ - add_symtab_completions (SYMTAB_COMPUNIT (s), - sym_text, sym_text_len, - text, word, TYPE_CODE_UNDEF); - - return (return_val); -} - -/* Wrapper around make_file_symbol_completion_list_1 - to handle MAX_COMPLETIONS_REACHED_ERROR. */ - -VEC (char_ptr) * -make_file_symbol_completion_list (const char *text, const char *word, - const char *srcfile) -{ - struct cleanup *back_to, *cleanups; - - completion_tracker = new_completion_tracker (); - cleanups = make_cleanup_free_completion_tracker (&completion_tracker); - return_val = NULL; - back_to = make_cleanup (do_free_completion_list, &return_val); - - TRY - { - make_file_symbol_completion_list_1 (text, word, srcfile); - } - CATCH (except, RETURN_MASK_ERROR) + /* Go through symtabs for SRCFILE and check the externs and statics + for symbols which match. */ + iterate_over_symtabs (srcfile, [&] (symtab *s) { - if (except.error != MAX_COMPLETIONS_REACHED_ERROR) - throw_exception (except); - } - END_CATCH - - discard_cleanups (back_to); - do_cleanups (cleanups); - return return_val; + add_symtab_completions (SYMTAB_COMPUNIT (s), + tracker, + sym_text, sym_text_len, + text, word, TYPE_CODE_UNDEF); + return false; + }); } /* A helper function for make_source_files_completion_list. It adds @@ -5488,7 +5335,7 @@ make_file_symbol_completion_list (const char *text, const char *word, static void add_filename_to_list (const char *fname, const char *text, const char *word, - VEC (char_ptr) **list) + completion_list *list) { char *newobj; size_t fnlen = strlen (fname); @@ -5513,7 +5360,7 @@ add_filename_to_list (const char *fname, const char *text, const char *word, newobj[text - word] = '\0'; strcat (newobj, fname); } - VEC_safe_push (char_ptr, *list, newobj); + list->emplace_back (newobj); } static int @@ -5541,7 +5388,7 @@ struct add_partial_filename_data const char *text; const char *word; int text_len; - VEC (char_ptr) **list; + completion_list *list; }; /* A callback for map_partial_symbol_filenames. */ @@ -5555,7 +5402,7 @@ maybe_add_partial_symtab_filename (const char *filename, const char *fullname, if (not_interesting_fname (filename)) return; - if (!filename_seen (data->filename_seen_cache, filename, 1) + if (!data->filename_seen_cache->seen (filename) && filename_ncmp (filename, data->text, data->text_len) == 0) { /* This file matches for a completion; add it to the @@ -5567,44 +5414,38 @@ maybe_add_partial_symtab_filename (const char *filename, const char *fullname, const char *base_name = lbasename (filename); if (base_name != filename - && !filename_seen (data->filename_seen_cache, base_name, 1) + && !data->filename_seen_cache->seen (base_name) && filename_ncmp (base_name, data->text, data->text_len) == 0) add_filename_to_list (base_name, data->text, data->word, data->list); } } -/* Return a vector of all source files whose names begin with matching +/* Return a list of all source files whose names begin with matching TEXT. The file names are looked up in the symbol tables of this - program. If the answer is no matchess, then the return value is - NULL. */ + program. */ -VEC (char_ptr) * +completion_list make_source_files_completion_list (const char *text, const char *word) { struct compunit_symtab *cu; struct symtab *s; struct objfile *objfile; size_t text_len = strlen (text); - VEC (char_ptr) *list = NULL; + completion_list list; const char *base_name; struct add_partial_filename_data datum; - struct filename_seen_cache *filename_seen_cache; - struct cleanup *back_to, *cache_cleanup; + struct cleanup *back_to; if (!have_full_symbols () && !have_partial_symbols ()) return list; - back_to = make_cleanup (do_free_completion_list, &list); - - filename_seen_cache = create_filename_seen_cache (); - cache_cleanup = make_cleanup (delete_filename_seen_cache, - filename_seen_cache); + filename_seen_cache filenames_seen; ALL_FILETABS (objfile, cu, s) { if (not_interesting_fname (s->filename)) continue; - if (!filename_seen (filename_seen_cache, s->filename, 1) + if (!filenames_seen.seen (s->filename) && filename_ncmp (s->filename, text, text_len) == 0) { /* This file matches for a completion; add it to the current @@ -5619,13 +5460,13 @@ make_source_files_completion_list (const char *text, const char *word) command do when they parse file names. */ base_name = lbasename (s->filename); if (base_name != s->filename - && !filename_seen (filename_seen_cache, base_name, 1) + && !filenames_seen.seen (base_name) && filename_ncmp (base_name, text, text_len) == 0) add_filename_to_list (base_name, text, word, &list); } } - datum.filename_seen_cache = filename_seen_cache; + datum.filename_seen_cache = &filenames_seen; datum.text = text; datum.word = word; datum.text_len = text_len; @@ -5633,9 +5474,6 @@ make_source_files_completion_list (const char *text, const char *word) map_symbol_filenames (maybe_add_partial_symtab_filename, &datum, 0 /*need_fullname*/); - do_cleanups (cache_cleanup); - discard_cleanups (back_to); - return list; } diff --git a/gdb/symtab.h b/gdb/symtab.h index 78a0cfc..8b0da8a 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -25,6 +25,7 @@ #include "gdbtypes.h" #include "common/enum-flags.h" #include "common/function-view.h" +#include "completer.h" /* Opaque declarations. */ struct ui_file; @@ -663,8 +664,8 @@ struct symbol_computed_ops the caller will generate the right code in the process of treating this as an lvalue or rvalue. */ - void (*tracepoint_var_ref) (struct symbol *symbol, struct gdbarch *gdbarch, - struct agent_expr *ax, struct axs_value *value); + void (*tracepoint_var_ref) (struct symbol *symbol, struct agent_expr *ax, + struct axs_value *value); /* Generate C code to compute the location of SYMBOL. The C code is emitted to STREAM. GDBARCH is the current architecture and PC is @@ -1520,25 +1521,43 @@ extern void forget_cached_source_info (void); extern void select_source_symtab (struct symtab *); -extern VEC (char_ptr) *default_make_symbol_completion_list_break_on - (const char *text, const char *word, const char *break_on, +/* The reason we're calling into a completion match list collector + function. */ +enum class complete_symbol_mode + { + /* Completing an expression. */ + EXPRESSION, + + /* Completing a linespec. */ + LINESPEC, + }; + +extern void default_collect_symbol_completion_matches_break_on + (completion_tracker &tracker, + complete_symbol_mode mode, + const char *text, const char *word, const char *break_on, enum type_code code); -extern VEC (char_ptr) *default_make_symbol_completion_list (const char *, - const char *, - enum type_code); -extern VEC (char_ptr) *make_symbol_completion_list (const char *, const char *); -extern VEC (char_ptr) *make_symbol_completion_type (const char *, const char *, +extern void default_collect_symbol_completion_matches + (completion_tracker &tracker, + complete_symbol_mode, + const char *, + const char *, + enum type_code); +extern void collect_symbol_completion_matches (completion_tracker &tracker, + complete_symbol_mode, + const char *, const char *); +extern void collect_symbol_completion_matches_type (completion_tracker &tracker, + const char *, const char *, enum type_code); -extern VEC (char_ptr) *make_symbol_completion_list_fn (struct cmd_list_element *, - const char *, - const char *); -extern VEC (char_ptr) *make_file_symbol_completion_list (const char *, - const char *, - const char *); +extern void collect_file_symbol_completion_matches (completion_tracker &tracker, + complete_symbol_mode, + const char *, + const char *, + const char *); -extern VEC (char_ptr) *make_source_files_completion_list (const char *, - const char *); +extern completion_list + make_source_files_completion_list (const char *, const char *); /* symtab.c */ diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c index 0b5b46f..bee8e00 100644 --- a/gdb/target-descriptions.c +++ b/gdb/target-descriptions.c @@ -34,6 +34,30 @@ #include "gdb_obstack.h" #include "hashtab.h" #include "inferior.h" +#include <algorithm> +#include "completer.h" +#include "readline/tilde.h" /* tilde_expand */ + +/* The interface to visit different elements of target description. */ + +class tdesc_element_visitor +{ +public: + virtual void visit_pre (const target_desc *e) = 0; + virtual void visit_post (const target_desc *e) = 0; + + virtual void visit_pre (const tdesc_feature *e) = 0; + virtual void visit_post (const tdesc_feature *e) = 0; + + virtual void visit (const tdesc_type *e) = 0; + virtual void visit (const tdesc_reg *e) = 0; +}; + +class tdesc_element +{ +public: + virtual void accept (tdesc_element_visitor &v) const = 0; +}; /* Types. */ @@ -46,7 +70,7 @@ DEF_VEC_O(property_s); /* An individual register from a target description. */ -typedef struct tdesc_reg +typedef struct tdesc_reg : tdesc_element { tdesc_reg (struct tdesc_feature *feature, const char *name_, int regnum, int save_restore_, const char *group_, @@ -62,7 +86,7 @@ typedef struct tdesc_reg tdesc_type = tdesc_named_type (feature, type); } - ~tdesc_reg () + virtual ~tdesc_reg () { xfree (name); xfree (type); @@ -106,6 +130,26 @@ typedef struct tdesc_reg /* The target-described type corresponding to TYPE, if found. */ struct tdesc_type *tdesc_type; + + void accept (tdesc_element_visitor &v) const override + { + v.visit (this); + } + + bool operator== (const tdesc_reg &other) const + { + return (streq (name, other.name) + && target_regnum == other.target_regnum + && save_restore == other.save_restore + && bitsize == other.bitsize + && (group == other.group || streq (group, other.group)) + && streq (type, other.type)); + } + + bool operator!= (const tdesc_reg &other) const + { + return !(*this == other); + } } *tdesc_reg_p; DEF_VEC_P(tdesc_reg_p); @@ -151,7 +195,7 @@ enum tdesc_type_kind TDESC_TYPE_ENUM }; -typedef struct tdesc_type +typedef struct tdesc_type : tdesc_element { tdesc_type (const char *name_, enum tdesc_type_kind kind_) : name (xstrdup (name_)), kind (kind_) @@ -159,7 +203,7 @@ typedef struct tdesc_type memset (&u, 0, sizeof (u)); } - ~tdesc_type () + virtual ~tdesc_type () { switch (kind) { @@ -214,19 +258,34 @@ typedef struct tdesc_type int size; } u; } u; + + void accept (tdesc_element_visitor &v) const override + { + v.visit (this); + } + + bool operator== (const tdesc_type &other) const + { + return (streq (name, other.name) && kind == other.kind); + } + + bool operator!= (const tdesc_type &other) const + { + return !(*this == other); + } } *tdesc_type_p; DEF_VEC_P(tdesc_type_p); /* A feature from a target description. Each feature is a collection of other elements, e.g. registers and types. */ -typedef struct tdesc_feature +typedef struct tdesc_feature : tdesc_element { tdesc_feature (const char *name_) : name (xstrdup (name_)) {} - ~tdesc_feature () + virtual ~tdesc_feature () { struct tdesc_reg *reg; struct tdesc_type *type; @@ -256,6 +315,76 @@ typedef struct tdesc_feature /* The types associated with this feature. */ VEC(tdesc_type_p) *types = NULL; + + void accept (tdesc_element_visitor &v) const override + { + v.visit_pre (this); + + struct tdesc_type *type; + + for (int ix = 0; + VEC_iterate (tdesc_type_p, types, ix, type); + ix++) + type->accept (v); + + struct tdesc_reg *reg; + + for (int ix = 0; + VEC_iterate (tdesc_reg_p, registers, ix, reg); + ix++) + reg->accept (v); + + + v.visit_post (this); + } + + bool operator== (const tdesc_feature &other) const + { + if (strcmp (name, other.name) != 0) + return false; + + if (VEC_length (tdesc_reg_p, registers) + != VEC_length (tdesc_reg_p, other.registers)) + return false; + + struct tdesc_reg *reg; + + for (int ix = 0; + VEC_iterate (tdesc_reg_p, registers, ix, reg); + ix++) + { + tdesc_reg *reg2 + = VEC_index (tdesc_reg_p, other.registers, ix); + + if (reg != reg2 && *reg != *reg2) + return false; + } + + if (VEC_length (tdesc_type_p, types) + != VEC_length (tdesc_type_p, other.types)) + return false; + + tdesc_type *type; + + for (int ix = 0; + VEC_iterate (tdesc_type_p, types, ix, type); + ix++) + { + tdesc_type *type2 + = VEC_index (tdesc_type_p, other.types, ix); + + if (type != type2 && *type != *type2) + return false; + } + + return true; + } + + bool operator!= (const tdesc_feature &other) const + { + return !(*this == other); + } + } *tdesc_feature_p; DEF_VEC_P(tdesc_feature_p); @@ -265,23 +394,100 @@ DEF_VEC_P(arch_p); /* A target description. */ -struct target_desc +struct target_desc : tdesc_element { + target_desc () + {} + + virtual ~target_desc () + { + struct tdesc_feature *feature; + struct property *prop; + int ix; + + for (ix = 0; + VEC_iterate (tdesc_feature_p, features, ix, feature); + ix++) + delete feature; + VEC_free (tdesc_feature_p, features); + + for (ix = 0; + VEC_iterate (property_s, properties, ix, prop); + ix++) + { + xfree (prop->key); + xfree (prop->value); + } + + VEC_free (property_s, properties); + VEC_free (arch_p, compatible); + } + + target_desc (const target_desc &) = delete; + void operator= (const target_desc &) = delete; + /* The architecture reported by the target, if any. */ - const struct bfd_arch_info *arch; + const struct bfd_arch_info *arch = NULL; /* The osabi reported by the target, if any; GDB_OSABI_UNKNOWN otherwise. */ - enum gdb_osabi osabi; + enum gdb_osabi osabi = GDB_OSABI_UNKNOWN; /* The list of compatible architectures reported by the target. */ - VEC(arch_p) *compatible; + VEC(arch_p) *compatible = NULL; /* Any architecture-specific properties specified by the target. */ - VEC(property_s) *properties; + VEC(property_s) *properties = NULL; /* The features associated with this target. */ - VEC(tdesc_feature_p) *features; + VEC(tdesc_feature_p) *features = NULL; + + void accept (tdesc_element_visitor &v) const override + { + v.visit_pre (this); + + struct tdesc_feature *feature; + + for (int ix = 0; + VEC_iterate (tdesc_feature_p, features, ix, feature); + ix++) + feature->accept (v); + + v.visit_post (this); + } + + bool operator== (const target_desc &other) const + { + if (arch != other.arch) + return false; + + if (osabi != other.osabi) + return false; + + if (VEC_length (tdesc_feature_p, features) + != VEC_length (tdesc_feature_p, other.features)) + return false; + + struct tdesc_feature *feature; + + for (int ix = 0; + VEC_iterate (tdesc_feature_p, features, ix, feature); + ix++) + { + struct tdesc_feature *feature2 + = VEC_index (tdesc_feature_p, other.features, ix); + + if (feature != feature2 && *feature != *feature2) + return false; + } + + return true; + } + + bool operator!= (const target_desc &other) const + { + return !(*this == other); + } }; /* Per-architecture data associated with a target description. The @@ -1551,35 +1757,15 @@ tdesc_create_feature (struct target_desc *tdesc, const char *name) struct target_desc * allocate_target_description (void) { - return XCNEW (struct target_desc); + return new target_desc (); } static void free_target_description (void *arg) { struct target_desc *target_desc = (struct target_desc *) arg; - struct tdesc_feature *feature; - struct property *prop; - int ix; - - for (ix = 0; - VEC_iterate (tdesc_feature_p, target_desc->features, ix, feature); - ix++) - delete feature; - VEC_free (tdesc_feature_p, target_desc->features); - - for (ix = 0; - VEC_iterate (property_s, target_desc->properties, ix, prop); - ix++) - { - xfree (prop->key); - xfree (prop->value); - } - VEC_free (property_s, target_desc->properties); - - VEC_free (arch_p, target_desc->compatible); - xfree (target_desc); + delete target_desc; } struct cleanup * @@ -1704,279 +1890,477 @@ unset_tdesc_filename_cmd (char *args, int from_tty) target_find_description (); } -static void -maint_print_c_tdesc_cmd (char *args, int from_tty) +/* Print target description in C. */ + +class print_c_tdesc : public tdesc_element_visitor { - const struct target_desc *tdesc; - const struct bfd_arch_info *compatible; - const char *filename, *inp; - char *function, *outp; - struct property *prop; - struct tdesc_feature *feature; - struct tdesc_reg *reg; - struct tdesc_type *type; - struct tdesc_type_field *f; - int ix, ix2, ix3; - int printed_field_type = 0; - - /* Use the global target-supplied description, not the current - architecture's. This lets a GDB for one architecture generate C - for another architecture's description, even though the gdbarch - initialization code will reject the new description. */ - tdesc = current_target_desc; - if (tdesc == NULL) - error (_("There is no target description to print.")); +public: + print_c_tdesc (std::string &filename_after_features) + : m_filename_after_features (filename_after_features) + { + const char *inp; + char *outp; + const char *filename = lbasename (m_filename_after_features.c_str ()); - if (target_description_filename == NULL) - error (_("The current target description did not come from an XML file.")); + m_function = (char *) xmalloc (strlen (filename) + 1); + for (inp = filename, outp = m_function; *inp != '\0'; inp++) + if (*inp == '.') + break; + else if (*inp == '-') + *outp++ = '_'; + else + *outp++ = *inp; + *outp = '\0'; - filename = lbasename (target_description_filename); - function = (char *) alloca (strlen (filename) + 1); - for (inp = filename, outp = function; *inp != '\0'; inp++) - if (*inp == '.') - break; - else if (*inp == '-') - *outp++ = '_'; - else - *outp++ = *inp; - *outp = '\0'; - - /* Standard boilerplate. */ - printf_unfiltered ("/* THIS FILE IS GENERATED. " - "-*- buffer-read-only: t -*- vi" - ":set ro:\n"); - printf_unfiltered (" Original: %s */\n\n", filename); - printf_unfiltered ("#include \"defs.h\"\n"); - printf_unfiltered ("#include \"osabi.h\"\n"); - printf_unfiltered ("#include \"target-descriptions.h\"\n"); - printf_unfiltered ("\n"); - - printf_unfiltered ("struct target_desc *tdesc_%s;\n", function); - printf_unfiltered ("static void\n"); - printf_unfiltered ("initialize_tdesc_%s (void)\n", function); - printf_unfiltered ("{\n"); - printf_unfiltered - (" struct target_desc *result = allocate_target_description ();\n"); - printf_unfiltered (" struct tdesc_feature *feature;\n"); - - /* Now we do some "filtering" in order to know which variables to - declare. This is needed because otherwise we would declare unused - variables `field_type' and `type'. */ - for (ix = 0; - VEC_iterate (tdesc_feature_p, tdesc->features, ix, feature); - ix++) - { - int printed_desc_type = 0; + /* Standard boilerplate. */ + printf_unfiltered ("/* THIS FILE IS GENERATED. " + "-*- buffer-read-only: t -*- vi" + ":set ro:\n"); + } - for (ix2 = 0; - VEC_iterate (tdesc_type_p, feature->types, ix2, type); - ix2++) - { - if (!printed_field_type) - { - printf_unfiltered (" struct tdesc_type *field_type;\n"); - printed_field_type = 1; - } + ~print_c_tdesc () + { + xfree (m_function); + } - if ((type->kind == TDESC_TYPE_UNION - || type->kind == TDESC_TYPE_STRUCT - || type->kind == TDESC_TYPE_FLAGS - || type->kind == TDESC_TYPE_ENUM) - && VEC_length (tdesc_type_field, type->u.u.fields) > 0) - { - printf_unfiltered (" struct tdesc_type *type;\n"); - printed_desc_type = 1; - break; - } - } + void visit_pre (const target_desc *e) override + { + printf_unfiltered (" Original: %s */\n\n", + lbasename (m_filename_after_features.c_str ())); + + printf_unfiltered ("#include \"defs.h\"\n"); + printf_unfiltered ("#include \"osabi.h\"\n"); + printf_unfiltered ("#include \"target-descriptions.h\"\n"); + printf_unfiltered ("\n"); + + printf_unfiltered ("struct target_desc *tdesc_%s;\n", m_function); + printf_unfiltered ("static void\n"); + printf_unfiltered ("initialize_tdesc_%s (void)\n", m_function); + printf_unfiltered ("{\n"); + printf_unfiltered + (" struct target_desc *result = allocate_target_description ();\n"); + + if (tdesc_architecture (e) != NULL) + { + printf_unfiltered + (" set_tdesc_architecture (result, bfd_scan_arch (\"%s\"));\n", + tdesc_architecture (e)->printable_name); + printf_unfiltered ("\n"); + } + if (tdesc_osabi (e) > GDB_OSABI_UNKNOWN + && tdesc_osabi (e) < GDB_OSABI_INVALID) + { + printf_unfiltered + (" set_tdesc_osabi (result, osabi_from_tdesc_string (\"%s\"));\n", + gdbarch_osabi_name (tdesc_osabi (e))); + printf_unfiltered ("\n"); + } - if (printed_desc_type) + int ix; + const struct bfd_arch_info *compatible; + struct property *prop; + + for (ix = 0; VEC_iterate (arch_p, e->compatible, ix, compatible); + ix++) + { + printf_unfiltered + (" tdesc_add_compatible (result, bfd_scan_arch (\"%s\"));\n", + compatible->printable_name); + } + + if (ix) + printf_unfiltered ("\n"); + + for (ix = 0; VEC_iterate (property_s, e->properties, ix, prop); + ix++) + { + printf_unfiltered (" set_tdesc_property (result, \"%s\", \"%s\");\n", + prop->key, prop->value); + } + printf_unfiltered (" struct tdesc_feature *feature;\n"); + } + + void visit_pre (const tdesc_feature *e) override + { + printf_unfiltered ("\n feature = tdesc_create_feature (result, \"%s\");\n", + e->name); + } + + void visit_post (const tdesc_feature *e) override + {} + + void visit_post (const target_desc *e) override + { + printf_unfiltered ("\n tdesc_%s = result;\n", m_function); + printf_unfiltered ("}\n"); + } + + void visit (const tdesc_type *type) override + { + struct tdesc_type_field *f; + + /* Now we do some "filtering" in order to know which variables to + declare. This is needed because otherwise we would declare unused + variables `field_type' and `type'. */ + if (!m_printed_field_type) + { + printf_unfiltered (" struct tdesc_type *field_type;\n"); + m_printed_field_type = true; + } + + if ((type->kind == TDESC_TYPE_UNION + || type->kind == TDESC_TYPE_STRUCT + || type->kind == TDESC_TYPE_FLAGS + || type->kind == TDESC_TYPE_ENUM) + && VEC_length (tdesc_type_field, type->u.u.fields) > 0 + && !m_printed_type) + { + printf_unfiltered (" struct tdesc_type *type;\n"); + m_printed_type = true; + } + + switch (type->kind) + { + case TDESC_TYPE_VECTOR: + printf_unfiltered + (" field_type = tdesc_named_type (feature, \"%s\");\n", + type->u.v.type->name); + printf_unfiltered + (" tdesc_create_vector (feature, \"%s\", field_type, %d);\n", + type->name, type->u.v.count); break; - } + case TDESC_TYPE_STRUCT: + case TDESC_TYPE_FLAGS: + if (type->kind == TDESC_TYPE_STRUCT) + { + printf_unfiltered + (" type = tdesc_create_struct (feature, \"%s\");\n", + type->name); + if (type->u.u.size != 0) + printf_unfiltered + (" tdesc_set_struct_size (type, %d);\n", + type->u.u.size); + } + else + { + printf_unfiltered + (" type = tdesc_create_flags (feature, \"%s\", %d);\n", + type->name, type->u.u.size); + } + for (int ix3 = 0; + VEC_iterate (tdesc_type_field, type->u.u.fields, ix3, f); + ix3++) + { + const char *type_name; + + gdb_assert (f->type != NULL); + type_name = f->type->name; + + /* To minimize changes to generated files, don't emit type + info for fields that have defaulted types. */ + if (f->start != -1) + { + gdb_assert (f->end != -1); + if (f->type->kind == TDESC_TYPE_BOOL) + { + gdb_assert (f->start == f->end); + printf_unfiltered + (" tdesc_add_flag (type, %d, \"%s\");\n", + f->start, f->name); + } + else if ((type->u.u.size == 4 + && f->type->kind == TDESC_TYPE_UINT32) + || (type->u.u.size == 8 + && f->type->kind == TDESC_TYPE_UINT64)) + { + printf_unfiltered + (" tdesc_add_bitfield (type, \"%s\", %d, %d);\n", + f->name, f->start, f->end); + } + else + { + printf_unfiltered + (" field_type = tdesc_named_type (feature," + " \"%s\");\n", + type_name); + printf_unfiltered + (" tdesc_add_typed_bitfield (type, \"%s\"," + " %d, %d, field_type);\n", + f->name, f->start, f->end); + } + } + else /* Not a bitfield. */ + { + gdb_assert (f->end == -1); + gdb_assert (type->kind == TDESC_TYPE_STRUCT); + printf_unfiltered + (" field_type = tdesc_named_type (feature," + " \"%s\");\n", + type_name); + printf_unfiltered + (" tdesc_add_field (type, \"%s\", field_type);\n", + f->name); + } + } + break; + case TDESC_TYPE_UNION: + printf_unfiltered + (" type = tdesc_create_union (feature, \"%s\");\n", + type->name); + for (int ix3 = 0; + VEC_iterate (tdesc_type_field, type->u.u.fields, ix3, f); + ix3++) + { + printf_unfiltered + (" field_type = tdesc_named_type (feature, \"%s\");\n", + f->type->name); + printf_unfiltered + (" tdesc_add_field (type, \"%s\", field_type);\n", + f->name); + } + break; + case TDESC_TYPE_ENUM: + printf_unfiltered + (" type = tdesc_create_enum (feature, \"%s\", %d);\n", + type->name, type->u.u.size); + for (int ix3 = 0; + VEC_iterate (tdesc_type_field, type->u.u.fields, ix3, f); + ix3++) + printf_unfiltered + (" tdesc_add_enum_value (type, %d, \"%s\");\n", + f->start, f->name); + break; + default: + error (_("C output is not supported type \"%s\"."), type->name); + } + printf_unfiltered ("\n"); + } + + void visit (const tdesc_reg *reg) override + { + printf_unfiltered (" tdesc_create_reg (feature, \"%s\", %ld, %d, ", + reg->name, reg->target_regnum, reg->save_restore); + if (reg->group) + printf_unfiltered ("\"%s\", ", reg->group); + else + printf_unfiltered ("NULL, "); + printf_unfiltered ("%d, \"%s\");\n", reg->bitsize, reg->type); + } + +protected: + std::string m_filename_after_features; + +private: + char *m_function; + bool m_printed_field_type = false; + bool m_printed_type = false; +}; + +/* Print target description feature in C. */ + +class print_c_feature : public print_c_tdesc +{ +public: + print_c_feature (std::string &file) + : print_c_tdesc (file) + { + /* Trim ".tmp". */ + auto const pos = m_filename_after_features.find_last_of ('.'); + + m_filename_after_features = m_filename_after_features.substr (0, pos); + } + + void visit_pre (const target_desc *e) override + { + printf_unfiltered (" Original: %s */\n\n", + lbasename (m_filename_after_features.c_str ())); + + printf_unfiltered ("#include \"target-descriptions.h\"\n"); + printf_unfiltered ("\n"); + } + + void visit_post (const target_desc *e) override + {} + + void visit_pre (const tdesc_feature *e) override + { + std::string name (m_filename_after_features); + + auto pos = name.find_first_of ('.'); + + name = name.substr (0, pos); + std::replace (name.begin (), name.end (), '/', '_'); + std::replace (name.begin (), name.end (), '-', '_'); + + printf_unfiltered ("static int\n"); + printf_unfiltered ("create_feature_%s ", name.c_str ()); + printf_unfiltered ("(struct target_desc *result, long regnum)\n"); - printf_unfiltered ("\n"); + printf_unfiltered ("{\n"); + printf_unfiltered (" struct tdesc_feature *feature;\n"); + printf_unfiltered ("\n feature = tdesc_create_feature (result, \"%s\");\n", + e->name); + } + + void visit_post (const tdesc_feature *e) override + { + printf_unfiltered (" return regnum;\n"); + printf_unfiltered ("}\n"); + } + + void visit (const tdesc_reg *reg) override + { + /* Most "reg" in XML target descriptions don't have "regnum" + attribute, so the register number is allocated sequentially. + In case that reg has "regnum" attribute, register number + should be set by that explicitly. */ + + if (reg->target_regnum < m_next_regnum) + { + /* The integrity check, it can catch some errors on register + number collision, like this, + + <reg name="x0" bitsize="32"/> + <reg name="x1" bitsize="32"/> + <reg name="x2" bitsize="32"/> + <reg name="x3" bitsize="32"/> + <reg name="ps" bitsize="32" regnum="3"/> + + but it also has false negatives. The target description + below is correct, + + <reg name="x1" bitsize="32" regnum="1"/> + <reg name="x3" bitsize="32" regnum="3"/> + <reg name="x2" bitsize="32" regnum="2"/> + <reg name="x4" bitsize="32" regnum="4"/> + + but it is not a good practice, so still error on this, + and also print the message so that it can be saved in the + generated c file. */ + + printf_unfiltered ("ERROR: \"regnum\" attribute %ld ", + reg->target_regnum); + printf_unfiltered ("is not the largest number (%d).\n", + m_next_regnum); + error (_("\"regnum\" attribute %ld is not the largest number (%d)."), + reg->target_regnum, m_next_regnum); + } + + if (reg->target_regnum > m_next_regnum) + { + printf_unfiltered (" regnum = %ld;\n", reg->target_regnum); + m_next_regnum = reg->target_regnum; + } + + printf_unfiltered (" tdesc_create_reg (feature, \"%s\", regnum++, %d, ", + reg->name, reg->save_restore); + if (reg->group) + printf_unfiltered ("\"%s\", ", reg->group); + else + printf_unfiltered ("NULL, "); + printf_unfiltered ("%d, \"%s\");\n", reg->bitsize, reg->type); + + m_next_regnum++; + } + +private: + /* The register number to use for the next register we see. */ + int m_next_regnum = 0; +}; + +static void +maint_print_c_tdesc_cmd (char *args, int from_tty) +{ + const struct target_desc *tdesc; + const char *filename; - if (tdesc_architecture (tdesc) != NULL) + if (args == NULL) { - printf_unfiltered - (" set_tdesc_architecture (result, bfd_scan_arch (\"%s\"));\n", - tdesc_architecture (tdesc)->printable_name); - printf_unfiltered ("\n"); + /* Use the global target-supplied description, not the current + architecture's. This lets a GDB for one architecture generate C + for another architecture's description, even though the gdbarch + initialization code will reject the new description. */ + tdesc = current_target_desc; + filename = target_description_filename; } - - if (tdesc_osabi (tdesc) > GDB_OSABI_UNKNOWN - && tdesc_osabi (tdesc) < GDB_OSABI_INVALID) + else { - printf_unfiltered - (" set_tdesc_osabi (result, osabi_from_tdesc_string (\"%s\"));\n", - gdbarch_osabi_name (tdesc_osabi (tdesc))); - printf_unfiltered ("\n"); + /* Use the target description from the XML file. */ + filename = args; + tdesc = file_read_description_xml (filename); } - for (ix = 0; VEC_iterate (arch_p, tdesc->compatible, ix, compatible); - ix++) + if (tdesc == NULL) + error (_("There is no target description to print.")); + + if (filename == NULL) + error (_("The current target description did not come from an XML file.")); + + std::string filename_after_features (filename); + auto loc = filename_after_features.rfind ("/features/"); + + if (loc != std::string::npos) + filename_after_features = filename_after_features.substr (loc + 10); + + /* Print c files for target features instead of target descriptions, + because c files got from target features are more flexible than the + counterparts. */ + if (startswith (filename_after_features.c_str (), "i386/32bit-")) { - printf_unfiltered - (" tdesc_add_compatible (result, bfd_scan_arch (\"%s\"));\n", - compatible->printable_name); - } - if (ix) - printf_unfiltered ("\n"); + print_c_feature v (filename_after_features); - for (ix = 0; VEC_iterate (property_s, tdesc->properties, ix, prop); - ix++) + tdesc->accept (v); + } + else { - printf_unfiltered (" set_tdesc_property (result, \"%s\", \"%s\");\n", - prop->key, prop->value); + print_c_tdesc v (filename_after_features); + + tdesc->accept (v); } +} - for (ix = 0; - VEC_iterate (tdesc_feature_p, tdesc->features, ix, feature); - ix++) - { - printf_unfiltered (" \ -feature = tdesc_create_feature (result, \"%s\");\n", - feature->name); +namespace selftests { - for (ix2 = 0; - VEC_iterate (tdesc_type_p, feature->types, ix2, type); - ix2++) - { - switch (type->kind) - { - case TDESC_TYPE_VECTOR: - printf_unfiltered - (" field_type = tdesc_named_type (feature, \"%s\");\n", - type->u.v.type->name); - printf_unfiltered - (" tdesc_create_vector (feature, \"%s\", field_type, %d);\n", - type->name, type->u.v.count); - break; - case TDESC_TYPE_STRUCT: - case TDESC_TYPE_FLAGS: - if (type->kind == TDESC_TYPE_STRUCT) - { - printf_unfiltered - (" type = tdesc_create_struct (feature, \"%s\");\n", - type->name); - if (type->u.u.size != 0) - printf_unfiltered - (" tdesc_set_struct_size (type, %d);\n", - type->u.u.size); - } - else - { - printf_unfiltered - (" type = tdesc_create_flags (feature, \"%s\", %d);\n", - type->name, type->u.u.size); - } - for (ix3 = 0; - VEC_iterate (tdesc_type_field, type->u.u.fields, ix3, f); - ix3++) - { - const char *type_name; - - gdb_assert (f->type != NULL); - type_name = f->type->name; - - /* To minimize changes to generated files, don't emit type - info for fields that have defaulted types. */ - if (f->start != -1) - { - gdb_assert (f->end != -1); - if (f->type->kind == TDESC_TYPE_BOOL) - { - gdb_assert (f->start == f->end); - printf_unfiltered - (" tdesc_add_flag (type, %d, \"%s\");\n", - f->start, f->name); - } - else if ((type->u.u.size == 4 - && f->type->kind == TDESC_TYPE_UINT32) - || (type->u.u.size == 8 - && f->type->kind == TDESC_TYPE_UINT64)) - { - printf_unfiltered - (" tdesc_add_bitfield (type, \"%s\", %d, %d);\n", - f->name, f->start, f->end); - } - else - { - printf_unfiltered - (" field_type = tdesc_named_type (feature," - " \"%s\");\n", - type_name); - printf_unfiltered - (" tdesc_add_typed_bitfield (type, \"%s\"," - " %d, %d, field_type);\n", - f->name, f->start, f->end); - } - } - else /* Not a bitfield. */ - { - gdb_assert (f->end == -1); - gdb_assert (type->kind == TDESC_TYPE_STRUCT); - printf_unfiltered - (" field_type = tdesc_named_type (feature," - " \"%s\");\n", - type_name); - printf_unfiltered - (" tdesc_add_field (type, \"%s\", field_type);\n", - f->name); - } - } - break; - case TDESC_TYPE_UNION: - printf_unfiltered - (" type = tdesc_create_union (feature, \"%s\");\n", - type->name); - for (ix3 = 0; - VEC_iterate (tdesc_type_field, type->u.u.fields, ix3, f); - ix3++) - { - printf_unfiltered - (" field_type = tdesc_named_type (feature, \"%s\");\n", - f->type->name); - printf_unfiltered - (" tdesc_add_field (type, \"%s\", field_type);\n", - f->name); - } - break; - case TDESC_TYPE_ENUM: - printf_unfiltered - (" type = tdesc_create_enum (feature, \"%s\", %d);\n", - type->name, type->u.u.size); - for (ix3 = 0; - VEC_iterate (tdesc_type_field, type->u.u.fields, ix3, f); - ix3++) - printf_unfiltered - (" tdesc_add_enum_value (type, %d, \"%s\");\n", - f->start, f->name); - break; - default: - error (_("C output is not supported type \"%s\"."), type->name); - } - printf_unfiltered ("\n"); - } +static std::vector<std::pair<const char*, const target_desc *>> xml_tdesc; - for (ix2 = 0; - VEC_iterate (tdesc_reg_p, feature->registers, ix2, reg); - ix2++) - { - printf_unfiltered (" tdesc_create_reg (feature, \"%s\", %ld, %d, ", - reg->name, reg->target_regnum, reg->save_restore); - if (reg->group) - printf_unfiltered ("\"%s\", ", reg->group); - else - printf_unfiltered ("NULL, "); - printf_unfiltered ("%d, \"%s\");\n", reg->bitsize, reg->type); - } +#if GDB_SELF_TEST - printf_unfiltered ("\n"); - } +/* See target-descritpions.h. */ + +void +record_xml_tdesc (const char *xml_file, const struct target_desc *tdesc) +{ + xml_tdesc.emplace_back (xml_file, tdesc); +} +#endif - printf_unfiltered (" tdesc_%s = result;\n", function); - printf_unfiltered ("}\n"); +} + +/* Check that the target descriptions created dynamically by + architecture-specific code equal the descriptions created from XML files + found in the specified directory DIR. */ + +static void +maintenance_check_xml_descriptions (char *dir, int from_tty) +{ + if (dir == NULL) + error (_("Missing dir name")); + + gdb::unique_xmalloc_ptr<char> dir1 (tilde_expand (dir)); + std::string feature_dir (dir1.get ()); + unsigned int failed = 0; + + for (auto const &e : selftests::xml_tdesc) + { + std::string tdesc_xml = (feature_dir + SLASH_STRING + e.first); + const target_desc *tdesc + = file_read_description_xml (tdesc_xml.data ()); + + if (tdesc == NULL || *tdesc != *e.second) + failed++; + } + printf_filtered (_("Tested %lu XML files, %d failed\n"), + (long) selftests::xml_tdesc.size (), failed); } /* Provide a prototype to silence -Wmissing-prototypes. */ @@ -2019,4 +2403,14 @@ GDB will read the description from the target."), add_cmd ("c-tdesc", class_maintenance, maint_print_c_tdesc_cmd, _("\ Print the current target description as a C source file."), &maintenanceprintlist); + + cmd_list_element *cmd; + + cmd = add_cmd ("xml-descriptions", class_maintenance, + maintenance_check_xml_descriptions, _("\ +Check the target descriptions created in GDB equal the descriptions\n\ +created from XML files in the directory.\n\ +The parameter is the directory name."), + &maintenancechecklist); + set_cmd_completer (cmd, filename_completer); } diff --git a/gdb/target-descriptions.h b/gdb/target-descriptions.h index 361ac97..591da15 100644 --- a/gdb/target-descriptions.h +++ b/gdb/target-descriptions.h @@ -253,4 +253,16 @@ void tdesc_create_reg (struct tdesc_feature *feature, const char *name, int regnum, int save_restore, const char *group, int bitsize, const char *type); +#if GDB_SELF_TEST +namespace selftests { + +/* Record that XML_FILE should generate a target description that equals + TDESC, to be verified by the "maintenance check xml-descriptions" + command. */ + +void record_xml_tdesc (const char *xml_file, + const struct target_desc *tdesc); +} +#endif + #endif /* TARGET_DESCRIPTIONS_H */ diff --git a/gdb/target.c b/gdb/target.c index e526bcc..9b63ab7 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -46,6 +46,7 @@ #include "top.h" #include "event-top.h" #include <algorithm> +#include "byte-vector.h" static void target_info (char *, int); @@ -1284,9 +1285,6 @@ memory_xfer_partial (struct target_ops *ops, enum target_object object, } else { - gdb_byte *buf; - struct cleanup *old_chain; - /* A large write request is likely to be partially satisfied by memory_xfer_partial_1. We will continually malloc and free a copy of the entire write request for breakpoint @@ -1295,15 +1293,10 @@ memory_xfer_partial (struct target_ops *ops, enum target_object object, to mitigate this. */ len = std::min (ops->to_get_memory_xfer_limit (ops), len); - buf = (gdb_byte *) xmalloc (len); - old_chain = make_cleanup (xfree, buf); - memcpy (buf, writebuf, len); - - breakpoint_xfer_memory (NULL, buf, writebuf, memaddr, len); - res = memory_xfer_partial_1 (ops, object, NULL, buf, memaddr, len, + gdb::byte_vector buf (writebuf, writebuf + len); + breakpoint_xfer_memory (NULL, buf.data (), writebuf, memaddr, len); + res = memory_xfer_partial_1 (ops, object, NULL, buf.data (), memaddr, len, xfered_len); - - do_cleanups (old_chain); } return res; @@ -2439,9 +2432,7 @@ simple_search_memory (struct target_ops *ops, #define SEARCH_CHUNK_SIZE 16000 const unsigned chunk_size = SEARCH_CHUNK_SIZE; /* Buffer to hold memory contents for searching. */ - gdb_byte *search_buf; unsigned search_buf_size; - struct cleanup *old_cleanups; search_buf_size = chunk_size + pattern_len - 1; @@ -2449,20 +2440,17 @@ simple_search_memory (struct target_ops *ops, if (search_space_len < search_buf_size) search_buf_size = search_space_len; - search_buf = (gdb_byte *) malloc (search_buf_size); - if (search_buf == NULL) - error (_("Unable to allocate memory to perform the search.")); - old_cleanups = make_cleanup (free_current_contents, &search_buf); + gdb::byte_vector search_buf (search_buf_size); /* Prime the search buffer. */ if (target_read (ops, TARGET_OBJECT_MEMORY, NULL, - search_buf, start_addr, search_buf_size) != search_buf_size) + search_buf.data (), start_addr, search_buf_size) + != search_buf_size) { warning (_("Unable to access %s bytes of target " "memory at %s, halting search."), pulongest (search_buf_size), hex_string (start_addr)); - do_cleanups (old_cleanups); return -1; } @@ -2478,15 +2466,14 @@ simple_search_memory (struct target_ops *ops, unsigned nr_search_bytes = std::min (search_space_len, (ULONGEST) search_buf_size); - found_ptr = (gdb_byte *) memmem (search_buf, nr_search_bytes, + found_ptr = (gdb_byte *) memmem (search_buf.data (), nr_search_bytes, pattern, pattern_len); if (found_ptr != NULL) { - CORE_ADDR found_addr = start_addr + (found_ptr - search_buf); + CORE_ADDR found_addr = start_addr + (found_ptr - search_buf.data ()); *found_addrp = found_addr; - do_cleanups (old_cleanups); return 1; } @@ -2507,20 +2494,19 @@ simple_search_memory (struct target_ops *ops, /* Copy the trailing part of the previous iteration to the front of the buffer for the next iteration. */ gdb_assert (keep_len == pattern_len - 1); - memcpy (search_buf, search_buf + chunk_size, keep_len); + memcpy (&search_buf[0], &search_buf[chunk_size], keep_len); nr_to_read = std::min (search_space_len - keep_len, (ULONGEST) chunk_size); if (target_read (ops, TARGET_OBJECT_MEMORY, NULL, - search_buf + keep_len, read_addr, + &search_buf[keep_len], read_addr, nr_to_read) != nr_to_read) { warning (_("Unable to access %s bytes of target " "memory at %s, halting search."), plongest (nr_to_read), hex_string (read_addr)); - do_cleanups (old_cleanups); return -1; } @@ -2530,7 +2516,6 @@ simple_search_memory (struct target_ops *ops, /* Not found. */ - do_cleanups (old_cleanups); return 0; } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 253e229..39c49b8 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,150 @@ +2017-08-15 Sergio Durigan Junior <sergiodj@redhat.com> + + PR gdb/21954 + * gdb.base/environ.exp: Add test to check if 'unset environment' + works. + +2017-08-14 Andreas Arnez <arnez@linux.vnet.ibm.com> + + * lib/gdb.exp (universal_compile_options): New caching proc. + (gdb_compile): Suppress GCC's coloring of messages. + +2017-08-14 Tom Tromey <tom@tromey.com> + + PR gdb/21675: + * gdb.base/printcmds.exp (test_radices): New function. + * gdb.dwarf2/var-access.exp: Use p/u, not p/d. + * gdb.base/sizeof.exp (check_valueof): Use p/d. + * lib/gdb.exp (get_integer_valueof): Use p/d. + +2017-08-12 Simon Marchi <simon.marchi@ericsson.com> + + * lib/gdb.exp (get_valueof): Don't capture end-of-line + characters. + +2017-08-05 Tom Tromey <tom@tromey.com> + + * gdb.rust/simple.exp: Allow String to appear in a different + namespace. + +2017-07-26 Yao Qi <yao.qi@linaro.org> + + * gdb.gdb/unittest.exp: Invoke command + "maintenance check xml-descriptions". + +2017-07-24 Andreas Arnez <arnez@linux.vnet.ibm.com> + + * gdb.arch/s390-vregs.exp: Calculate parameters to hex128 in the + calling context. + (hex128): Drop erroneous calculation of parameters. + +2017-07-22 Simon Marchi <simon.marchi@ericsson.com> + + * gdb.python/py-unwind.exp: Disable stack protection when + building test file. + +2017-07-20 Pedro Alves <palves@redhat.com> + + * gdb.base/default.exp (set language): Adjust expected output. + +2017-07-20 Pedro Alves <palves@redhat.com> + + * gdb.base/dmsym.c (pck__foo__bar__minsym): Rename to ... + (test_minsym): ... this, and make static. + (get_pck__foo__bar__minsym): Rename to ... + (get_test_minsym): ... this. + * gdb.base/dmsym.exp (): Remove "set language ada" call. Adjust + symbol names and comments. + * gdb.base/dmsym_main.c (get_pck__foo__bar__minsym): Rename to ... + (get_test_minsym): ... this. + (pck__foo__bar__minsym__2): Rename to ... + (test_minsym): ... this. + (main): Adjust. + +2017-07-17 Pedro Alves <palves@redhat.com> + + * gdb.base/completion.exp: Adjust expected output. + * gdb.linespec/ls-errs.exp: Don't send tab characters, now that + the completer works. + +2017-07-17 Pedro Alves <palves@redhat.com> + + * gdb.linespec/ls-errs.exp (do_test): Adjust expected output. + +2017-07-15 Andrew Burgess <andrew.burgess@embecosm.com> + + * gdb.mi/mi-vla-fortran.exp: Make test names unique. + +2017-07-14 Tom Tromey <tom@tromey.com> + + PR rust/21764: + * gdb.rust/simple.exp: Add tests. + +2017-07-14 Tom Tromey <tom@tromey.com> + + * gdb.rust/simple.exp: Add regression test for PR rust/21763. + +2017-07-14 Pedro Alves <palves@redhat.com> + + * gdb.linespec/base/one/thefile.cc (z1): New function. + * gdb.linespec/base/two/thefile.cc (z2): New function. + * gdb.linespec/linespec.exp: Add tests. + +2017-07-13 Andrew Burgess <andrew.burgess@embecosm.com> + + * gdb.mi/mi-vla-fortran.exp: Correct even more parameter passing + to mi_create_breakpoint. + +2017-07-13 Andrew Burgess <andrew.burgess@embecosm.com> + + * gdb.mi/mi-vla-fortran.exp: Correct parameter passing to + mi_create_breakpoint. + +2017-07-11 Iain Buclaw <ibuclaw@gdcproject.org> + + * gdb.dlang/demangle.exp: Update for demangling changes. + +2017-07-09 Tom Tromey <tom@tromey.com> + + * gdb.dwarf2/shortpiece.exp: New file. + +2017-07-06 David Blaikie <dblaikie@gmail.com> + + * gdb.dwarf2/fission-multi-cu.S: Test containing multiple CUs in a DWO, + built from fissiont-multi-cu{1,2}.c. + * gdb.dwarf2/fission-multi-cu.exp: Test similar to fission-base.exp, + except putting 'main' and 'func' in separate CUs in the same DWO file. + * gdb.dwarf2/fission-multi-cu1.c: First CU for the multi-CU-single-DWO + test. + * gdb.dwarf2/fission-multi-cu2.c: Second CU in the multi-CU-single-DWO + test. + +2017-07-06 Pedro Alves <palves@redhat.com> + + * gdb.python/py-unwind.exp: Test flushregs. + +2017-06-30 Sergio Durigan Junior <sergiodj@redhat.com> + + PR cli/21688 + * gdb.python/py-cmd.exp (test_python_inline_or_multiline): Add new + tests for alias commands and trailing whitespace. + +2017-06-30 Sergio Durigan Junior <sergiodj@redhat.com> + + PR cli/21688 + * gdb.python/py-cmd.exp (test_python_inline_or_multiline): New + procedure. Call it. + +2017-06-29 Pedro Alves <palves@redhat.com> + + * gdb.base/printcmds.exp: Add tests. + +2017-06-28 Doug Gilmore <Doug.Gilmore@imgtec.com> + + PR gdb/21337 + * gdb.base/reread-readsym.exp: New file. + * gdb.base/reread-readsym.c: New file. + 2017-06-21 Kevin Buettner <kevinb@redhat.com> * gdb.exp (gdb_test): Using noncapturing parens for the $pattern diff --git a/gdb/testsuite/gdb.arch/s390-vregs.exp b/gdb/testsuite/gdb.arch/s390-vregs.exp index 078c153..d2c31e1 100644 --- a/gdb/testsuite/gdb.arch/s390-vregs.exp +++ b/gdb/testsuite/gdb.arch/s390-vregs.exp @@ -147,14 +147,12 @@ gdb_continue_to_breakpoint "change vrs" set vregs [capture_command_output "info registers vector" ""] # Format a 128-bit value, given individual 4-byte values, as hex. -# Leading zeros are suppressed. +# Suppress leading zeros. proc hex128 {a_high a_low b_high b_low} { - set result [format %08x%08x%08x%08x \ - [expr $a_high * ($i + 1) * $a_high ] \ - [expr $a_low * ($i + 1) * $a_low ] \ - [expr $b_high * (32 - $i) * $b_high * 32] \ - [expr $b_low * (32 - $i) * $b_low * 32] ] - return [regsub -- "^0*" $result ""] + set result [format "%x%08x%08x%08x" $a_high $a_low $b_high $b_low] + regsub -- "^0*" $result "" result + if { $result eq "" } { set result 0 } + return $result } set j 1 @@ -162,7 +160,11 @@ foreach {- r i val} [regexp -all -inline -line \ {^(\D*)(\d+)\s+.*?uint128 = 0x([0-9a-f]+?)} $vregs] { if { $r ne "v" } { fail "info registers vector: bad line $j" - } elseif { $val ne [hex128 $a_high $a_low $b_high $b_low] } { + } elseif { $val ne [hex128 \ + [expr $a_high * ($i + 1) * $a_high ] \ + [expr $a_low * ($i + 1) * $a_low ] \ + [expr $b_high * (32 - $i) * $b_high * 32] \ + [expr $b_low * (32 - $i) * $b_low * 32] ] } { fail "compare \$v$i" } incr j 1 diff --git a/gdb/testsuite/gdb.base/completion.exp b/gdb/testsuite/gdb.base/completion.exp index 6597ea7..f03bfc3 100644 --- a/gdb/testsuite/gdb.base/completion.exp +++ b/gdb/testsuite/gdb.base/completion.exp @@ -790,7 +790,7 @@ gdb_test_multiple "" $test { -re "break\.c.*break1\.c.*$gdb_prompt " { send_gdb "1\t\n" gdb_test_multiple "" $test { - -re ".*Function \"$srcfile2\" not defined\..*$gdb_prompt " { + -re "malformed linespec error: unexpected end of input\r\n$gdb_prompt " { pass $test } -re "$gdb_prompt p$" { diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp index 8c0b29c..c25069a 100644 --- a/gdb/testsuite/gdb.base/default.exp +++ b/gdb/testsuite/gdb.base/default.exp @@ -511,7 +511,7 @@ gdb_test "set history size" "Argument required .integer to set it to.*" "set his #test set history gdb_test "set history" "\"set history\" must be followed by the name of a history subcommand.(\[^\r\n\]*\[\r\n\])+List of set history subcommands:(\[^\r\n\]*\[\r\n\])+set history expansion -- Set history expansion on command input(\[^\r\n\]*\[\r\n\])+set history filename -- Set the filename in which to record the command history(\[^\r\n\]*\[\r\n\])+set history save -- Set saving of the history record on exit(\[^\r\n\]*\[\r\n\])+set history size -- Set the size of the command history(\[^\r\n\]*\[\r\n\])+Type \"help set history\" followed by set history subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set history" #test set language -gdb_test "set language" "Requires an argument. Valid arguments are ada, c, c.., asm, minimal, d, fortran, go, auto, local, unknown, modula-2, objective-c, opencl, pascal, rust." "set language" +gdb_test "set language" "Requires an argument. Valid arguments are auto, local, unknown, ada, asm, c, c.., d, fortran, go, minimal, modula-2, objective-c, opencl, pascal, rust." "set language" #test set listsize gdb_test "set listsize" "Argument required .integer to set it to.*" "set listsize" #test set print "p" abbreviation diff --git a/gdb/testsuite/gdb.base/dmsym.c b/gdb/testsuite/gdb.base/dmsym.c index f358b51..dccea23 100644 --- a/gdb/testsuite/gdb.base/dmsym.c +++ b/gdb/testsuite/gdb.base/dmsym.c @@ -15,11 +15,11 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -int pck__foo__bar__minsym = 123; +static int test_minsym = 123; int -get_pck__foo__bar__minsym (void) +get_test_minsym (void) { - pck__foo__bar__minsym++; - return pck__foo__bar__minsym; + test_minsym++; + return test_minsym; } diff --git a/gdb/testsuite/gdb.base/dmsym.exp b/gdb/testsuite/gdb.base/dmsym.exp index a318080..191a319 100644 --- a/gdb/testsuite/gdb.base/dmsym.exp +++ b/gdb/testsuite/gdb.base/dmsym.exp @@ -44,42 +44,31 @@ clean_restart ${testfile} set num "\[0-9\]+" set addr "0x\[0-9a-zA-Z\]+" -# Although the test program is written in C, the original problem -# occurs only when the language is Ada. The use of a C program is -# only a convenience to be able to exercise the original problem -# without requiring an Ada compiler. In the meantime, temporarily -# force the language to Ada. - -gdb_test_no_output "set lang ada" - -# Verify that setting a breakpoint on `pck__foo__bar__minsym' only -# results in one location found (function pck__foo__bar__minsym__2). -# A mistake would be to also insert a breakpoint where -# pck__foo__bar__minsym is defined. Despite the fact that there is -# no debugging info available, this is a data symbol and thus should -# not be used for breakpoint purposes. - -gdb_test "break pck__foo__bar__minsym" \ +# Verify that setting a breakpoint on `test_minsym' only results in +# one location found. A mistake would be to also insert a breakpoint +# in the test_minsym data symbol in dmsym.c. Despite the fact that +# there is no debugging info available, this is a data symbol and thus +# should not be used for breakpoint purposes. + +gdb_test "break test_minsym" \ "Breakpoint $num at $addr.: file .*dmsym_main\\.c, line $num\\." # However, verify that the `info line' command, on the other hand, # finds both locations. -gdb_test "info line pck__foo__bar__minsym" \ - "Line $num of \".*dmsym_main\\.c\" .*\r\nNo line number information available for address $addr <pck__foo__bar__minsym>" - -gdb_test_no_output "set lang auto" +gdb_test "info line test_minsym" \ + "Line $num of \".*dmsym_main\\.c\" .*\r\nNo line number information available for address $addr <test_minsym>" -# Now, run the program until we get past the call to -# pck__foo__bar__minsym__2. Except when using hardware breakpoints, -# inferior behavior is going to be affected if a breakpoint was -# incorrectly inserted at pck__foo__bar__minsym. +# Now, run the program until we get past the call to test_minsym. +# Except when using hardware breakpoints, inferior behavior is going +# to be affected if a breakpoint was incorrectly inserted at +# test_minsym. gdb_breakpoint dmsym_main.c:[gdb_get_line_number "BREAK" dmsym_main.c] gdb_run_cmd gdb_test "" \ - "Breakpoint $num, pck__foo__bar__minsym__2 \\(\\) at.*" \ + "Breakpoint $num, test_minsym \\(\\) at.*" \ "run until breakpoint at BREAK" gdb_test "continue" \ diff --git a/gdb/testsuite/gdb.base/dmsym_main.c b/gdb/testsuite/gdb.base/dmsym_main.c index 99589b8..0338dc7 100644 --- a/gdb/testsuite/gdb.base/dmsym_main.c +++ b/gdb/testsuite/gdb.base/dmsym_main.c @@ -15,18 +15,18 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -extern int get_pck__foo__bar__minsym (void); +extern int get_test_minsym (void); -int -pck__foo__bar__minsym__2 (void) +static int +test_minsym (void) { - return get_pck__foo__bar__minsym (); + return get_test_minsym (); } int main (void) { - int val = pck__foo__bar__minsym__2 (); + int val = test_minsym (); if (val != 124) /* BREAK */ return 1; diff --git a/gdb/testsuite/gdb.base/environ.exp b/gdb/testsuite/gdb.base/environ.exp index 0b69a80..bb52063 100644 --- a/gdb/testsuite/gdb.base/environ.exp +++ b/gdb/testsuite/gdb.base/environ.exp @@ -46,6 +46,9 @@ gdb_test "unset environment" "" "unset all environment variables" \ "Delete all environment variables. .y or n. $" \ "y" +gdb_test_no_output "show environment" \ + "all environment variables have been unset" + # Verify that we can set a specific environment variable. test_set_show_env_var "EDITOR" "emacs" "set environment variable" diff --git a/gdb/testsuite/gdb.base/printcmds.exp b/gdb/testsuite/gdb.base/printcmds.exp index d949b30..9409c6a 100644 --- a/gdb/testsuite/gdb.base/printcmds.exp +++ b/gdb/testsuite/gdb.base/printcmds.exp @@ -155,6 +155,16 @@ proc test_float_rejected {} { test_print_reject "p 1.1ll" } +# Regression test for PR gdb/21675 +proc test_radices {} { + gdb_test "print/o 16777211" " = 077777773" + gdb_test "print/d 1.5" " = 1" + gdb_test "print/u 1.5" " = 1" + + gdb_test "print/u (char) -1" " = 255" + gdb_test "print/d (unsigned char) -1" " = -1" +} + proc test_print_all_chars {} { global gdb_prompt @@ -931,6 +941,12 @@ gdb_test "ptype \"abc\"" " = char \\\[4\\\]" gdb_test "print \$cvar = \"abc\"" " = \"abc\"" gdb_test "print sizeof (\$cvar)" " = 4" +# GDB used to complete the explicit location options even when +# printing expressions. +gdb_test_no_output "complete p -function" +gdb_test_no_output "complete p -line" +gdb_test_no_output "complete p -source" + gdb_file_cmd ${binfile} gdb_test "print \$pc" "No registers\\." "print \$pc (with file)" @@ -975,3 +991,4 @@ test_printf test_printf_with_dfp test_print_symbol test_repeat_bytes +test_radices diff --git a/gdb/testsuite/gdb.base/reread-readsym.c b/gdb/testsuite/gdb.base/reread-readsym.c new file mode 100644 index 0000000..2fee696 --- /dev/null +++ b/gdb/testsuite/gdb.base/reread-readsym.c @@ -0,0 +1,22 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2017 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +int +main (void) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.base/reread-readsym.exp b/gdb/testsuite/gdb.base/reread-readsym.exp new file mode 100644 index 0000000..b69eaad --- /dev/null +++ b/gdb/testsuite/gdb.base/reread-readsym.exp @@ -0,0 +1,61 @@ +# Copyright 2017 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +standard_testfile + +set gdbfile [standard_output_file ${testfile}.gdb] + +# Test rereading executable. See PR gdb/21337. + +proc generate_cmd_file {gdbfile binfile} { + set ofd [open $gdbfile w] + + puts $ofd "file ${binfile}" + puts $ofd "shell sleep 1; touch ${binfile}" + puts $ofd "run" + puts $ofd "file" + puts $ofd "file ${binfile}" + puts $ofd "shell sleep 1; touch ${binfile}" + puts $ofd "run" + puts $ofd "file" + puts $ofd "file ${binfile}" + puts $ofd "shell sleep 1; touch ${binfile}" + puts $ofd "run" + puts $ofd "file" + puts $ofd "p \"source-command-completed\"" + close $ofd +} + +if [use_gdb_stub] { + return 0 +} + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} { + return -1 +} + +# Start with a fresh gdb. +clean_restart ${testfile} + +# Using the source command to read commands from a file is important, +# otherwise section data is freed and reallocated using the same +# memory locations and the bug is not exposed. +generate_cmd_file $gdbfile $binfile + +gdb_test "source $gdbfile" ".*source-command-completed.*" \ + "source $testfile.gdb 1" +# Sometimes the failure only occurs on the second invocation. +gdb_test "source $gdbfile" ".*source-command-completed.*" \ + "source $testfile.gdb 2" diff --git a/gdb/testsuite/gdb.base/reread.exp b/gdb/testsuite/gdb.base/reread.exp index cc0f577..4e611ce 100644 --- a/gdb/testsuite/gdb.base/reread.exp +++ b/gdb/testsuite/gdb.base/reread.exp @@ -15,111 +15,131 @@ set prototypes 1 -# build the first test case +# Build programs in PIE mode, to reproduce PR 21555. +foreach_with_prefix opts { + { "" "" } + { "-fPIE" "ldflags=-pie" } } { -set testfile1 "reread1" -set srcfile1 ${testfile1}.c -# Cygwin needs $EXEEXT. -set binfile1 [standard_output_file ${testfile1}$EXEEXT] - -if { [gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${binfile1}" executable {debug nowarnings}] != "" } { - untested "failed to compile first testcase" - return -1 -} - -# build the second test case - -set testfile2 "reread2" -set srcfile2 ${testfile2}.c -set binfile2 [standard_output_file ${testfile2}$EXEEXT] - -if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {debug nowarnings}] != "" - && [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {debug nowarnings additional_flags=-DNO_SECTIONS}] != ""} { - untested "failed to compile second testcase" - return -1 -} - -# Start with a fresh gdb. - -set testfile "reread" -set binfile [standard_output_file ${testfile}$EXEEXT] - -gdb_start -gdb_reinitialize_dir $srcdir/$subdir - -# Load the first executable. - -gdb_rename_execfile ${binfile1} ${binfile} -gdb_load ${binfile} - -# Set a breakpoint at foo - -gdb_test "break foo" \ - "Breakpoint.*at.* file .*$srcfile1, line 14.*" \ - "breakpoint foo in first file" - - -# Run, should see "Breakpoint 1, foo () at hello1.c:14" - -gdb_run_cmd -gdb_test "" "Breakpoint.* foo .* at .*$srcfile1:14.*" "run to foo()" - -# Restore first executable to its original name, and move -# second executable into its place. Ensure that the new -# executable is at least a second newer than the old. - -gdb_rename_execfile ${binfile} ${binfile1} -gdb_rename_execfile ${binfile2} ${binfile} -gdb_test "shell sleep 1" ".*" "" -gdb_touch_execfile ${binfile} - -# Run a second time; GDB should detect that the executable has changed -# and reset the breakpoints correctly. -# Should see "Breakpoint 1, foo () at reread2.c:9" - -set test "run to foo() second time" -if [is_remote target] { - unsupported $test -} else { - gdb_run_cmd - gdb_test "" "Breakpoint.* foo .* at .*:9.*" $test -} - - -### Second pass: verify that GDB checks the executable file's -### timestamp when the program is *restarted*, not just when it exits. - -if [is_remote target] { - unsupported "second pass: GDB should check for changes before running" -} else { - - # Put the older executable back in place. - gdb_rename_execfile ${binfile} ${binfile2} - gdb_rename_execfile ${binfile1} ${binfile} - - # Restart GDB entirely. - clean_restart ${binfile} - - # Set a breakpoint on foo and run to it. - gdb_test "break foo" \ - "Breakpoint.*at.* file .*$srcfile1, line 14.*" \ - "second pass: breakpoint foo in first file" - gdb_run_cmd - gdb_test "" "Breakpoint.* foo .* at .*$srcfile1:14.*" "second pass: run to foo()" - - # This time, let the program run to completion. If GDB checks the - # executable file's timestamp now, it won't notice any change. - gdb_continue_to_end "second pass" - - # Now move the newer executable into place, and re-run. GDB - # should still notice that the executable file has changed, - # and still re-set the breakpoint appropriately. - gdb_rename_execfile ${binfile} ${binfile1} - gdb_rename_execfile ${binfile2} ${binfile} - gdb_run_cmd - gdb_test "" "Breakpoint.* foo .* at .*:9.*" "second pass: run to foo() second time" -} + # build the first test case + set testfile1 "reread1" + set srcfile1 ${testfile1}.c + # Cygwin needs $EXEEXT. + set binfile1 [standard_output_file ${testfile1}$EXEEXT] + + set testfile1_opt [list debug nowarnings \ + additional_flags=[lindex $opts 0] \ + [lindex $opts 1] ] + if { [gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${binfile1}" \ + executable ${testfile1_opt}] != "" } { + untested "failed to compile first testcase" + return -1 + } + + # build the second test case + + set testfile2 "reread2" + set srcfile2 ${testfile2}.c + set binfile2 [standard_output_file ${testfile2}$EXEEXT] + + set testfile2_opt1 [list debug nowarnings \ + additional_flags=[lindex $opts 0] \ + [lindex $opts 1]] + set testfile2_op2 [list debug nowarnings \ + "additional_flags=-DNO_SECTIONS [lindex $opts 0]" \ + [lindex $opts 1]] + if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" \ + executable ${testfile2_opt1}] != "" + && [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" \ + executable ${testfile2_opt2}] != ""} { + untested "failed to compile second testcase" + return -1 + } + + # Start with a fresh gdb. + + set testfile "reread" + set binfile [standard_output_file ${testfile}$EXEEXT] + + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + + # Load the first executable. + + gdb_rename_execfile ${binfile1} ${binfile} + gdb_load ${binfile} + + # Set a breakpoint at foo + + gdb_test "break foo" \ + "Breakpoint.*at.* file .*$srcfile1, line 14.*" \ + "breakpoint foo in first file" + + + # Run, should see "Breakpoint 1, foo () at hello1.c:14" + + gdb_run_cmd + gdb_test "" "Breakpoint.* foo .* at .*$srcfile1:14.*" "run to foo()" + + # Restore first executable to its original name, and move + # second executable into its place. Ensure that the new + # executable is at least a second newer than the old. + + gdb_rename_execfile ${binfile} ${binfile1} + gdb_rename_execfile ${binfile2} ${binfile} + gdb_test "shell sleep 1" ".*" "" + gdb_touch_execfile ${binfile} + + # Run a second time; GDB should detect that the executable has changed + # and reset the breakpoints correctly. + # Should see "Breakpoint 1, foo () at reread2.c:9" + + set test "run to foo() second time" + if [is_remote target] { + unsupported $test + } else { + gdb_run_cmd + gdb_test "" "Breakpoint.* foo .* at .*:9.*" $test + } + + + ### Second pass: verify that GDB checks the executable file's + ### timestamp when the program is *restarted*, not just when it exits. + + if [is_remote target] { + unsupported "second pass: GDB should check for changes before running" + } else { + + # Put the older executable back in place. + gdb_rename_execfile ${binfile} ${binfile2} + gdb_rename_execfile ${binfile1} ${binfile} + + # Restart GDB entirely. + clean_restart ${binfile} + + # Set a breakpoint on foo and run to it. + gdb_test "break foo" \ + "Breakpoint.*at.* file .*$srcfile1, line 14.*" \ + "second pass: breakpoint foo in first file" + gdb_run_cmd + gdb_test "" "Breakpoint.* foo .* at .*$srcfile1:14.*" \ + "second pass: run to foo()" + + # This time, let the program run to completion. If GDB checks the + # executable file's timestamp now, it won't notice any change. + gdb_continue_to_end "second pass" + + # Now move the newer executable into place, and re-run. GDB + # should still notice that the executable file has changed, + # and still re-set the breakpoint appropriately. + gdb_rename_execfile ${binfile} ${binfile1} + gdb_rename_execfile ${binfile2} ${binfile} + gdb_run_cmd + gdb_test "" "Breakpoint.* foo .* at .*:9.*" \ + "second pass: run to foo() second time" + } + + } # End of tests. return 0 diff --git a/gdb/testsuite/gdb.base/sizeof.exp b/gdb/testsuite/gdb.base/sizeof.exp index d7ada65..5d89407 100644 --- a/gdb/testsuite/gdb.base/sizeof.exp +++ b/gdb/testsuite/gdb.base/sizeof.exp @@ -81,7 +81,7 @@ check_sizeof "long double" ${sizeof_long_double} proc check_valueof { exp val } { gdb_test "next" "" "" - gdb_test "p value" " = ${val}" "check valueof \"$exp\"" + gdb_test "p /d value" " = ${val}" "check valueof \"$exp\"" } # Check that GDB and the target agree over the sign of a character. diff --git a/gdb/testsuite/gdb.dlang/demangle.exp b/gdb/testsuite/gdb.dlang/demangle.exp index baf6d6f..fcb353a 100644 --- a/gdb/testsuite/gdb.dlang/demangle.exp +++ b/gdb/testsuite/gdb.dlang/demangle.exp @@ -146,7 +146,7 @@ proc test_d_demangling {} { test_demangling "_D8demangle4testFPFNdNfNaZaZv" "demangle.test(char() @property @safe pure function)" test_demangling "_D8demangle4test6__vtblZ" "vtable for demangle.test" - test_demangling "_D8demangle4test6__initZ" "demangle.test.init$" + test_demangling "_D8demangle4test6__initZ" "initializer for demangle.test" test_demangling "_D8demangle4test12__ModuleInfoZ" "ModuleInfo for demangle.test" test_demangling "_D8demangle4test7__ClassZ" "ClassInfo for demangle.test" test_demangling "_D8demangle4test11__InterfaceZ" "Interface for demangle.test" diff --git a/gdb/testsuite/gdb.dwarf2/fission-multi-cu.S b/gdb/testsuite/gdb.dwarf2/fission-multi-cu.S new file mode 100644 index 0000000..d09a7e5 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/fission-multi-cu.S @@ -0,0 +1,374 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2012-2017 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + This file was created by doing: + + clang fission-multi-cu*.c -g -fno-split-dwarf-inlining -emit-llvm -S -c + llvm-link fission-multi-cu*.ll -S -o fission-multi-cu.ll + clang-tot fission-multi-cu.ll -gsplit-dwarf -S + + and then massaging the output. +*/ + .text + .file "llvm-link" + .globl func + .p2align 4, 0x90 + .type func,@function +func: # @func +.Lfunc_begin0: + .file 1 "fission-multi-cu1.c" + .loc 1 20 0 # fission-multi-cu1.c:20:0 + .cfi_startproc +# BB#0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) + .loc 1 21 10 prologue_end # fission-multi-cu1.c:21:10 + movl -4(%rbp), %edi + .loc 1 21 14 is_stmt 0 # fission-multi-cu1.c:21:14 + addl $1, %edi + .loc 1 21 3 # fission-multi-cu1.c:21:3 + movl %edi, %eax + popq %rbp + retq +.Lfunc_end0: + .size func, .Lfunc_end0-func + .cfi_endproc + + .globl main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin1: + .file 2 "fission-multi-cu2.c" + .loc 2 23 0 is_stmt 1 # fission-multi-cu2.c:23:0 + .cfi_startproc +# BB#0: # %entry + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl $4294967295, %edi # imm = 0xFFFFFFFF + .loc 2 24 3 prologue_end # fission-multi-cu2.c:24:3 + movb $0, %al + callq func + xorl %eax, %eax + .loc 2 25 1 # fission-multi-cu2.c:25:1 + popq %rbp + retq +.Lfunc_end1: + .size main, .Lfunc_end1-main + .cfi_endproc + + .section .debug_str,"MS",@progbits,1 +.Lskel_string0: + .asciz "fission-multi-cu.dwo" # string offset=0 +.Lskel_string1: + .asciz "/tmp/src/gdb/testsuite" # string offset=21 + .section .debug_loc.dwo,"",@progbits + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 0 # DW_CHILDREN_no + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .ascii "\260B" # DW_AT_GNU_dwo_name + .byte 14 # DW_FORM_strp + .byte 27 # DW_AT_comp_dir + .byte 14 # DW_FORM_strp + .ascii "\261B" # DW_AT_GNU_dwo_id + .byte 7 # DW_FORM_data8 + .ascii "\263B" # DW_AT_GNU_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long 44 # Length of Unit + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x25 DW_TAG_compile_unit + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Lskel_string0 # DW_AT_GNU_dwo_name + .long .Lskel_string1 # DW_AT_comp_dir + .quad 7615852067747431413 # DW_AT_GNU_dwo_id + .long .debug_addr # DW_AT_GNU_addr_base + .quad .Lfunc_begin0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc +.Lcu_begin1: + .long 44 # Length of Unit + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x25 DW_TAG_compile_unit + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Lskel_string0 # DW_AT_GNU_dwo_name + .long .Lskel_string1 # DW_AT_comp_dir + .quad 2037650261599692324 # DW_AT_GNU_dwo_id + .long .debug_addr # DW_AT_GNU_addr_base + .quad .Lfunc_begin1 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc + .section .debug_ranges,"",@progbits + .section .debug_macinfo,"",@progbits +.Lcu_macro_begin1: +.Lcu_macro_begin3: + .byte 0 # End Of Macro List Mark + .section .debug_str.dwo,"MS",@progbits,1 +.Linfo_string0: + .asciz "fission-multi-cu.dwo" # string offset=0 +.Linfo_string1: + .asciz "clang version 5.0.0 (trunk 302855) (llvm/trunk 302853)" # string offset=21 +.Linfo_string2: + .asciz "fission-multi-cu1.c" # string offset=76 +.Linfo_string3: + .asciz "fission-multi-cu2.c" # string offset=96 +.Linfo_string4: + .asciz "func" # string offset=116 +.Linfo_string5: + .asciz "int" # string offset=121 +.Linfo_string6: + .asciz "main" # string offset=125 +.Linfo_string7: + .asciz "arg" # string offset=130 + .section .debug_str_offsets.dwo,"",@progbits + .long 0 + .long 21 + .long 76 + .long 96 + .long 116 + .long 121 + .long 125 + .long 130 + .section .debug_info.dwo,"",@progbits + .long 53 # Length of Unit + .short 4 # DWARF version number + .long 0 # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x2e DW_TAG_compile_unit + .byte 0 # DW_AT_GNU_dwo_name + .byte 1 # DW_AT_producer + .short 12 # DW_AT_language + .byte 2 # DW_AT_name + .quad 7615852067747431413 # DW_AT_GNU_dwo_id + .byte 2 # Abbrev [2] 0x19:0x1b DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 4 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 19 # DW_AT_decl_line + # DW_AT_prototyped + .long 52 # DW_AT_type + # DW_AT_external + .byte 3 # Abbrev [3] 0x28:0xb DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 124 + .byte 7 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 19 # DW_AT_decl_line + .long 52 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x34:0x4 DW_TAG_base_type + .byte 5 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark + .long 41 # Length of Unit + .short 4 # DWARF version number + .long 0 # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x22 DW_TAG_compile_unit + .byte 0 # DW_AT_GNU_dwo_name + .byte 1 # DW_AT_producer + .short 12 # DW_AT_language + .byte 3 # DW_AT_name + .quad 2037650261599692324 # DW_AT_GNU_dwo_id + .byte 5 # Abbrev [5] 0x19:0xf DW_TAG_subprogram + .byte 1 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 6 # DW_AT_name + .byte 2 # DW_AT_decl_file + .byte 22 # DW_AT_decl_line + .long 40 # DW_AT_type + # DW_AT_external + .byte 4 # Abbrev [4] 0x28:0x4 DW_TAG_base_type + .byte 5 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark + .section .debug_abbrev.dwo,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .ascii "\260B" # DW_AT_GNU_dwo_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 37 # DW_AT_producer + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .ascii "\202>" # DW_FORM_GNU_str_index + .ascii "\261B" # DW_AT_GNU_dwo_id + .byte 7 # DW_FORM_data8 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .ascii "\201>" # DW_FORM_GNU_addr_index + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 39 # DW_AT_prototyped + .byte 25 # DW_FORM_flag_present + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 0 # DW_CHILDREN_no + .byte 17 # DW_AT_low_pc + .ascii "\201>" # DW_FORM_GNU_addr_index + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .ascii "\202>" # DW_FORM_GNU_str_index + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_line.dwo,"",@progbits +.Ltmp4: + .long (.Ltmp5-.Ltmp4)-4 + .short 2 + .long (.Ltmp6-.Ltmp4)-10 + .byte 1 + .byte 1 + .byte -5 + .byte 14 + .byte 1 + .byte 0 + .byte 0 +.Ltmp6: +.Ltmp5: + .section .debug_addr,"",@progbits + .quad .Lfunc_begin0 + .quad .Lfunc_begin1 + .section .debug_pubnames,"",@progbits + .long .LpubNames_end0-.LpubNames_begin0 # Length of Public Names Info +.LpubNames_begin0: + .short 2 # DWARF Version + .long .Lcu_begin0 # Offset of Compilation Unit Info + .long 48 # Compilation Unit Length + .long 25 # DIE offset + .asciz "func" # External Name + .long 0 # End Mark +.LpubNames_end0: + .long .LpubNames_end1-.LpubNames_begin1 # Length of Public Names Info +.LpubNames_begin1: + .short 2 # DWARF Version + .long .Lcu_begin1 # Offset of Compilation Unit Info + .long 48 # Compilation Unit Length + .long 25 # DIE offset + .asciz "main" # External Name + .long 0 # End Mark +.LpubNames_end1: + .section .debug_pubtypes,"",@progbits + .long .LpubTypes_end0-.LpubTypes_begin0 # Length of Public Types Info +.LpubTypes_begin0: + .short 2 # DWARF Version + .long .Lcu_begin0 # Offset of Compilation Unit Info + .long 48 # Compilation Unit Length + .long 52 # DIE offset + .asciz "int" # External Name + .long 0 # End Mark +.LpubTypes_end0: + .long .LpubTypes_end1-.LpubTypes_begin1 # Length of Public Types Info +.LpubTypes_begin1: + .short 2 # DWARF Version + .long .Lcu_begin1 # Offset of Compilation Unit Info + .long 48 # Compilation Unit Length + .long 40 # DIE offset + .asciz "int" # External Name + .long 0 # End Mark +.LpubTypes_end1: + + .ident "clang version 5.0.0 (trunk 302855) (llvm/trunk 302853)" + .ident "clang version 5.0.0 (trunk 302855) (llvm/trunk 302853)" + .section ".note.GNU-stack","",@progbits + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/gdb/testsuite/gdb.dwarf2/fission-multi-cu.exp b/gdb/testsuite/gdb.dwarf2/fission-multi-cu.exp new file mode 100644 index 0000000..1f23c5b6 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/fission-multi-cu.exp @@ -0,0 +1,67 @@ +# Copyright 2012-2017 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +load_lib dwarf.exp + +# We run objcopy locally to split out the .dwo file. +if [is_remote host] { + return 0 +} + +# This test can only be run on targets which support DWARF-2 and use gas. +if ![dwarf2_support] { + return 0 +} + +# This test can only be run on x86-64 targets. +if {![istarget x86_64-*] || ![is_lp64_target]} { + return 0 +} + +standard_testfile .S + +if [build_executable_from_fission_assembler \ + "$testfile.exp" "$binfile" "$srcfile" {nodebug}] { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +# Make sure we can find the .dwo file, regardless of whether we're +# running in parallel mode. +gdb_test_no_output "set debug-file-directory [file dirname $binfile]" \ + "set debug-file-directory" +gdb_load $binfile + +if ![runto_main] { + return -1 +} + +# Do a few basic things to verify we're finding the DWO debug info. + +gdb_test "ptype main" "type = int \\(\\)" +gdb_test "ptype func" "type = int \\(int\\)" + +gdb_test "frame" "#0 *main \\(\\) at ${testfile}2\\.c:$decimal.*" \ + "frame in main" + +gdb_test "break func" "Breakpoint.*at.* file .*${testfile}1\\.c, line .*" + +gdb_test "continue" "Breakpoint.* func \\(arg=-1\\).*" \ + "continue to func" + +gdb_test "frame" "#0 *func \\(arg=-1\\) at ${testfile}1\\.c:$decimal.*" \ + "frame in func" diff --git a/gdb/testsuite/gdb.dwarf2/fission-multi-cu1.c b/gdb/testsuite/gdb.dwarf2/fission-multi-cu1.c new file mode 100644 index 0000000..d93e2f9 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/fission-multi-cu1.c @@ -0,0 +1,22 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2012-2017 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +int +func (int arg) +{ + return arg + 1; +} diff --git a/gdb/testsuite/gdb.dwarf2/fission-multi-cu2.c b/gdb/testsuite/gdb.dwarf2/fission-multi-cu2.c new file mode 100644 index 0000000..053b3ea --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/fission-multi-cu2.c @@ -0,0 +1,24 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2012-2017 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +void func (); + +int +main () +{ + func (-1); +} diff --git a/gdb/testsuite/gdb.dwarf2/shortpiece.exp b/gdb/testsuite/gdb.dwarf2/shortpiece.exp new file mode 100644 index 0000000..8526a70 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/shortpiece.exp @@ -0,0 +1,100 @@ +# Copyright 2017 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +if {![dwarf2_support]} { + return 0 +} + +standard_testfile main.c shortpiece-dw.S + +# Make some DWARF for the test. +set asm_file [standard_output_file $srcfile2] +Dwarf::assemble $asm_file { + global pair + + cu { addr_size 4 } { + compile_unit {} { + declare_labels int_label ushort_label struct_label + + int_label: DW_TAG_base_type { + {DW_AT_byte_size 4 DW_FORM_udata} + {DW_AT_encoding @DW_ATE_unsigned} + {DW_AT_name "myint"} + } + ushort_label: DW_TAG_base_type { + {DW_AT_byte_size 2 DW_FORM_udata} + {DW_AT_encoding @DW_ATE_unsigned} + {DW_AT_name "myushort"} + } + + struct_label: DW_TAG_structure_type { + {DW_AT_name "S"} + {DW_AT_byte_size 8 DW_FORM_udata} + } { + DW_TAG_member { + {DW_AT_name "a"} + {DW_AT_type :${int_label}} + {DW_AT_data_member_location 0 DW_FORM_udata} + } + + DW_TAG_member { + {DW_AT_name "b"} + {DW_AT_type :${ushort_label}} + {DW_AT_data_member_location 4 DW_FORM_udata} + } + } + + DW_TAG_variable { + {DW_AT_name "s1"} + {DW_AT_type :${struct_label}} + {DW_AT_external 1 DW_FORM_flag} + {DW_AT_location { + DW_OP_constu 1 + DW_OP_stack_value + DW_OP_piece 4 + DW_OP_constu 0 + DW_OP_stack_value + DW_OP_piece 2 + } SPECIAL_expr} + } + + DW_TAG_variable { + {DW_AT_name "s2"} + {DW_AT_type :${struct_label}} + {DW_AT_external 1 DW_FORM_flag} + {DW_AT_location { + DW_OP_constu 1 + DW_OP_stack_value + DW_OP_piece 4 + DW_OP_constu 0 + DW_OP_stack_value + DW_OP_piece 8 + } SPECIAL_expr} + } + } + } +} + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile $asm_file] {nodebug}] } { + return -1 +} + +gdb_test "p s1" " = {a = 1, b = 0}" +gdb_test "p s2" \ + "access outside bounds of object referenced via synthetic pointer" diff --git a/gdb/testsuite/gdb.dwarf2/var-access.exp b/gdb/testsuite/gdb.dwarf2/var-access.exp index 8ebad6a..9180c88 100644 --- a/gdb/testsuite/gdb.dwarf2/var-access.exp +++ b/gdb/testsuite/gdb.dwarf2/var-access.exp @@ -282,16 +282,16 @@ gdb_test_no_output "set var \$[lindex $regname 0] = 81" \ "init reg for s2.a" gdb_test_no_output "set var \$[lindex $regname 1] = 28" \ "init reg for s2.c" -gdb_test "print/d s2" " = \\{a = 81, b = 4, c = 28, d = 5\\}" \ +gdb_test "print/u s2" " = \\{a = 81, b = 4, c = 28, d = 5\\}" \ "initialized s2 from mem and regs" gdb_test_no_output "set var s2.c += s2.a + s2.b - s2.d" -gdb_test "print/d s2" " = \\{a = 81, b = 4, c = 108, d = 5\\}" \ +gdb_test "print/u s2" " = \\{a = 81, b = 4, c = 108, d = 5\\}" \ "verify s2.c" -gdb_test "print/d \$[lindex $regname 1]" " = 108" \ +gdb_test "print/u \$[lindex $regname 1]" " = 108" \ "verify s2.c through reg" gdb_test_no_output "set var s2 = {191, 73, 231, 123}" \ "re-initialize s2" -gdb_test "print/d s2" " = \\{a = 191, b = 73, c = 231, d = 123\\}" \ +gdb_test "print/u s2" " = \\{a = 191, b = 73, c = 231, d = 123\\}" \ "verify re-initialized s2" # Unaligned bitfield access through byte-aligned pieces. diff --git a/gdb/testsuite/gdb.gdb/unittest.exp b/gdb/testsuite/gdb.gdb/unittest.exp index d6fc3de..c3e36e6 100644 --- a/gdb/testsuite/gdb.gdb/unittest.exp +++ b/gdb/testsuite/gdb.gdb/unittest.exp @@ -15,3 +15,8 @@ gdb_start gdb_test "maintenance selftest" "Ran $decimal unit tests, 0 failed" + +if { ![is_remote host] } { + gdb_test "maintenance check xml-descriptions ${srcdir}/../features" \ + "Tested $decimal XML files, 0 failed" +} diff --git a/gdb/testsuite/gdb.linespec/base/one/thefile.cc b/gdb/testsuite/gdb.linespec/base/one/thefile.cc index 0417b7a..34bc547 100644 --- a/gdb/testsuite/gdb.linespec/base/one/thefile.cc +++ b/gdb/testsuite/gdb.linespec/base/one/thefile.cc @@ -23,3 +23,8 @@ int NameSpace::overload(int x) { return x + 23; } + +int z1 () +{ + return 0; +} diff --git a/gdb/testsuite/gdb.linespec/base/two/thefile.cc b/gdb/testsuite/gdb.linespec/base/two/thefile.cc index 88188a5..264ae97 100644 --- a/gdb/testsuite/gdb.linespec/base/two/thefile.cc +++ b/gdb/testsuite/gdb.linespec/base/two/thefile.cc @@ -24,3 +24,8 @@ int NameSpace::overload(double x) { return (int) x - 23; } + +int z2 () +{ + return 0; +} diff --git a/gdb/testsuite/gdb.linespec/linespec.exp b/gdb/testsuite/gdb.linespec/linespec.exp index ccb73c8..b30ac10 100644 --- a/gdb/testsuite/gdb.linespec/linespec.exp +++ b/gdb/testsuite/gdb.linespec/linespec.exp @@ -43,6 +43,9 @@ if {$l1 != $l2} { error "somebody incompatibly modified the source files needed by linespec.exp" } +gdb_test_no_output "set breakpoint pending off" \ + "disable pending breakpoints for linespec tests" + # Copying files to a remote host loses the directory prefix during # compilation. if { [is_remote host] } { @@ -55,6 +58,93 @@ if { [is_remote host] } { gdb_test "clear one/thefile.cc:$l1" \ "Deleted breakpoint $decimal *" \ "clear breakpoint using dir/file:line" + + if { [readline_is_used] } { + # There are functions named 'twodup' in both source files. + # Both should be found if we restrict the linespec to the + # ambiguous "thefile.cc" source filename. Check both + # completion and setting the breakpoint. + set tst "complete unique function name in two source files" + send_gdb "break thefile.cc:t\t" + gdb_test_multiple "" $tst { + -re "break thefile.cc:twodup\\(\\) " { + pass $tst + + send_gdb "\n" + gdb_test "" \ + "Breakpoint $decimal at $hex: thefile.cc:twodup\\(\\). \[(\]2 locations\[)\]" \ + "set break at unique function name in two source files" + } + } + + # Check both completing and setting a breakpoint on a linespec + # with a source component, where there's more than one source + # file with the same basename. We should find the functions + # in all matching sources -- one/thefile.cc and + # two/thefile.cc. The "one" file has "z1()", while the "two" + # file has "z2()". + set tst "complete non-unique function name in two source files" + send_gdb "break thefile.cc:z\t" + gdb_test_multiple "" $tst { + -re "break thefile.cc:z\\\x07" { + send_gdb "\t" + gdb_test_multiple "" $tst { + -re "\r\nz1\\(\\)\[ \t\]+z2\\(\\)\[ \t\]+\r\n$gdb_prompt " { + pass $tst + + send_gdb "\n" + gdb_test "" \ + "Function \"z\" not defined in \"thefile.cc\"." \ + "set break at non-unique function name in two source files" + } + } + } + } + + # Now check that disambiguating the source path makes GDB only + # match the symbols in that file. "z" should now have a + # unique completion to "z1()", and setting the breakpoint + # should find only one location. + set tst "complete unique function name in disambiguated source file" + send_gdb "break one/thefile.cc:z\t" + gdb_test_multiple "" $tst { + -re "break one/thefile.cc:z1\\(\\) " { + pass $tst + + send_gdb "\n" + gdb_test "" \ + "Breakpoint $decimal at $hex: file .*thefile.cc, line \[^\r\n\]*" \ + "set break at unique function name in disambiguated source file" + } + } + + # Check that using a non-existing source path does not confuse + # GDB. It should not match any symbol. + set dir_file "one/thefile.cc" + set non_existing "/some/non-existing/absolute/path/prefix/$dir_file" + set non_existing_re [string_to_regexp $non_existing] + + set tst "complete functions in non-existing absolute path" + send_gdb "break $non_existing:\t" + gdb_test_multiple "" $tst { + -re "break $non_existing_re:\\\x07" { + send_gdb "\t\t" + gdb_test_multiple "" $tst { + -re "^\\\x07\\\x07" { + pass $tst + + # There's a function called 'twodup' in each + # of the thefile.cc files. Make sure none is + # picked. + send_gdb "twodup\n" + gdb_test "" \ + "No source file named $non_existing_re." \ + "set break in function in non-existing absolute path" + } + } + } + } + } } gdb_test "break thefile.cc:$l1" \ @@ -73,9 +163,6 @@ gdb_test "break dupname:label" \ # not the locations. gdb_test "complete condition " "condition $decimal\r\ncondition $decimal\r\ncondition $decimal" -gdb_test_no_output "set breakpoint pending off" \ - "disable pending breakpoints for linespec tests" - # This is PR breakpoints/12856. gdb_test "break lspec.cc:nosuchfunction" \ "Function \"nosuchfunction\" not defined in \"lspec.cc\"." \ diff --git a/gdb/testsuite/gdb.linespec/ls-errs.exp b/gdb/testsuite/gdb.linespec/ls-errs.exp index 1f78ca6..f55cd0e 100644 --- a/gdb/testsuite/gdb.linespec/ls-errs.exp +++ b/gdb/testsuite/gdb.linespec/ls-errs.exp @@ -96,8 +96,13 @@ proc do_test {lang} { } # Some commonly used whitespace tests around ':'. - set spaces [list ":" ": " " :" " : " "\t: " " :\t" "\t:\t" \ - " \t:\t " "\t \t:\t \t \t"] + set spaces [list \ + ":" \ + ": " \ + " :" \ + " : " \ + " : " \ + ] # A list of invalid offsets. set invalid_offsets [list -100 +500 1000] @@ -167,11 +172,14 @@ proc do_test {lang} { test_break "-source $x -line 3" invalid_file [string trim $x \"'] } - # Test that option lexing stops at whitespace boundaries + # Test that option lexing stops at whitespace boundaries, except + # when lexing function names, where we want to handle setting + # breakpoints on e.g., "int template_function<int>()". test_break "-source this file has spaces.c -line 3" invalid_file "this" - test_break "-function function whitespace" invalid_function "function" - test_break "-source $srcfile -function function whitespace" \ - invalid_function_f "function" $srcfile + test_break "-function ret_type tmpl_function" \ + invalid_function "ret_type tmpl_function" + test_break "-source $srcfile -function ret_type tmpl_function" \ + invalid_function_f "ret_type tmpl_function" $srcfile test_break "-function main -label label whitespace" \ invalid_label "label" "main" @@ -232,7 +240,12 @@ proc do_test {lang} { foreach x {"3" "+100" "-100" "foo"} { test_break "main 3" invalid_function "main 3" test_break "-function \"main $x\"" invalid_function "main $x" - test_break "main:here $x" invalid_label "here $x" "main" + if {$x == "foo"} { + test_break "main:here $x" unexpected_opt "string" $x + } else { + test_break "main:here $x" unexpected_opt "number" $x + } + test_break "-function main -label \"here $x\"" \ invalid_label "here $x" "main" } diff --git a/gdb/testsuite/gdb.mi/mi-vla-fortran.exp b/gdb/testsuite/gdb.mi/mi-vla-fortran.exp index b81165e..11ac532 100644 --- a/gdb/testsuite/gdb.mi/mi-vla-fortran.exp +++ b/gdb/testsuite/gdb.mi/mi-vla-fortran.exp @@ -37,14 +37,14 @@ mi_gdb_reinitialize_dir $srcdir/$subdir mi_gdb_load ${binfile} set bp_lineno [gdb_get_line_number "vla1-not-allocated"] -mi_create_breakpoint "-t vla.f90:$bp_lineno" 1 "del" "vla" \ - ".*vla.f90" $bp_lineno $hex \ - "insert breakpoint at line $bp_lineno (vla not allocated)" +mi_create_breakpoint "-t vla.f90:$bp_lineno" \ + "insert breakpoint at line $bp_lineno (vla not allocated)" \ + -number 1 -disp del -func vla ".*vla.f90" $bp_lineno $hex mi_run_cmd mi_expect_stop "breakpoint-hit" "vla" "" ".*vla.f90" "$bp_lineno" \ { "" "disp=\"del\"" } "run to breakpoint at line $bp_lineno" mi_gdb_test "500-data-evaluate-expression vla1" \ - "500\\^done,value=\"<not allocated>\"" "evaluate not allocated vla" + "500\\^done,value=\"<not allocated>\"" "evaluate not allocated vla, before allocation" mi_create_varobj_checked vla1_not_allocated vla1 "<not allocated>" \ "create local variable vla1_not_allocated" @@ -63,8 +63,9 @@ mi_list_array_varobj_children_with_index "vla1_not_allocated" "0" "1" \ set bp_lineno [gdb_get_line_number "vla1-allocated"] -mi_create_breakpoint "-t vla.f90:$bp_lineno" 2 "del" "vla" ".*vla.f90" \ - $bp_lineno $hex "insert breakpoint at line $bp_lineno (vla allocated)" +mi_create_breakpoint "-t vla.f90:$bp_lineno" \ + "insert breakpoint at line $bp_lineno (vla allocated)" \ + -number 2 -disp del -func vla ".*vla.f90" $bp_lineno $hex mi_run_cmd mi_expect_stop "breakpoint-hit" "vla" "" ".*vla.f90" "$bp_lineno" \ { "" "disp=\"del\"" } "run to breakpoint at line $bp_lineno" @@ -87,44 +88,48 @@ mi_list_array_varobj_children_with_index "vla1_allocated" "5" "1" \ set bp_lineno [gdb_get_line_number "vla1-filled"] -mi_create_breakpoint "-t vla.f90:$bp_lineno" 3 "del" "vla" ".*vla.f90" \ - $bp_lineno $hex "insert breakpoint at line $bp_lineno" +mi_create_breakpoint "-t vla.f90:$bp_lineno" \ + "insert breakpoint at line $bp_lineno" \ + -number 3 -disp del -func vla ".*vla.f90" $bp_lineno $hex mi_run_cmd mi_expect_stop "breakpoint-hit" "vla" "" ".*vla.f90" "$bp_lineno" \ { "" "disp=\"del\"" } "run to breakpoint at line $bp_lineno" mi_gdb_test "520-data-evaluate-expression vla1" \ - "520\\^done,value=\"\\(1, 1, 1, 1, 1\\)\"" "evaluate filled vla" + "520\\^done,value=\"\\(1, 1, 1, 1, 1\\)\"" "evaluate filled vla, filled all 1s" set bp_lineno [gdb_get_line_number "vla1-modified"] -mi_create_breakpoint "-t vla.f90:$bp_lineno" 4 "del" "vla" ".*vla.f90" \ - $bp_lineno $hex "insert breakpoint at line $bp_lineno" +mi_create_breakpoint "-t vla.f90:$bp_lineno" \ + "insert breakpoint at line $bp_lineno" \ + -number 4 -disp del -func vla ".*vla.f90" $bp_lineno $hex mi_run_cmd mi_expect_stop "breakpoint-hit" "vla" "" ".*vla.f90" "$bp_lineno" \ { "" "disp=\"del\"" } "run to breakpoint at line $bp_lineno" mi_gdb_test "530-data-evaluate-expression vla1" \ - "530\\^done,value=\"\\(1, 42, 1, 24, 1\\)\"" "evaluate filled vla" + "530\\^done,value=\"\\(1, 42, 1, 24, 1\\)\"" "evaluate filled vla, contents modified" mi_gdb_test "540-data-evaluate-expression vla1(1)" \ - "540\\^done,value=\"1\"" "evaluate filled vla" + "540\\^done,value=\"1\"" "evaluate filled vla(1)" mi_gdb_test "550-data-evaluate-expression vla1(2)" \ - "550\\^done,value=\"42\"" "evaluate filled vla" + "550\\^done,value=\"42\"" "evaluate filled vla(2)" mi_gdb_test "560-data-evaluate-expression vla1(4)" \ - "560\\^done,value=\"24\"" "evaluate filled vla" + "560\\^done,value=\"24\"" "evaluate filled vla(4)" set bp_lineno [gdb_get_line_number "vla1-deallocated"] -mi_create_breakpoint "-t vla.f90:$bp_lineno" 5 "del" "vla" ".*vla.f90" \ - $bp_lineno $hex "insert breakpoint at line $bp_lineno" +mi_create_breakpoint "-t vla.f90:$bp_lineno" \ + "insert breakpoint at line $bp_lineno" \ + -number 5 -disp del -func vla ".*vla.f90" $bp_lineno $hex mi_run_cmd mi_expect_stop "breakpoint-hit" "vla" "" ".*vla.f90" "$bp_lineno" \ { "" "disp=\"del\"" } "run to breakpoint at line $bp_lineno" mi_gdb_test "570-data-evaluate-expression vla1" \ - "570\\^done,value=\"<not allocated>\"" "evaluate not allocated vla" + "570\\^done,value=\"<not allocated>\"" "evaluate not allocated vla, after deallocation" set bp_lineno [gdb_get_line_number "pvla2-not-associated"] -mi_create_breakpoint "-t vla.f90:$bp_lineno" 6 "del" "vla" ".*vla.f90" \ - $bp_lineno $hex "insert breakpoint at line $bp_lineno" +mi_create_breakpoint "-t vla.f90:$bp_lineno" \ + "insert breakpoint at line $bp_lineno" \ + -number 6 -disp "del" -func "vla" ".*vla.f90" $bp_lineno $hex mi_run_cmd mi_expect_stop "breakpoint-hit" "vla" "" ".*vla.f90" "$bp_lineno" \ { "" "disp=\"del\"" } "run to breakpoint at line $bp_lineno" @@ -163,8 +168,9 @@ gdb_expect { } set bp_lineno [gdb_get_line_number "pvla2-associated"] -mi_create_breakpoint "-t vla.f90:$bp_lineno" 7 "del" "vla" ".*vla.f90" \ - $bp_lineno $hex "insert breakpoint at line $bp_lineno" +mi_create_breakpoint "-t vla.f90:$bp_lineno" \ + "insert breakpoint at line $bp_lineno" \ + -number 7 -disp del -func vla ".*vla.f90" $bp_lineno $hex mi_run_cmd mi_expect_stop "breakpoint-hit" "vla" "" ".*vla.f90" "$bp_lineno" \ { "" "disp=\"del\"" } "run to breakpoint at line $bp_lineno" @@ -186,8 +192,9 @@ mi_gdb_test "593-var-evaluate-expression pvla2_associated" \ set bp_lineno [gdb_get_line_number "pvla2-set-to-null"] -mi_create_breakpoint "-t vla.f90:$bp_lineno" 8 "del" "vla" ".*vla.f90" \ - $bp_lineno $hex "insert breakpoint at line $bp_lineno" +mi_create_breakpoint "-t vla.f90:$bp_lineno" \ + "insert breakpoint at line $bp_lineno" \ + -number 8 -disp del -func vla ".*vla.f90" $bp_lineno $hex mi_run_cmd mi_expect_stop "breakpoint-hit" "vla" "" ".*vla.f90" "$bp_lineno" \ { "" "disp=\"del\"" } "run to breakpoint at line $bp_lineno" diff --git a/gdb/testsuite/gdb.python/py-cmd.exp b/gdb/testsuite/gdb.python/py-cmd.exp index 2dbf23ce..953d52a 100644 --- a/gdb/testsuite/gdb.python/py-cmd.exp +++ b/gdb/testsuite/gdb.python/py-cmd.exp @@ -181,6 +181,71 @@ gdb_test "complete expr_test bar\." \ "expr_test bar\.bc.*expr_test bar\.ij.*" \ "test completion through complete command" +# Test that the "python" command is correctly recognized as +# inline/multi-line when entering a sequence of commands. +# +# This proc tests PR cli/21688. The PR is not language-specific, but +# the easiest way is just to test with Python. +proc test_python_inline_or_multiline { } { + global gdb_prompt + + set define_cmd_not_inline { + { "if 1" " >$" "multi-line if 1" } + { "python" " >$" "multi-line python command" } + { "print ('hello')" " >$" "multi-line print" } + { "end" " >$" "multi-line first end" } + { "end" "hello\r\n" "multi-line last end" } } + + # This also tests trailing whitespace on the command. + set define_cmd_alias_not_inline { + { "if 1" " >$" "multi-line if 1 alias" } + { "py " " >$" "multi-line python command alias" } + { "print ('hello')" " >$" "multi-line print alias" } + { "end" " >$" "multi-line first end alias" } + { "end" "hello\r\n" "multi-line last end alias" } } + + set define_cmd_alias_foo_not_inline { + { "alias foo=python" "\r\n" "multi-line alias foo" } + { "if 1" " >$" "multi-line if 1 alias foo" } + { "foo " " >$" "multi-line python command alias foo" } + { "print ('hello')" " >$" "multi-line print alias foo" } + { "end" " >$" "multi-line first end alias foo" } + { "end" "hello\r\n" "multi-line last end alias foo" } } + + set define_cmd_inline { + { "if 1" " >$" "inline if 1" } + { "python print ('hello')" " >$" "inline python command" } + { "end" "hello\r\n" "inline end" } } + + set define_cmd_alias_inline { + { "if 1" " >$" "inline if 1 alias" } + { "py print ('hello')" " >$" "inline python command alias" } + { "end" "hello\r\n" "inline end alias" } } + + set define_cmd_alias_foo_inline { + { "if 1" " >$" "inline if 1 alias foo" } + { "foo print ('hello')" " >$" "inline python command alias foo" } + { "end" "hello\r\n" "inline end alias foo" } } + + foreach t [list $define_cmd_not_inline \ + $define_cmd_alias_not_inline \ + $define_cmd_alias_foo_not_inline \ + $define_cmd_inline \ + $define_cmd_alias_inline \ + $define_cmd_alias_foo_inline] { + foreach l $t { + lassign $l command regex testmsg + gdb_test_multiple "$command" "$testmsg" { + -re "$regex" { + pass "$testmsg" + } + } + } + } +} + +test_python_inline_or_multiline + if { [readline_is_used] } { set test "complete 'expr_test bar.i'" send_gdb "expr_test bar\.i\t\t" diff --git a/gdb/testsuite/gdb.python/py-unwind.exp b/gdb/testsuite/gdb.python/py-unwind.exp index 0a4d34f..86e695c 100644 --- a/gdb/testsuite/gdb.python/py-unwind.exp +++ b/gdb/testsuite/gdb.python/py-unwind.exp @@ -20,7 +20,12 @@ load_lib gdb-python.exp standard_testfile -if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { +# Stack protection can make the stack look a bit different, breaking the +# assumptions this test has about its layout. + +set flags "additional_flags=-fno-stack-protector" + +if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} "debug $flags"] } { return -1 } @@ -51,4 +56,5 @@ gdb_test_sequence "where" "Backtrace restored by unwinder" { "\\r\\n#2 .* main \\(.*\\) at" } - +# Check that the Python unwinder frames can be flushed / released. +gdb_test "flushregs" "Register cache flushed\\." "flush frames" diff --git a/gdb/testsuite/gdb.rust/simple.exp b/gdb/testsuite/gdb.rust/simple.exp index 872b22c..403a11b 100644 --- a/gdb/testsuite/gdb.rust/simple.exp +++ b/gdb/testsuite/gdb.rust/simple.exp @@ -135,6 +135,9 @@ gdb_test "print simple::ByeBob\{field1: 0xff, field2:5\}" \ gdb_test "print simple::HiBob(0xff, 5)" \ "Type simple::HiBob is not a tuple struct" +gdb_test "print sizeof(simple::HiBob)" " = \[0-9\]+" +gdb_test "print simple::HiBob + 5" \ + "Found type 'simple::HiBob', which can't be evaluated in this context" gdb_test "print nosuchsymbol" \ "No symbol 'nosuchsymbol' in current context" @@ -194,14 +197,14 @@ gdb_test "print 5.." " = .*::ops::RangeFrom.* \\{start: 5\\}" gdb_test "print .." " = .*::ops::RangeFull" gdb_test "print str_some" \ - " = core::option::Option<collections::string::String>::Some\\(collections::string::String .*" -gdb_test "print str_none" " = core::option::Option<collections::string::String>::None" + " = core::option::Option<\[a-z\]+::string::String>::Some\\(\[a-z\]+::string::String .*" +gdb_test "print str_none" " = core::option::Option<\[a-z\]+::string::String>::None" gdb_test "print int_some" " = core::option::Option::Some\\(1\\)" gdb_test "print int_none" " = core::option::Option::None" gdb_test "print box_some" " = core::option::Option<\[a-z:\]*Box<u8>>::Some\\(.*\\)" gdb_test "print box_none" " = core::option::Option<\[a-z:\]*Box<u8>>::None" gdb_test "print custom_some" \ - " = simple::NonZeroOptimized::Value\\(collections::string::String .*" + " = simple::NonZeroOptimized::Value\\(\[a-z\]+::string::String .*" gdb_test "print custom_none" " = simple::NonZeroOptimized::Empty" proc test_one_slice {svar length base range} { @@ -246,3 +249,11 @@ gdb_test "print parametrized.next.val" \ " = \\(simple::ParametrizedStruct<i32> \\*\\) $hex" gdb_test "print parametrized" \ " = simple::ParametrizedStruct<i32> \\{next: simple::ParametrizedEnum<\[a-z:\]*Box<simple::ParametrizedStruct<i32>>>::Val\\{val: $hex\\}, value: 0\\}" + + +load_lib gdb-python.exp +if {[skip_python_tests]} { + continue +} + +gdb_test "python print(gdb.lookup_type('simple::HiBob'))" "simple::HiBob" diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 3d3eaab..c0ecab3 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -3368,6 +3368,34 @@ proc gdb_wrapper_init { args } { set gdb_wrapper_target [current_target_name] } +# Determine options that we always want to pass to the compiler. +gdb_caching_proc universal_compile_options { + set me "universal_compile_options" + set options {} + + set src [standard_temp_file ccopts[pid].c] + set obj [standard_temp_file ccopts[pid].o] + + gdb_produce_source $src { + int foo(void) { return 0; } + } + + # Try an option for disabling colored diagnostics. Some compilers + # yield colored diagnostics by default (when run from a tty) unless + # such an option is specified. + set opt "additional_flags=-fdiagnostics-color=never" + set lines [target_compile $src $obj object [list "quiet" $opt]] + if [string match "" $lines] then { + # Seems to have worked; use the option. + lappend options $opt + } + file delete $src + file delete $obj + + verbose "$me: returning $options" 2 + return $options +} + # Some targets need to always link a special object in. Save its path here. global gdb_saved_set_unbuffered_mode_obj set gdb_saved_set_unbuffered_mode_obj "" @@ -3419,7 +3447,7 @@ proc gdb_compile {source dest type options} { # Add platform-specific options if a shared library was specified using # "shlib=librarypath" in OPTIONS. - set new_options "" + set new_options [universal_compile_options] set shlib_found 0 set shlib_load 0 foreach opt $options { @@ -5537,7 +5565,7 @@ proc get_valueof { fmt exp default {test ""} } { set val ${default} gdb_test_multiple "print${fmt} ${exp}" "$test" { - -re "\\$\[0-9\]* = (.*)\[\r\n\]*$gdb_prompt $" { + -re "\\$\[0-9\]* = (\[^\r\n\]*)\[\r\n\]*$gdb_prompt $" { set val $expect_out(1,string) pass "$test ($val)" } @@ -129,10 +129,6 @@ show_confirm (struct ui_file *file, int from_tty, value); } -/* Flag to indicate whether a user defined command is currently running. */ - -int in_user_command; - /* Current working directory. */ char *current_directory; @@ -346,16 +342,16 @@ make_delete_ui_cleanup (struct ui *ui) /* Open file named NAME for read/write, making sure not to make it the controlling terminal. */ -static FILE * +static gdb_file_up open_terminal_stream (const char *name) { int fd; - fd = open (name, O_RDWR | O_NOCTTY); + fd = gdb_open_cloexec (name, O_RDWR | O_NOCTTY, 0); if (fd < 0) perror_with_name (_("opening terminal failed")); - return fdopen (fd, "w+"); + return gdb_file_up (fdopen (fd, "w+")); } /* Implementation of the "new-ui" command. */ @@ -365,21 +361,18 @@ new_ui_command (char *args, int from_tty) { struct ui *ui; struct interp *interp; - FILE *stream[3] = { NULL, NULL, NULL }; + gdb_file_up stream[3]; int i; int res; int argc; - char **argv; const char *interpreter_name; const char *tty_name; - struct cleanup *success_chain; struct cleanup *failure_chain; dont_repeat (); - argv = gdb_buildargv (args); - success_chain = make_cleanup_freeargv (argv); - argc = countargv (argv); + gdb_argv argv (args); + argc = argv.count (); if (argc < 2) error (_("usage: new-ui <interpreter> <tty>")); @@ -390,18 +383,13 @@ new_ui_command (char *args, int from_tty) { scoped_restore save_ui = make_scoped_restore (¤t_ui); - failure_chain = make_cleanup (null_cleanup, NULL); - /* Open specified terminal, once for each of stdin/stdout/stderr. */ for (i = 0; i < 3; i++) - { - stream[i] = open_terminal_stream (tty_name); - make_cleanup_fclose (stream[i]); - } + stream[i] = open_terminal_stream (tty_name); - ui = new_ui (stream[0], stream[1], stream[2]); - make_cleanup (delete_ui_cleanup, ui); + ui = new_ui (stream[0].get (), stream[1].get (), stream[2].get ()); + failure_chain = make_cleanup (delete_ui_cleanup, ui); ui->async = 1; @@ -411,10 +399,12 @@ new_ui_command (char *args, int from_tty) interp_pre_command_loop (top_level_interpreter ()); - discard_cleanups (failure_chain); + /* Make sure the files are not closed. */ + stream[0].release (); + stream[1].release (); + stream[2].release (); - /* This restores the previous UI and frees argv. */ - do_cleanups (success_chain); + discard_cleanups (failure_chain); } printf_unfiltered ("New UI allocated\n"); @@ -448,27 +438,14 @@ quit_cover (void) event-top.c into this file, top.c. */ /* static */ const char *source_file_name; -/* Clean up on error during a "source" command (or execution of a - user-defined command). */ - -void -do_restore_instream_cleanup (void *stream) -{ - struct ui *ui = current_ui; - - /* Restore the previous input stream. */ - ui->instream = (FILE *) stream; -} - /* Read commands from STREAM. */ void read_command_file (FILE *stream) { struct ui *ui = current_ui; - struct cleanup *cleanups; - cleanups = make_cleanup (do_restore_instream_cleanup, ui->instream); - ui->instream = stream; + scoped_restore save_instream + = make_scoped_restore (&ui->instream, stream); /* Read commands from `instream' and execute them until end of file or error reading instream. */ @@ -483,8 +460,6 @@ read_command_file (FILE *stream) break; command_handler (command); } - - do_cleanups (cleanups); } void (*pre_init_ui_hook) (void); @@ -2023,7 +1998,7 @@ init_main (void) /* Setup important stuff for command line editing. */ rl_completion_word_break_hook = gdb_completion_word_break_characters; - rl_completion_entry_function = readline_line_completion_function; + rl_attempted_completion_function = gdb_rl_attempted_completion_function; set_rl_completer_word_break_characters (default_word_break_characters ()); rl_completer_quote_characters = get_gdb_completer_quote_characters (); rl_completion_display_matches_hook = cli_display_match_list; @@ -218,7 +218,6 @@ extern void ui_unregister_input_event_handler (struct ui *ui); /* From top.c. */ extern char *saved_command_line; -extern int in_user_command; extern int confirm; extern char gdb_dirbuf[1024]; extern int inhibit_gdbinit; @@ -291,8 +290,6 @@ extern void show_history (char *, int); extern void set_verbose (char *, int, struct cmd_list_element *); -extern void do_restore_instream_cleanup (void *stream); - extern char *handle_line_of_input (struct buffer *cmd_line_buffer, char *rl, int repeat, const char *annotation_suffix); diff --git a/gdb/tracefile-tfile.c b/gdb/tracefile-tfile.c index d479cef..37bd96a 100644 --- a/gdb/tracefile-tfile.c +++ b/gdb/tracefile-tfile.c @@ -89,7 +89,7 @@ tfile_start (struct trace_file_writer *self, const char *filename) = (struct tfile_trace_file_writer *) self; writer->pathname = tilde_expand (filename); - writer->fp = gdb_fopen_cloexec (writer->pathname, "wb"); + writer->fp = gdb_fopen_cloexec (writer->pathname, "wb").release (); if (writer->fp == NULL) error (_("Unable to open file '%s' for saving trace data (%s)"), writer->pathname, safe_strerror (errno)); @@ -423,7 +423,6 @@ static void tfile_open (const char *arg, int from_tty) { char *temp; - struct cleanup *old_chain; int flags; int scratch_chan; char header[TRACE_HEADER_SIZE]; @@ -433,34 +432,27 @@ tfile_open (const char *arg, int from_tty) struct trace_status *ts; struct uploaded_tp *uploaded_tps = NULL; struct uploaded_tsv *uploaded_tsvs = NULL; - char *filename; target_preopen (from_tty); if (!arg) error (_("No trace file specified.")); - filename = tilde_expand (arg); - if (!IS_ABSOLUTE_PATH(filename)) - { - temp = concat (current_directory, "/", filename, (char *) NULL); - xfree (filename); - filename = temp; - } - - old_chain = make_cleanup (xfree, filename); + gdb::unique_xmalloc_ptr<char> filename (tilde_expand (arg)); + if (!IS_ABSOLUTE_PATH (filename.get ())) + filename.reset (concat (current_directory, "/", filename.get (), + (char *) NULL)); flags = O_BINARY | O_LARGEFILE; flags |= O_RDONLY; - scratch_chan = gdb_open_cloexec (filename, flags, 0); + scratch_chan = gdb_open_cloexec (filename.get (), flags, 0); if (scratch_chan < 0) - perror_with_name (filename); + perror_with_name (filename.get ()); /* Looks semi-reasonable. Toss the old trace file and work on the new. */ - discard_cleanups (old_chain); /* Don't free filename any more. */ unpush_target (&tfile_ops); - trace_filename = xstrdup (filename); + trace_filename = filename.release (); trace_fd = scratch_chan; /* Make sure this is clear. */ diff --git a/gdb/tracefile.c b/gdb/tracefile.c index e208fc6..8dde605 100644 --- a/gdb/tracefile.c +++ b/gdb/tracefile.c @@ -318,8 +318,8 @@ tsave_command (char *args, int from_tty) if (args == NULL) error_no_arg (_("file in which to save trace data")); - argv = gdb_buildargv (args); - back_to = make_cleanup_freeargv (argv); + gdb_argv built_argv (args); + argv = built_argv.get (); for (; *argv; ++argv) { @@ -341,7 +341,7 @@ tsave_command (char *args, int from_tty) else writer = tfile_trace_file_writer_new (); - make_cleanup (trace_file_writer_xfree, writer); + back_to = make_cleanup (trace_file_writer_xfree, writer); trace_save (filename, writer, target_does_save); diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index 4f2bac5..86acdbe 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -447,10 +447,6 @@ trace_variable_command (char *args, int from_tty) static void delete_trace_variable_command (char *args, int from_tty) { - int ix; - char **argv; - struct cleanup *back_to; - if (args == NULL) { if (query (_("Delete all trace state variables? "))) @@ -460,19 +456,16 @@ delete_trace_variable_command (char *args, int from_tty) return; } - argv = gdb_buildargv (args); - back_to = make_cleanup_freeargv (argv); + gdb_argv argv (args); - for (ix = 0; argv[ix] != NULL; ix++) + for (char *arg : argv) { - if (*argv[ix] == '$') - delete_trace_state_variable (argv[ix] + 1); + if (*arg == '$') + delete_trace_state_variable (arg + 1); else - warning (_("Name \"%s\" not prefixed with '$', ignoring"), argv[ix]); + warning (_("Name \"%s\" not prefixed with '$', ignoring"), arg); } - do_cleanups (back_to); - dont_repeat (); } @@ -482,7 +475,6 @@ tvariables_info_1 (void) struct trace_state_variable *tsv; int ix; int count = 0; - struct cleanup *back_to; struct ui_out *uiout = current_uiout; if (VEC_length (tsv_s, tvariables) == 0 && !uiout->is_mi_like_p ()) @@ -496,8 +488,7 @@ tvariables_info_1 (void) tsv->value_known = target_get_trace_state_variable_value (tsv->number, &(tsv->value)); - back_to = make_cleanup_ui_out_table_begin_end (uiout, 3, - count, "trace-variables"); + ui_out_emit_table table_emitter (uiout, 3, count, "trace-variables"); uiout->table_header (15, ui_left, "name", "Name"); uiout->table_header (11, ui_left, "initial", "Initial"); uiout->table_header (11, ui_left, "current", "Current"); @@ -531,8 +522,6 @@ tvariables_info_1 (void) uiout->field_string ("current", c); uiout->text ("\n"); } - - do_cleanups (back_to); } /* List all the trace state variables. */ @@ -3952,9 +3941,8 @@ info_static_tracepoint_markers_command (char *arg, int from_tty) don't work without in-process agent, so we don't bother users to type `set agent on' when to use static tracepoint. */ - old_chain - = make_cleanup_ui_out_table_begin_end (uiout, 5, -1, - "StaticTracepointMarkersTable"); + ui_out_emit_table table_emitter (uiout, 5, -1, + "StaticTracepointMarkersTable"); uiout->table_header (7, ui_left, "counter", "Cnt"); @@ -3970,7 +3958,7 @@ info_static_tracepoint_markers_command (char *arg, int from_tty) uiout->table_body (); markers = target_static_tracepoint_markers_by_strid (NULL); - make_cleanup (VEC_cleanup (static_tracepoint_marker_p), &markers); + old_chain = make_cleanup (VEC_cleanup (static_tracepoint_marker_p), &markers); for (i = 0; VEC_iterate (static_tracepoint_marker_p, diff --git a/gdb/tui/tui-layout.c b/gdb/tui/tui-layout.c index e52f789..7ecfaec 100644 --- a/gdb/tui/tui-layout.c +++ b/gdb/tui/tui-layout.c @@ -353,14 +353,15 @@ tui_default_win_viewport_height (enum tui_win_type type, /* Complete possible layout names. TEXT is the complete text entered so far, WORD is the word currently being completed. */ -static VEC (char_ptr) * +static void layout_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, const char *text, const char *word) { static const char *layout_names [] = { "src", "asm", "split", "regs", "next", "prev", NULL }; - return complete_on_enum (layout_names, text, word); + complete_on_enum (tracker, layout_names, text, word); } /* Function to initialize gdb commands, for tui window layout diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c index 3f9a007..217fff2 100644 --- a/gdb/tui/tui-regs.c +++ b/gdb/tui/tui-regs.c @@ -668,24 +668,23 @@ tui_reg_command (char *args, int from_tty) /* Complete names of register groups, and add the special "prev" and "next" names. */ -static VEC (char_ptr) * +static void tui_reggroup_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, const char *text, const char *word) { - VEC (char_ptr) *result = NULL; static const char *extra[] = { "next", "prev", NULL }; size_t len = strlen (word); const char **tmp; - result = reggroup_completer (ignore, text, word); + reggroup_completer (ignore, tracker, text, word); + /* XXXX use complete_on_enum instead? */ for (tmp = extra; *tmp != NULL; ++tmp) { if (strncmp (word, *tmp, len) == 0) - VEC_safe_push (char_ptr, result, xstrdup (*tmp)); + tracker.add_completion (gdb::unique_xmalloc_ptr<char> (xstrdup (*tmp))); } - - return result; } /* Provide a prototype to silence -Wmissing-prototypes. */ @@ -708,13 +707,6 @@ TUI command to control the register window."), tuicmd); ** STATIC LOCAL FUNCTIONS ** ******************************************/ -static void -tui_restore_gdbout (void *ui) -{ - gdb_stdout = (struct ui_file*) ui; - pagination_enabled = 1; -} - /* Get the register from the frame and return a printable representation of it. */ @@ -722,17 +714,14 @@ static char * tui_register_format (struct frame_info *frame, int regnum) { struct gdbarch *gdbarch = get_frame_arch (frame); - struct ui_file *old_stdout; - struct cleanup *cleanups; - char *p, *s; - char *ret; string_file stream; - pagination_enabled = 0; - old_stdout = gdb_stdout; - gdb_stdout = &stream; - cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout); + scoped_restore save_pagination + = make_scoped_restore (&pagination_enabled, 0); + scoped_restore save_stdout + = make_scoped_restore (&gdb_stdout, &stream); + gdbarch_print_registers_info (gdbarch, &stream, frame, regnum, 1); /* Remove the possible \n. */ @@ -741,11 +730,7 @@ tui_register_format (struct frame_info *frame, int regnum) str.resize (str.size () - 1); /* Expand tabs into spaces, since ncurses on MS-Windows doesn't. */ - ret = tui_expand_tabs (str.c_str (), 0); - - do_cleanups (cleanups); - - return ret; + return tui_expand_tabs (str.c_str (), 0); } /* Get the register value from the given frame and format it for the diff --git a/gdb/tui/tui-win.c b/gdb/tui/tui-win.c index f49d7d5..e0df667 100644 --- a/gdb/tui/tui-win.c +++ b/gdb/tui/tui-win.c @@ -359,12 +359,12 @@ tui_set_var_cmd (char *null_args, int from_tty, struct cmd_list_element *c) window names 'next' and 'prev' will also be considered as possible completions of the window name. */ -static VEC (char_ptr) * -window_name_completer (int include_next_prev_p, +static void +window_name_completer (completion_tracker &tracker, + int include_next_prev_p, const char *text, const char *word) { VEC (const_char_ptr) *completion_name_vec = NULL; - VEC (char_ptr) *matches_vec; int win_type; for (win_type = SRC_WIN; win_type < MAX_MAJOR_WINDOWS; win_type++) @@ -398,39 +398,39 @@ window_name_completer (int include_next_prev_p, } VEC_safe_push (const_char_ptr, completion_name_vec, NULL); - matches_vec - = complete_on_enum (VEC_address (const_char_ptr, completion_name_vec), - text, word); + complete_on_enum (tracker, + VEC_address (const_char_ptr, completion_name_vec), + text, word); VEC_free (const_char_ptr, completion_name_vec); - - return matches_vec; } /* Complete possible window names to focus on. TEXT is the complete text entered so far, WORD is the word currently being completed. */ -static VEC (char_ptr) * +static void focus_completer (struct cmd_list_element *ignore, - const char *text, const char *word) + completion_tracker &tracker, + const char *text, const char *word) { - return window_name_completer (1, text, word); + window_name_completer (tracker, 1, text, word); } /* Complete possible window names for winheight command. TEXT is the complete text entered so far, WORD is the word currently being completed. */ -static VEC (char_ptr) * +static void winheight_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, const char *text, const char *word) { /* The first word is the window name. That we can complete. Subsequent words can't be completed. */ if (word != text) - return NULL; + return; - return window_name_completer (0, text, word); + window_name_completer (tracker, 0, text, word); } /* Function to initialize gdb commands, for tui window diff --git a/gdb/ui-file.c b/gdb/ui-file.c index 60e3274..046e14f 100644 --- a/gdb/ui-file.c +++ b/gdb/ui-file.c @@ -177,12 +177,12 @@ stdio_file::open (const char *name, const char *mode) m_close_p = false; } - FILE *f = gdb_fopen_cloexec (name, mode); + gdb_file_up f = gdb_fopen_cloexec (name, mode); if (f == NULL) return false; - set_stream (f); + set_stream (f.release ()); m_close_p = true; return true; diff --git a/gdb/ui-out.h b/gdb/ui-out.h index 9278cab..857e252 100644 --- a/gdb/ui-out.h +++ b/gdb/ui-out.h @@ -220,4 +220,30 @@ private: typedef ui_out_emit_type<ui_out_type_tuple> ui_out_emit_tuple; typedef ui_out_emit_type<ui_out_type_list> ui_out_emit_list; +/* This is similar to make_cleanup_ui_out_table_begin_end, but written + as an RAII class. */ +class ui_out_emit_table +{ +public: + + ui_out_emit_table (struct ui_out *uiout, int nr_cols, int nr_rows, + const char *tblid) + : m_uiout (uiout) + { + m_uiout->table_begin (nr_cols, nr_rows, tblid); + } + + ~ui_out_emit_table () + { + m_uiout->table_end (); + } + + ui_out_emit_table (const ui_out_emit_table &) = delete; + ui_out_emit_table &operator= (const ui_out_emit_table &) = delete; + +private: + + struct ui_out *m_uiout; +}; + #endif /* UI_OUT_H */ diff --git a/gdb/utils.c b/gdb/utils.c index c110ef4..c00bfd4 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -66,6 +66,7 @@ #include "interps.h" #include "gdb_regex.h" #include "job-control.h" +#include "cp-support.h" #if !HAVE_DECL_MALLOC extern PTR malloc (); /* ARI: PTR */ @@ -136,54 +137,6 @@ show_pagination_enabled (struct ui_file *file, int from_tty, because while they use the "cleanup API" they are not part of the "cleanup API". */ -static void -do_freeargv (void *arg) -{ - freeargv ((char **) arg); -} - -struct cleanup * -make_cleanup_freeargv (char **arg) -{ - return make_cleanup (do_freeargv, arg); -} - -/* Helper function which does the work for make_cleanup_fclose. */ - -static void -do_fclose_cleanup (void *arg) -{ - FILE *file = (FILE *) arg; - - fclose (file); -} - -/* Return a new cleanup that closes FILE. */ - -struct cleanup * -make_cleanup_fclose (FILE *file) -{ - return make_cleanup (do_fclose_cleanup, file); -} - -/* Helper function which does the work for make_cleanup_obstack_free. */ - -static void -do_obstack_free (void *arg) -{ - struct obstack *ob = (struct obstack *) arg; - - obstack_free (ob, NULL); -} - -/* Return a new cleanup that frees OBSTACK. */ - -struct cleanup * -make_cleanup_obstack_free (struct obstack *obstack) -{ - return make_cleanup (do_obstack_free, obstack); -} - /* Helper function for make_cleanup_ui_out_redirect_pop. */ static void @@ -304,46 +257,6 @@ make_cleanup_value_free (struct value *value) return make_cleanup (do_value_free, value); } -/* Helper for make_cleanup_free_so. */ - -static void -do_free_so (void *arg) -{ - struct so_list *so = (struct so_list *) arg; - - free_so (so); -} - -/* Make cleanup handler calling free_so for SO. */ - -struct cleanup * -make_cleanup_free_so (struct so_list *so) -{ - return make_cleanup (do_free_so, so); -} - -/* Helper for make_cleanup_restore_current_language. */ - -static void -do_restore_current_language (void *p) -{ - enum language saved_lang = (enum language) (uintptr_t) p; - - set_language (saved_lang); -} - -/* Remember the current value of CURRENT_LANGUAGE and make it restored when - the cleanup is run. */ - -struct cleanup * -make_cleanup_restore_current_language (void) -{ - enum language saved_lang = current_language->la_language; - - return make_cleanup (do_restore_current_language, - (void *) (uintptr_t) saved_lang); -} - /* Helper function for make_cleanup_clear_parser_state. */ static void @@ -1277,13 +1190,10 @@ query (const char *ctlstr, ...) static int host_char_to_target (struct gdbarch *gdbarch, int c, int *target_c) { - struct obstack host_data; char the_char = c; - struct cleanup *cleanups; int result = 0; - obstack_init (&host_data); - cleanups = make_cleanup_obstack_free (&host_data); + auto_obstack host_data; convert_between_encodings (target_charset (gdbarch), host_charset (), (gdb_byte *) &the_char, 1, 1, @@ -1295,7 +1205,6 @@ host_char_to_target (struct gdbarch *gdbarch, int c, int *target_c) *target_c = *(char *) obstack_base (&host_data); } - do_cleanups (cleanups); return result; } @@ -2385,41 +2294,72 @@ fprintf_symbol_filtered (struct ui_file *stream, const char *name, } } -/* Do a strcmp() type operation on STRING1 and STRING2, ignoring any - differences in whitespace. Returns 0 if they match, non-zero if they - don't (slightly different than strcmp()'s range of return values). +/* Modes of operation for strncmp_iw_with_mode. */ - As an extra hack, string1=="FOO(ARGS)" matches string2=="FOO". - This "feature" is useful when searching for matching C++ function names - (such as if the user types 'break FOO', where FOO is a mangled C++ - function). */ +enum class strncmp_iw_mode +{ + /* Work like strncmp, while ignoring whitespace. */ + NORMAL, -int -strcmp_iw (const char *string1, const char *string2) + /* Like NORMAL, but also apply the strcmp_iw hack. I.e., + string1=="FOO(PARAMS)" matches string2=="FOO". */ + MATCH_PARAMS, +}; + +/* Helper for strncmp_iw and strcmp_iw. */ + +static int +strncmp_iw_with_mode (const char *string1, const char *string2, + size_t string2_len, strncmp_iw_mode mode) { - while ((*string1 != '\0') && (*string2 != '\0')) + const char *end_str2 = string2 + string2_len; + + while (1) { while (isspace (*string1)) - { - string1++; - } - while (isspace (*string2)) - { - string2++; - } + string1++; + while (string2 < end_str2 && isspace (*string2)) + string2++; + if (*string1 == '\0' || string2 == end_str2) + break; if (case_sensitivity == case_sensitive_on && *string1 != *string2) break; if (case_sensitivity == case_sensitive_off && (tolower ((unsigned char) *string1) != tolower ((unsigned char) *string2))) break; - if (*string1 != '\0') - { - string1++; - string2++; - } + + string1++; + string2++; } - return (*string1 != '\0' && *string1 != '(') || (*string2 != '\0'); + + if (string2 == end_str2) + { + if (mode == strncmp_iw_mode::NORMAL) + return 0; + else + return (*string1 != '\0' && *string1 != '('); + } + else + return 1; +} + +/* See utils.h. */ + +int +strncmp_iw (const char *string1, const char *string2, size_t string2_len) +{ + return strncmp_iw_with_mode (string1, string2, string2_len, + strncmp_iw_mode::NORMAL); +} + +/* See utils.h. */ + +int +strcmp_iw (const char *string1, const char *string2) +{ + return strncmp_iw_with_mode (string1, string2, strlen (string2), + strncmp_iw_mode::MATCH_PARAMS); } /* This is like strcmp except that it ignores whitespace and treats @@ -2912,19 +2852,18 @@ ldirname (const char *filename) return dirname; } -/* Call libiberty's buildargv, and return the result. - If buildargv fails due to out-of-memory, call nomem. - Therefore, the returned value is guaranteed to be non-NULL, - unless the parameter itself is NULL. */ +/* See utils.h. */ -char ** -gdb_buildargv (const char *s) +void +gdb_argv::reset (const char *s) { char **argv = buildargv (s); if (s != NULL && argv == NULL) malloc_failure (0); - return argv; + + freeargv (m_argv); + m_argv = argv; } int @@ -3367,6 +3306,47 @@ find_toplevel_char (const char *s, char c) depth++; else if ((*scan == ')' || *scan == '>') && depth > 0) depth--; + else if (*scan == 'o' && !quoted && depth == 0) + { + /* Handle C++ operator names. */ + if (strncmp (scan, CP_OPERATOR_STR, CP_OPERATOR_LEN) == 0) + { + scan += CP_OPERATOR_LEN; + if (*scan == c) + return scan; + while (isspace (*scan)) + { + ++scan; + if (*scan == c) + return scan; + } + if (*scan == '\0') + break; + + switch (*scan) + { + /* Skip over one less than the appropriate number of + characters: the for loop will skip over the last + one. */ + case '<': + if (scan[1] == '<') + { + scan++; + if (*scan == c) + return scan; + } + break; + case '>': + if (scan[1] == '>') + { + scan++; + if (*scan == c) + return scan; + } + break; + } + } + } } return 0; diff --git a/gdb/utils.h b/gdb/utils.h index 5e5033a..9516071 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -31,7 +31,24 @@ extern void initialize_utils (void); extern int sevenbit_strings; -extern int strcmp_iw (const char *, const char *); +/* Do a strncmp() type operation on STRING1 and STRING2, ignoring any + differences in whitespace. STRING2_LEN is STRING2's length. + Returns 0 if STRING1 matches STRING2_LEN characters of STRING2, + non-zero otherwise (slightly different than strncmp()'s range of + return values). */ +extern int strncmp_iw (const char *string1, const char *string2, + size_t string2_len); + +/* Do a strcmp() type operation on STRING1 and STRING2, ignoring any + differences in whitespace. Returns 0 if they match, non-zero if + they don't (slightly different than strcmp()'s range of return + values). + + As an extra hack, string1=="FOO(ARGS)" matches string2=="FOO". + This "feature" is useful when searching for matching C++ function + names (such as if the user types 'break FOO', where FOO is a + mangled C++ function). */ +extern int strcmp_iw (const char *string1, const char *string2); extern int strcmp_iw_ordered (const char *, const char *); @@ -42,6 +59,14 @@ extern int subset_compare (const char *, const char *); int compare_positive_ints (const void *ap, const void *bp); int compare_strings (const void *ap, const void *bp); +/* Compare C strings for std::sort. */ + +static inline bool +compare_cstrings (const char *str1, const char *str2) +{ + return strcmp (str1, str2) < 0; +} + /* A wrapper for bfd_errmsg to produce a more helpful error message in the case of bfd_error_file_ambiguously recognized. MATCHING, if non-NULL, is the corresponding argument to @@ -60,12 +85,126 @@ extern int parse_pid_to_attach (const char *args); extern int parse_escape (struct gdbarch *, const char **); -char **gdb_buildargv (const char *); +/* A wrapper for an array of char* that was allocated in the way that + 'buildargv' does, and should be freed with 'freeargv'. */ + +class gdb_argv +{ +public: + + /* A constructor that initializes to NULL. */ + + gdb_argv () + : m_argv (NULL) + { + } + + /* A constructor that calls buildargv on STR. STR may be NULL, in + which case this object is initialized with a NULL array. If + buildargv fails due to out-of-memory, call malloc_failure. + Therefore, the value is guaranteed to be non-NULL, unless the + parameter itself is NULL. */ + + explicit gdb_argv (const char *str) + : m_argv (NULL) + { + reset (str); + } + + /* A constructor that takes ownership of an existing array. */ + + explicit gdb_argv (char **array) + : m_argv (array) + { + } + + gdb_argv (const gdb_argv &) = delete; + gdb_argv &operator= (const gdb_argv &) = delete; + + ~gdb_argv () + { + freeargv (m_argv); + } + + /* Call buildargv on STR, storing the result in this object. Any + previous state is freed. STR may be NULL, in which case this + object is reset with a NULL array. If buildargv fails due to + out-of-memory, call malloc_failure. Therefore, the value is + guaranteed to be non-NULL, unless the parameter itself is + NULL. */ + + void reset (const char *str); + + /* Return the underlying array. */ + + char **get () + { + return m_argv; + } + + /* Return the underlying array, transferring ownership to the + caller. */ + + char **release () + { + char **result = m_argv; + m_argv = NULL; + return result; + } + + /* Return the number of items in the array. */ + + int count () const + { + return countargv (m_argv); + } + + /* Index into the array. */ + + char *operator[] (int arg) + { + gdb_assert (m_argv != NULL); + return m_argv[arg]; + } + + /* The iterator type. */ + + typedef char **iterator; + + /* Return an iterator pointing to the start of the array. */ + + iterator begin () + { + return m_argv; + } + + /* Return an iterator pointing to the end of the array. */ + + iterator end () + { + return m_argv + count (); + } + + bool operator!= (std::nullptr_t) + { + return m_argv != NULL; + } + + bool operator== (std::nullptr_t) + { + return m_argv == NULL; + } + +private: + + /* The wrapped array. */ + + char **m_argv; +}; + /* Cleanup utilities. */ -extern struct cleanup *make_cleanup_freeargv (char **); - struct ui_out; extern struct cleanup * make_cleanup_ui_out_redirect_pop (struct ui_out *uiout); @@ -76,11 +215,6 @@ extern struct cleanup *(make_cleanup_free_section_addr_info /* For make_cleanup_close see common/filestuff.h. */ -extern struct cleanup *make_cleanup_fclose (FILE *file); - -struct obstack; -extern struct cleanup *make_cleanup_obstack_free (struct obstack *obstack); - extern struct cleanup *make_cleanup_restore_integer (int *variable); extern struct cleanup *make_cleanup_restore_uinteger (unsigned int *variable); @@ -90,11 +224,6 @@ extern struct cleanup *make_cleanup_unpush_target (struct target_ops *ops); extern struct cleanup *make_cleanup_value_free_to_mark (struct value *); extern struct cleanup *make_cleanup_value_free (struct value *); -struct so_list; -extern struct cleanup *make_cleanup_free_so (struct so_list *so); - -extern struct cleanup *make_cleanup_restore_current_language (void); - /* A deleter for a hash table. */ struct htab_deleter { diff --git a/gdb/valarith.c b/gdb/valarith.c index 985233c..9724aca 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -697,12 +697,9 @@ value_concat (struct value *arg1, struct value *arg2) if (TYPE_CODE (type2) == TYPE_CODE_STRING || TYPE_CODE (type2) == TYPE_CODE_CHAR) { - struct cleanup *back_to; - count = longest_to_int (value_as_long (inval1)); inval2len = TYPE_LENGTH (type2); - ptr = (char *) xmalloc (count * inval2len); - back_to = make_cleanup (xfree, ptr); + std::vector<char> ptr (count * inval2len); if (TYPE_CODE (type2) == TYPE_CODE_CHAR) { char_type = type2; @@ -711,7 +708,7 @@ value_concat (struct value *arg1, struct value *arg2) value_contents (inval2)); for (idx = 0; idx < count; idx++) { - *(ptr + idx) = inchar; + ptr[idx] = inchar; } } else @@ -720,12 +717,11 @@ value_concat (struct value *arg1, struct value *arg2) for (idx = 0; idx < count; idx++) { - memcpy (ptr + (idx * inval2len), value_contents (inval2), + memcpy (&ptr[idx * inval2len], value_contents (inval2), inval2len); } } - outval = value_string (ptr, count * inval2len, char_type); - do_cleanups (back_to); + outval = value_string (ptr.data (), count * inval2len, char_type); } else if (TYPE_CODE (type2) == TYPE_CODE_BOOL) { @@ -739,8 +735,6 @@ value_concat (struct value *arg1, struct value *arg2) else if (TYPE_CODE (type1) == TYPE_CODE_STRING || TYPE_CODE (type1) == TYPE_CODE_CHAR) { - struct cleanup *back_to; - /* We have two character strings to concatenate. */ if (TYPE_CODE (type2) != TYPE_CODE_STRING && TYPE_CODE (type2) != TYPE_CODE_CHAR) @@ -749,31 +743,29 @@ value_concat (struct value *arg1, struct value *arg2) } inval1len = TYPE_LENGTH (type1); inval2len = TYPE_LENGTH (type2); - ptr = (char *) xmalloc (inval1len + inval2len); - back_to = make_cleanup (xfree, ptr); + std::vector<char> ptr (inval1len + inval2len); if (TYPE_CODE (type1) == TYPE_CODE_CHAR) { char_type = type1; - *ptr = (char) unpack_long (type1, value_contents (inval1)); + ptr[0] = (char) unpack_long (type1, value_contents (inval1)); } else { char_type = TYPE_TARGET_TYPE (type1); - memcpy (ptr, value_contents (inval1), inval1len); + memcpy (ptr.data (), value_contents (inval1), inval1len); } if (TYPE_CODE (type2) == TYPE_CODE_CHAR) { - *(ptr + inval1len) = + ptr[inval1len] = (char) unpack_long (type2, value_contents (inval2)); } else { - memcpy (ptr + inval1len, value_contents (inval2), inval2len); + memcpy (&ptr[inval1len], value_contents (inval2), inval2len); } - outval = value_string (ptr, inval1len + inval2len, char_type); - do_cleanups (back_to); + outval = value_string (ptr.data (), inval1len + inval2len, char_type); } else if (TYPE_CODE (type1) == TYPE_CODE_BOOL) { diff --git a/gdb/valops.c b/gdb/valops.c index 708b86c..ee19bc5 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -39,6 +39,7 @@ #include "observer.h" #include "objfiles.h" #include "extension.h" +#include "byte-vector.h" extern unsigned int overload_debug; /* Local functions. */ @@ -2084,24 +2085,20 @@ search_struct_method (const char *name, struct value **arg1p, if (offset < 0 || offset >= TYPE_LENGTH (type)) { - gdb_byte *tmp; - struct cleanup *back_to; CORE_ADDR address; - tmp = (gdb_byte *) xmalloc (TYPE_LENGTH (baseclass)); - back_to = make_cleanup (xfree, tmp); + gdb::byte_vector tmp (TYPE_LENGTH (baseclass)); address = value_address (*arg1p); if (target_read_memory (address + offset, - tmp, TYPE_LENGTH (baseclass)) != 0) + tmp.data (), TYPE_LENGTH (baseclass)) != 0) error (_("virtual baseclass botch")); base_val = value_from_contents_and_address (baseclass, - tmp, + tmp.data (), address + offset); base_valaddr = value_contents_for_printing (base_val); this_offset = 0; - do_cleanups (back_to); } else { diff --git a/gdb/valprint.c b/gdb/valprint.c index c10dade..eef99b1 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -1490,9 +1490,6 @@ void print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr, unsigned len, enum bfd_endian byte_order, bool zero_pad) { - -#define BITS_IN_BYTES 8 - const gdb_byte *p; unsigned int i; int b; @@ -1512,7 +1509,7 @@ print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr, /* Every byte has 8 binary characters; peel off and print from the MSB end. */ - for (i = 0; i < (BITS_IN_BYTES * sizeof (*p)); i++) + for (i = 0; i < (HOST_CHAR_BIT * sizeof (*p)); i++) { if (*p & (mask >> i)) b = '1'; @@ -1532,7 +1529,7 @@ print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr, p >= valaddr; p--) { - for (i = 0; i < (BITS_IN_BYTES * sizeof (*p)); i++) + for (i = 0; i < (HOST_CHAR_BIT * sizeof (*p)); i++) { if (*p & (mask >> i)) b = '1'; @@ -1593,20 +1590,26 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr, */ #define BITS_IN_OCTAL 3 #define HIGH_ZERO 0340 -#define LOW_ZERO 0016 +#define LOW_ZERO 0034 #define CARRY_ZERO 0003 + static_assert (HIGH_ZERO + LOW_ZERO + CARRY_ZERO == 0xff, + "cycle zero constants are wrong"); #define HIGH_ONE 0200 #define MID_ONE 0160 #define LOW_ONE 0016 #define CARRY_ONE 0001 + static_assert (HIGH_ONE + MID_ONE + LOW_ONE + CARRY_ONE == 0xff, + "cycle one constants are wrong"); #define HIGH_TWO 0300 #define MID_TWO 0070 #define LOW_TWO 0007 + static_assert (HIGH_TWO + MID_TWO + LOW_TWO == 0xff, + "cycle two constants are wrong"); /* For 32 we start in cycle 2, with two bits and one bit carry; for 64 in cycle in cycle 1, with one bit and a two bit carry. */ - cycle = (len * BITS_IN_BYTES) % BITS_IN_OCTAL; + cycle = (len * HOST_CHAR_BIT) % BITS_IN_OCTAL; carry = 0; fputs_filtered ("0", stream); @@ -2484,8 +2487,6 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream, { enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); - struct obstack wchar_buf, output; - struct cleanup *cleanups; gdb_byte *buf; int need_escape = 0; @@ -2495,8 +2496,7 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream, wchar_iterator iter (buf, TYPE_LENGTH (type), encoding, TYPE_LENGTH (type)); /* This holds the printable form of the wchar_t data. */ - obstack_init (&wchar_buf); - cleanups = make_cleanup_obstack_free (&wchar_buf); + auto_obstack wchar_buf; while (1) { @@ -2543,8 +2543,7 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream, } /* The output in the host encoding. */ - obstack_init (&output); - make_cleanup_obstack_free (&output); + auto_obstack output; convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (), (gdb_byte *) obstack_base (&wchar_buf), @@ -2553,8 +2552,6 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream, obstack_1grow (&output, '\0'); fputs_filtered ((const char *) obstack_base (&output), stream); - - do_cleanups (cleanups); } /* Return the repeat count of the next character/byte in ITER, @@ -2813,7 +2810,6 @@ generic_printstr (struct ui_file *stream, struct type *type, enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); unsigned int i; int width = TYPE_LENGTH (type); - struct obstack wchar_buf, output; struct cleanup *cleanup; int finished = 0; struct converted_character *last; @@ -2885,8 +2881,7 @@ generic_printstr (struct ui_file *stream, struct type *type, /* WCHAR_BUF is the obstack we use to represent the string in wchar_t form. */ - obstack_init (&wchar_buf); - make_cleanup_obstack_free (&wchar_buf); + auto_obstack wchar_buf; /* Print the output string to the obstack. */ print_converted_chars_to_obstack (&wchar_buf, converted_chars, quote_char, @@ -2896,8 +2891,7 @@ generic_printstr (struct ui_file *stream, struct type *type, obstack_grow_wstr (&wchar_buf, LCST ("...")); /* OUTPUT is where we collect `char's for printing. */ - obstack_init (&output); - make_cleanup_obstack_free (&output); + auto_obstack output; convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (), (gdb_byte *) obstack_base (&wchar_buf), diff --git a/gdb/value.c b/gdb/value.c index be01f0f..ec615b3 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -41,6 +41,7 @@ #include "cp-abi.h" #include "user-regs.h" #include <algorithm> +#include "completer.h" /* Prototypes for exported functions. */ @@ -2144,14 +2145,12 @@ lookup_only_internalvar (const char *name) return NULL; } -/* Complete NAME by comparing it to the names of internal variables. - Returns a vector of newly allocated strings, or NULL if no matches - were found. */ +/* Complete NAME by comparing it to the names of internal + variables. */ -VEC (char_ptr) * -complete_internalvar (const char *name) +void +complete_internalvar (completion_tracker &tracker, const char *name) { - VEC (char_ptr) *result = NULL; struct internalvar *var; int len; @@ -2160,12 +2159,10 @@ complete_internalvar (const char *name) for (var = internalvars; var; var = var->next) if (strncmp (var->name, name, len) == 0) { - char *r = xstrdup (var->name); + gdb::unique_xmalloc_ptr<char> copy (xstrdup (var->name)); - VEC_safe_push (char_ptr, result, r); + tracker.add_completion (std::move (copy)); } - - return result; } /* Create an internal variable with name NAME and with a void value. diff --git a/gdb/value.h b/gdb/value.h index 852ce60..e7334e0 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -927,7 +927,8 @@ extern struct internalvar *lookup_only_internalvar (const char *name); extern struct internalvar *create_internalvar (const char *name); -extern VEC (char_ptr) *complete_internalvar (const char *name); +extern void complete_internalvar (completion_tracker &tracker, + const char *name); /* An internalvar can be dynamically computed by supplying a vector of function pointers to perform various operations. */ diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c index 7362282..2c4afb1 100644 --- a/gdb/x86-linux-nat.c +++ b/gdb/x86-linux-nat.c @@ -153,7 +153,7 @@ x86_linux_read_description (struct target_ops *ops) { have_ptrace_getfpxregs = 0; have_ptrace_getregset = TRIBOOL_FALSE; - return tdesc_i386_mmx_linux; + return i386_linux_read_description (X86_XSTATE_X87_MASK); } } #endif @@ -230,21 +230,13 @@ x86_linux_read_description (struct target_ops *ops) } else { - switch (xcr0_features_bits) - { - case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK: - return tdesc_i386_avx_mpx_avx512_pku_linux; - case X86_XSTATE_AVX_AVX512_MASK: - return tdesc_i386_avx_avx512_linux; - case X86_XSTATE_MPX_MASK: - return tdesc_i386_mpx_linux; - case X86_XSTATE_AVX_MPX_MASK: - return tdesc_i386_avx_mpx_linux; - case X86_XSTATE_AVX_MASK: - return tdesc_i386_avx_linux; - default: - return tdesc_i386_linux; - } + const struct target_desc * tdesc + = i386_linux_read_description (xcr0_features_bits); + + if (tdesc == NULL) + tdesc = i386_linux_read_description (X86_XSTATE_SSE_MASK); + + return tdesc; } gdb_assert_not_reached ("failed to return tdesc"); diff --git a/gdb/xml-support.c b/gdb/xml-support.c index fff3997..65638b9 100644 --- a/gdb/xml-support.c +++ b/gdb/xml-support.c @@ -1001,7 +1001,7 @@ char * xml_fetch_content_from_file (const char *filename, void *baton) { const char *dirname = (const char *) baton; - FILE *file; + gdb_file_up file; struct cleanup *back_to; char *text; size_t len, offset; @@ -1021,21 +1021,19 @@ xml_fetch_content_from_file (const char *filename, void *baton) if (file == NULL) return NULL; - back_to = make_cleanup_fclose (file); - /* Read in the whole file, one chunk at a time. */ len = 4096; offset = 0; text = (char *) xmalloc (len); - make_cleanup (free_current_contents, &text); + back_to = make_cleanup (free_current_contents, &text); while (1) { size_t bytes_read; /* Continue reading where the last read left off. Leave at least one byte so that we can NUL-terminate the result. */ - bytes_read = fread (text + offset, 1, len - offset - 1, file); - if (ferror (file)) + bytes_read = fread (text + offset, 1, len - offset - 1, file.get ()); + if (ferror (file.get ())) { warning (_("Read error from \"%s\""), filename); do_cleanups (back_to); @@ -1044,14 +1042,13 @@ xml_fetch_content_from_file (const char *filename, void *baton) offset += bytes_read; - if (feof (file)) + if (feof (file.get ())) break; len = len * 2; text = (char *) xrealloc (text, len); } - fclose (file); discard_cleanups (back_to); text[offset] = '\0'; diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c index f875f20..bfb9ac6 100644 --- a/gdb/xtensa-tdep.c +++ b/gdb/xtensa-tdep.c @@ -740,17 +740,13 @@ static void xtensa_init_reggroups (void) { int i; - char cpname[] = "cp0"; xtensa_ar_reggroup = reggroup_new ("ar", USER_REGGROUP); xtensa_user_reggroup = reggroup_new ("user", USER_REGGROUP); xtensa_vectra_reggroup = reggroup_new ("vectra", USER_REGGROUP); for (i = 0; i < XTENSA_MAX_COPROCESSOR; i++) - { - cpname[2] = '0' + i; - xtensa_cp[i] = reggroup_new (cpname, USER_REGGROUP); - } + xtensa_cp[i] = reggroup_new (xstrprintf ("cp%d", i), USER_REGGROUP); } static void |