diff options
-rw-r--r-- | bfd/version.h | 2 | ||||
-rw-r--r-- | gdb/arch-utils.c | 7 | ||||
-rw-r--r-- | gdb/disasm.c | 7 | ||||
-rw-r--r-- | gdb/dwarf2/read.c | 29 | ||||
-rw-r--r-- | gdb/event-top.h | 25 | ||||
-rw-r--r-- | gdb/gdb_bfd.c | 23 | ||||
-rw-r--r-- | gdb/python/py-utils.c | 29 | ||||
-rw-r--r-- | gdb/solib-frv.c | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/default.exp | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/limited-length.c | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/limited-length.exp | 10 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/enum-type-c++.cc | 35 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/enum-type-c++.exp | 54 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/enum-type.exp | 35 | ||||
-rw-r--r-- | gdb/testsuite/gdb.python/sys-exit.exp | 69 | ||||
-rw-r--r-- | gdb/value.c | 9 | ||||
-rw-r--r-- | gdb/version.in | 2 | ||||
-rw-r--r-- | gdb/x86-linux-nat.c | 6 |
18 files changed, 304 insertions, 44 deletions
diff --git a/bfd/version.h b/bfd/version.h index b6800d3..c8e34f4 100644 --- a/bfd/version.h +++ b/bfd/version.h @@ -16,7 +16,7 @@ In releases, the date is not included in either version strings or sonames. */ -#define BFD_VERSION_DATE 20240721 +#define BFD_VERSION_DATE 20241001 #define BFD_VERSION @bfd_version@ #define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@ #define REPORT_BUGS_TO @report_bugs_to@ diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 83e2947..ccbfffc 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -37,6 +37,7 @@ #include "auxv.h" #include "observable.h" #include "solib-target.h" +#include "event-top.h" #include "gdbsupport/version.h" @@ -1040,7 +1041,11 @@ default_print_insn (bfd_vma memaddr, disassemble_info *info) info->mach, current_program_space->exec_bfd ()); gdb_assert (disassemble_fn != NULL); - return (*disassemble_fn) (memaddr, info); + int res = (*disassemble_fn) (memaddr, info); + + QUIT; + + return res; } /* See arch-utils.h. */ diff --git a/gdb/disasm.c b/gdb/disasm.c index 16736e5..7209cfc 100644 --- a/gdb/disasm.c +++ b/gdb/disasm.c @@ -197,7 +197,12 @@ gdb_disassembler_memory_reader::dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr, unsigned int len, struct disassemble_info *info) noexcept { - return target_read_code (memaddr, myaddr, len); + auto res = catch_exceptions<int, -1> ([&] + { + return target_read_code (memaddr, myaddr, len); + }); + + return res; } /* Wrapper of memory_error. */ diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 4818da5..b2b95c2 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -16440,12 +16440,6 @@ cooked_indexer::index_dies (cutu_reader *reader, flags &= ~IS_STATIC; flags |= parent_entry->flags & IS_STATIC; } - /* If the parent is an enum, but not an enum class, then use the - grandparent instead. */ - if (this_parent_entry != nullptr - && this_parent_entry->tag == DW_TAG_enumeration_type - && !is_enum_class) - this_parent_entry = this_parent_entry->get_parent (); if (abbrev->tag == DW_TAG_namespace && m_language == language_cplus @@ -16505,7 +16499,15 @@ cooked_indexer::index_dies (cutu_reader *reader, break; case DW_TAG_enumeration_type: - info_ptr = recurse (reader, info_ptr, this_entry, fully); + /* We need to recurse even for an anonymous enumeration. + Which scope we record as the parent scope depends on + whether we're reading an "enum class". If so, we use + the enum itself as the parent, yielding names like + "enum_class::enumerator"; otherwise we inject the + names into our own parent scope. */ + info_ptr = recurse (reader, info_ptr, + is_enum_class ? this_entry : parent_entry, + fully); continue; case DW_TAG_module: @@ -17914,8 +17916,8 @@ public: we're processing the end of a sequence. */ void record_line (bool end_sequence); - /* Check ADDRESS is -1, or zero and less than UNRELOCATED_LOWPC, and if true - nop-out rest of the lines in this sequence. */ + /* Check ADDRESS is -1, -2, or zero and less than UNRELOCATED_LOWPC, and if + true nop-out rest of the lines in this sequence. */ void check_line_address (struct dwarf2_cu *cu, const gdb_byte *line_ptr, unrelocated_addr unrelocated_lowpc, @@ -18325,13 +18327,16 @@ lnp_state_machine::check_line_address (struct dwarf2_cu *cu, unrelocated_addr unrelocated_lowpc, unrelocated_addr address) { - /* Linkers resolve a symbolic relocation referencing a GC'd function to 0 or - -1. If ADDRESS is 0, ignoring the opcode will err if the text section is + /* Linkers resolve a symbolic relocation referencing a GC'd function to 0, + -1 or -2 (-2 is used by certain lld versions, see + https://github.com/llvm/llvm-project/commit/e618ccbf431f6730edb6d1467a127c3a52fd57f7). + If ADDRESS is 0, ignoring the opcode will err if the text section is located at 0x0. In this case, additionally check that if ADDRESS < UNRELOCATED_LOWPC. */ if ((address == (unrelocated_addr) 0 && address < unrelocated_lowpc) - || address == (unrelocated_addr) -1) + || address == (unrelocated_addr) -1 + || address == (unrelocated_addr) -2) { /* This line table is for a function which has been GCd by the linker. Ignore it. PR gdb/12528 */ diff --git a/gdb/event-top.h b/gdb/event-top.h index 846d1e4..d590552 100644 --- a/gdb/event-top.h +++ b/gdb/event-top.h @@ -24,6 +24,8 @@ #include <signal.h> +#include "extension.h" + struct cmd_list_element; /* The current quit handler (and its type). This is called from the @@ -81,6 +83,29 @@ extern void quit_serial_event_set (); extern void quit_serial_event_clear (); +/* Wrap f (args) and handle exceptions by: + - returning val, and + - calling set_quit_flag or set_force_quit_flag, if needed. */ + +template <typename R, R val, typename F, typename... Args> +static R +catch_exceptions (F &&f, Args&&... args) +{ + try + { + return f (std::forward<Args> (args)...); + } + catch (const gdb_exception &ex) + { + if (ex.reason == RETURN_QUIT) + set_quit_flag (); + else if (ex.reason == RETURN_FORCED_QUIT) + set_force_quit_flag (); + } + + return val; +} + extern void display_gdb_prompt (const char *new_prompt); extern void gdb_setup_readline (int); extern void gdb_disable_readline (void); diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c index cb9a91d..80c706c 100644 --- a/gdb/gdb_bfd.c +++ b/gdb/gdb_bfd.c @@ -930,29 +930,6 @@ gdb_bfd_openw (const char *filename, const char *target) return gdb_bfd_ref_ptr::new_reference (result); } -/* Wrap f (args) and handle exceptions by: - - returning val, and - - calling set_quit_flag or set_force_quit_flag, if needed. */ - -template <typename R, R val, typename F, typename... Args> -static R -catch_exceptions (F &&f, Args&&... args) -{ - try - { - return f (std::forward<Args> (args)...); - } - catch (const gdb_exception &ex) - { - if (ex.reason == RETURN_QUIT) - set_quit_flag (); - else if (ex.reason == RETURN_FORCED_QUIT) - set_force_quit_flag (); - } - - return val; -} - /* See gdb_bfd.h. */ gdb_bfd_ref_ptr diff --git a/gdb/python/py-utils.c b/gdb/python/py-utils.c index 47f65f4..39ae9b5 100644 --- a/gdb/python/py-utils.c +++ b/gdb/python/py-utils.c @@ -390,6 +390,35 @@ gdbpy_handle_exception () if (fetched_error.type_matches (PyExc_KeyboardInterrupt)) throw_quit ("Quit"); + else if (fetched_error.type_matches (PyExc_SystemExit)) + { + gdbpy_ref<> value = fetched_error.value (); + gdbpy_ref<> code (PyObject_GetAttrString (value.get (), "code")); + int exit_arg; + + if (code.get () == Py_None) + { + /* CODE == None: exit status is 0. */ + exit_arg = 0; + } + else if (code.get () != nullptr && PyLong_Check (code.get ())) + { + /* CODE == integer: exit status is aforementioned integer. */ + exit_arg = PyLong_AsLong (code.get ()); + } + else + { + if (code.get () == nullptr) + gdbpy_print_stack (); + + /* Otherwise: exit status is 1, print code to stderr. */ + if (msg != nullptr) + gdb_printf (gdb_stderr, "%s\n", msg.get ()); + exit_arg = 1; + } + + quit_force (&exit_arg, 0); + } else if (! fetched_error.type_matches (gdbpy_gdberror_exc) || msg == NULL || *msg == '\0') { diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c index 39508fa..a4cd82d 100644 --- a/gdb/solib-frv.c +++ b/gdb/solib-frv.c @@ -382,6 +382,8 @@ frv_current_sos () li->map = loadmap; li->got_value = got_addr; li->lm_addr = lm_addr; + sop->lm_info = std::move (li); + /* Fetch the name. */ addr = extract_unsigned_integer (lm_buf.l_name, sizeof (lm_buf.l_name), diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp index 8f33121..4fb4f73 100644 --- a/gdb/testsuite/gdb.base/default.exp +++ b/gdb/testsuite/gdb.base/default.exp @@ -692,7 +692,7 @@ set show_conv_list \ {$_gdb_setting_str = <internal function _gdb_setting_str>} \ {$_gdb_setting = <internal function _gdb_setting>} \ {$_gdb_major = 15} \ - {$_gdb_minor = 2} \ + {$_gdb_minor = 3} \ {$_shell_exitsignal = void} \ {$_shell_exitcode = 0} \ } diff --git a/gdb/testsuite/gdb.base/limited-length.c b/gdb/testsuite/gdb.base/limited-length.c index 627c34d..c8ece16 100644 --- a/gdb/testsuite/gdb.base/limited-length.c +++ b/gdb/testsuite/gdb.base/limited-length.c @@ -41,6 +41,8 @@ int large_2d_array[][10] = { {90, 91, 92, 93, 94, 95, 96, 97, 98, 99} }; +char large_empty_string[100000] = ""; + int main () { diff --git a/gdb/testsuite/gdb.base/limited-length.exp b/gdb/testsuite/gdb.base/limited-length.exp index a24adcb..2d160e1 100644 --- a/gdb/testsuite/gdb.base/limited-length.exp +++ b/gdb/testsuite/gdb.base/limited-length.exp @@ -240,3 +240,13 @@ with_test_prefix "with unlimited print elements" { "value is not available" \ "output expression referring unavailable element from history" } + +gdb_test_no_output "set max-value-size 10000" +gdb_test_no_output "set print elements 200" + +gdb_test "print large_empty_string" \ + " = \\\{0 '\\\\000' <repeats 10000 times>, <unavailable> <repeats 90000 times>\\\}" \ + "print large empty string which is not fully available" +gdb_test -nonl "output large_empty_string" \ + "\\\{0 '\\\\000' <repeats 10000 times>, <unavailable> <repeats 90000 times>\\\}" \ + "output large empty string which is not fully available" diff --git a/gdb/testsuite/gdb.dwarf2/enum-type-c++.cc b/gdb/testsuite/gdb.dwarf2/enum-type-c++.cc new file mode 100644 index 0000000..691c7fc --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/enum-type-c++.cc @@ -0,0 +1,35 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +namespace ns { + +class A { +public: + enum { + val1 = 1 + }; +}; + +enum class ec +{ + val2 = 2, +}; +} + +int u1 = ns::A::val1; + +int u2 = (int)ns::ec::val2; diff --git a/gdb/testsuite/gdb.dwarf2/enum-type-c++.exp b/gdb/testsuite/gdb.dwarf2/enum-type-c++.exp new file mode 100644 index 0000000..8bf737e --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/enum-type-c++.exp @@ -0,0 +1,54 @@ +# Copyright 2024 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +require !readnow + +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +require dwarf2_support + +standard_testfile main.c .cc + +if { [prepare_for_testing "failed to prepare" $testfile \ + [list $srcfile $srcfile2] {debug c++}] } { + return -1 +} + +require {string equal [have_index $binfile] ""} + +set re_ws "\[ \t\]" + +# Regression test for PR31900. +set val1 ns::A::val1 +gdb_test_lines "maint print objfiles" \ + "val1 has a parent" \ + [multi_line \ + "" \ + "$re_ws+qualified:$re_ws+$val1" \ + ".*"] + +gdb_test "print $val1" " = $val1" + +# Regression test for PR32158. +set val2 ns::ec::val2 +gdb_test_lines "maint print objfiles" \ + "val2 has correct parent" \ + [multi_line \ + "" \ + "$re_ws+qualified:$re_ws+$val2" \ + ".*"] + +gdb_test "print $val2" " = $val2" diff --git a/gdb/testsuite/gdb.dwarf2/enum-type.exp b/gdb/testsuite/gdb.dwarf2/enum-type.exp index 394d287..b2b3dc6 100644 --- a/gdb/testsuite/gdb.dwarf2/enum-type.exp +++ b/gdb/testsuite/gdb.dwarf2/enum-type.exp @@ -65,6 +65,41 @@ Dwarf::assemble $asm_file { } } } + + cu {} { + DW_TAG_compile_unit { + {DW_AT_language @DW_LANG_C_plus_plus} + {DW_AT_name tmp.c} + {DW_AT_comp_dir /tmp} + } { + declare_labels integer_label forward + + integer_label: DW_TAG_base_type { + {DW_AT_byte_size 4 DW_FORM_sdata} + {DW_AT_encoding @DW_ATE_signed} + {DW_AT_name int} + } + + DW_TAG_enumeration_type { + {DW_AT_specification :$forward} + } { + DW_TAG_enumerator { + {DW_AT_name val1} + {DW_AT_const_value 1 DW_FORM_sdata} + } + } + + DW_TAG_namespace { + {DW_AT_name ns} + } { + forward: DW_TAG_enumeration_type { + {DW_AT_name e} + {DW_AT_type :$integer_label} + {DW_AT_declaration 1 flag} + } + } + } + } } if { [prepare_for_testing "failed to prepare" ${testfile} \ diff --git a/gdb/testsuite/gdb.python/sys-exit.exp b/gdb/testsuite/gdb.python/sys-exit.exp new file mode 100644 index 0000000..3396b8d --- /dev/null +++ b/gdb/testsuite/gdb.python/sys-exit.exp @@ -0,0 +1,69 @@ +# Copyright 2024 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Check that python sys.exit makes gdb exit, with the correct exit status. + +require allow_python_tests + +# Have this code in a proc avoids clashing with runtest variable exit_status. + +proc do_test { n {expected_exit_status ""} {msg ""}} { + if { $expected_exit_status == "" } { + set expected_exit_status $n + } + + with_test_prefix $n { + clean_restart + + # Regression test for PR python/31946. + set seen_message 0 + gdb_test_multiple "python sys.exit ($n)" "python sys.exit" { + -re "\r\n$msg\r\n" { + set seen_message 1 + exp_continue + } + eof { + set wait_status [wait -i $::gdb_spawn_id] + clear_gdb_spawn_id + + verbose -log "GDB process exited with wait status $wait_status" + + set os_error [lindex $wait_status 2] + set exit_status [lindex $wait_status 3] + + gdb_assert \ + { $os_error == 0 \ + && $exit_status == $expected_exit_status } \ + $gdb_test_name + + if { $msg != "" } { + gdb_assert { $seen_message } + } + } + } + } +} + +# Test sys.exit (<int>). +do_test 0 +do_test 1 +do_test 2 + +# Test sys.exit (None). +do_test None 0 + +# Test sys.exit (<string>). +do_test {"Error Message"} 1 "Error Message" +do_test {""} 1 diff --git a/gdb/value.c b/gdb/value.c index e71f38b..ede4313 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -1716,10 +1716,6 @@ value::record_latest () fetch_lazy (); } - ULONGEST limit = m_limited_length; - if (limit != 0) - mark_bytes_unavailable (limit, m_enclosing_type->length () - limit); - /* Mark the value as recorded in the history for the availability check. */ m_in_history = true; @@ -3931,6 +3927,11 @@ value::fetch_lazy_memory () if (len > 0) read_value_memory (this, 0, stack (), addr, contents_all_raw ().data (), len); + + /* If only part of an array was loaded, mark the rest as unavailable. */ + if (m_limited_length > 0) + mark_bytes_unavailable (m_limited_length, + m_enclosing_type->length () - m_limited_length); } /* See value.h. */ diff --git a/gdb/version.in b/gdb/version.in index b5bc579..f08d473 100644 --- a/gdb/version.in +++ b/gdb/version.in @@ -1 +1 @@ -15.1.90.DATE-git +15.2.90.DATE-git diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c index a3d8ffb..1214aa4 100644 --- a/gdb/x86-linux-nat.c +++ b/gdb/x86-linux-nat.c @@ -180,6 +180,12 @@ x86_linux_nat_target::read_description () xcr0 = xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET / sizeof (uint64_t))]; +#ifdef __x86_64__ + /* No MPX on x32. */ + if (is_x32) + xcr0 &= ~X86_XSTATE_MPX; +#endif + m_xsave_layout = x86_fetch_xsave_layout (xcr0, x86_xsave_length ()); } } |