diff options
Diffstat (limited to 'gdb')
391 files changed, 7546 insertions, 5760 deletions
diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 1c697bf..13f512f 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -746,6 +746,7 @@ ALL_64_TARGET_OBS = \ amd64-windows-tdep.o \ arch/aarch64.o \ arch/aarch64-insn.o \ + arch/aarch64-mte.o \ arch/aarch64-mte-linux.o \ arch/aarch64-scalable-linux.o \ arch/amd64-linux-tdesc.o \ @@ -831,7 +832,6 @@ ALL_TARGET_OBS = \ i386-go32-tdep.o \ i386-linux-tdep.o \ i386-netbsd-tdep.o \ - i386-nto-tdep.o \ i386-obsd-tdep.o \ i386-sol2-tdep.o \ i386-tdep.o \ @@ -859,7 +859,6 @@ ALL_TARGET_OBS = \ nds32-tdep.o \ nios2-linux-tdep.o \ nios2-tdep.o \ - nto-tdep.o \ obsd-tdep.o \ or1k-linux-tdep.o \ or1k-tdep.o \ @@ -1443,7 +1442,6 @@ HFILES_NO_SRCDIR = \ nds32-tdep.h \ nios2-tdep.h \ elf-none-tdep.h \ - nto-tdep.h \ objc-lang.h \ objfiles.h \ obsd-nat.h \ @@ -1551,6 +1549,7 @@ HFILES_NO_SRCDIR = \ arch/aarch32.h \ arch/aarch64.h \ arch/aarch64-insn.h \ + arch/aarch64-mte.h \ arch/aarch64-mte-linux.h \ arch/aarch64-scalable-linux.h \ arch/amd64-linux-tdesc.h \ @@ -1579,7 +1578,6 @@ HFILES_NO_SRCDIR = \ compile/gcc-c-plugin.h \ compile/gcc-cp-plugin.h \ config/nm-linux.h \ - config/nm-nto.h \ config/djgpp/langinfo.h \ config/djgpp/nl_types.h \ config/i386/nm-i386gnu.h \ @@ -1664,6 +1662,7 @@ ALLDEPFILES = \ arch/aarch32.c \ arch/aarch64.c \ arch/aarch64-insn.c \ + arch/aarch64-mte.c \ arch/aarch64-mte-linux.c \ arch/aarch64-scalable-linux.c \ arch/amd64.c \ @@ -3,16 +3,38 @@ *** Changes since GDB 15 +* GDB now supports printing of ptwrite payloads from the Intel Processor + Trace during 'record instruction-history', 'record function-call-history' + and all stepping commands. The payload is also accessible in Python as a + RecordAuxiliary object. Printing is customizable via a ptwrite filter + function in Python. By default, the raw ptwrite payload is printed for + each ptwrite that is encountered. + +* Python API + + ** Added gdb.record.clear. Clears the trace data of the current recording. + This forces re-decoding of the trace for successive commands. + * Debugger Adapter Protocol changes ** The "scopes" request will now return a scope holding global variables from the stack frame's compilation unit. + ** The "scopes" request will return a "returnValue" scope holding + the return value from the latest "stepOut" command, when + appropriate. + * For ARM targets, the offset of the pc in the jmp_buf has been fixed to match glibc 2.20 and later. This should only matter when not using libc probes. This may cause breakage when using an incompatible libc, like uclibc or newlib, or an older glibc. +* MTE (Memory Tagging Extension) debugging is now supported on AArch64 baremetal + targets. + +* Remove support (native and remote) for QNX Neutrino (triplet + `i[3456]86-*-nto*`). + *** Changes in GDB 15 * The MPX commands "show/set mpx bound" have been deprecated, as Intel @@ -224,6 +246,11 @@ qIsAddressTagged file is about, this new packet provides a more generic way to perform such a check. +vFile:stat + Return information about files on the remote system. Like + vFile:fstat but takes a filename rather than an open file + descriptor. + *** Changes in GDB 14 * GDB now supports the AArch64 Scalable Matrix Extension 2 (SME2), which diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c index 2e6541f..0fa5bee 100644 --- a/gdb/aarch64-linux-nat.c +++ b/gdb/aarch64-linux-nat.c @@ -496,12 +496,11 @@ fetch_tlsregs_from_thread (struct regcache *regcache) gdb_assert (regno != -1); gdb_assert (tdep->tls_register_count > 0); - uint64_t tpidrs[tdep->tls_register_count]; - memset(tpidrs, 0, sizeof(tpidrs)); + std::vector<uint64_t> tpidrs (tdep->tls_register_count); struct iovec iovec; - iovec.iov_base = tpidrs; - iovec.iov_len = sizeof (tpidrs); + iovec.iov_base = tpidrs.data (); + iovec.iov_len = tpidrs.size () * sizeof (tpidrs[0]); int tid = get_ptrace_pid (regcache->ptid ()); if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_TLS, &iovec) != 0) @@ -524,8 +523,7 @@ store_tlsregs_to_thread (struct regcache *regcache) gdb_assert (regno != -1); gdb_assert (tdep->tls_register_count > 0); - uint64_t tpidrs[tdep->tls_register_count]; - memset(tpidrs, 0, sizeof(tpidrs)); + std::vector<uint64_t> tpidrs (tdep->tls_register_count); for (int i = 0; i < tdep->tls_register_count; i++) { @@ -536,8 +534,8 @@ store_tlsregs_to_thread (struct regcache *regcache) } struct iovec iovec; - iovec.iov_base = &tpidrs; - iovec.iov_len = sizeof (tpidrs); + iovec.iov_base = tpidrs.data (); + iovec.iov_len = tpidrs.size () * sizeof (tpidrs[0]); int tid = get_ptrace_pid (regcache->ptid ()); if (ptrace (PTRACE_SETREGSET, tid, NT_ARM_TLS, &iovec) != 0) diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c index a1296a8..c608a84 100644 --- a/gdb/aarch64-linux-tdep.c +++ b/gdb/aarch64-linux-tdep.c @@ -48,6 +48,7 @@ #include "record-full.h" #include "linux-record.h" +#include "arch/aarch64-mte.h" #include "arch/aarch64-mte-linux.h" #include "arch/aarch64-scalable-linux.h" @@ -1297,8 +1298,7 @@ aarch64_linux_supply_za_regset (const struct regset *regset, } else { - gdb_byte za_zeroed[za_bytes]; - memset (za_zeroed, 0, za_bytes); + gdb::byte_vector za_zeroed (za_bytes, 0); regcache->raw_supply (tdep->sme_za_regnum, za_zeroed); } } @@ -2427,29 +2427,6 @@ aarch64_linux_gcc_target_options (struct gdbarch *gdbarch) return {}; } -/* Helper to get the allocation tag from a 64-bit ADDRESS. - - Return the allocation tag if successful and nullopt otherwise. */ - -static std::optional<CORE_ADDR> -aarch64_mte_get_atag (CORE_ADDR address) -{ - gdb::byte_vector tags; - - /* Attempt to fetch the allocation tag. */ - if (!target_fetch_memtags (address, 1, tags, - static_cast<int> (memtag_type::allocation))) - return {}; - - /* Only one tag should've been returned. Make sure we got exactly that. */ - if (tags.size () != 1) - error (_("Target returned an unexpected number of tags.")); - - /* Although our tags are 4 bits in size, they are stored in a - byte. */ - return tags[0]; -} - /* Implement the tagged_address_p gdbarch method. */ static bool @@ -2466,132 +2443,6 @@ aarch64_linux_tagged_address_p (struct gdbarch *gdbarch, CORE_ADDR address) return true; } -/* Implement the memtag_matches_p gdbarch method. */ - -static bool -aarch64_linux_memtag_matches_p (struct gdbarch *gdbarch, - struct value *address) -{ - gdb_assert (address != nullptr); - - CORE_ADDR addr = value_as_address (address); - - /* Fetch the allocation tag for ADDRESS. */ - std::optional<CORE_ADDR> atag - = aarch64_mte_get_atag (gdbarch_remove_non_address_bits (gdbarch, addr)); - - if (!atag.has_value ()) - return true; - - /* Fetch the logical tag for ADDRESS. */ - gdb_byte ltag = aarch64_mte_get_ltag (addr); - - /* Are the tags the same? */ - return ltag == *atag; -} - -/* Implement the set_memtags gdbarch method. */ - -static bool -aarch64_linux_set_memtags (struct gdbarch *gdbarch, struct value *address, - size_t length, const gdb::byte_vector &tags, - memtag_type tag_type) -{ - gdb_assert (!tags.empty ()); - gdb_assert (address != nullptr); - - CORE_ADDR addr = value_as_address (address); - - /* Set the logical tag or the allocation tag. */ - if (tag_type == memtag_type::logical) - { - /* When setting logical tags, we don't care about the length, since - we are only setting a single logical tag. */ - addr = aarch64_mte_set_ltag (addr, tags[0]); - - /* Update the value's content with the tag. */ - enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - gdb_byte *srcbuf = address->contents_raw ().data (); - store_unsigned_integer (srcbuf, sizeof (addr), byte_order, addr); - } - else - { - /* Remove the top byte. */ - addr = gdbarch_remove_non_address_bits (gdbarch, addr); - - /* With G being the number of tag granules and N the number of tags - passed in, we can have the following cases: - - 1 - G == N: Store all the N tags to memory. - - 2 - G < N : Warn about having more tags than granules, but write G - tags. - - 3 - G > N : This is a "fill tags" operation. We should use the tags - as a pattern to fill the granules repeatedly until we have - written G tags to memory. - */ - - size_t g = aarch64_mte_get_tag_granules (addr, length, - AARCH64_MTE_GRANULE_SIZE); - size_t n = tags.size (); - - if (g < n) - warning (_("Got more tags than memory granules. Tags will be " - "truncated.")); - else if (g > n) - warning (_("Using tag pattern to fill memory range.")); - - if (!target_store_memtags (addr, length, tags, - static_cast<int> (memtag_type::allocation))) - return false; - } - return true; -} - -/* Implement the get_memtag gdbarch method. */ - -static struct value * -aarch64_linux_get_memtag (struct gdbarch *gdbarch, struct value *address, - memtag_type tag_type) -{ - gdb_assert (address != nullptr); - - CORE_ADDR addr = value_as_address (address); - CORE_ADDR tag = 0; - - /* Get the logical tag or the allocation tag. */ - if (tag_type == memtag_type::logical) - tag = aarch64_mte_get_ltag (addr); - else - { - /* Remove the top byte. */ - addr = gdbarch_remove_non_address_bits (gdbarch, addr); - std::optional<CORE_ADDR> atag = aarch64_mte_get_atag (addr); - - if (!atag.has_value ()) - return nullptr; - - tag = *atag; - } - - /* Convert the tag to a value. */ - return value_from_ulongest (builtin_type (gdbarch)->builtin_unsigned_int, - tag); -} - -/* Implement the memtag_to_string gdbarch method. */ - -static std::string -aarch64_linux_memtag_to_string (struct gdbarch *gdbarch, struct value *tag_value) -{ - if (tag_value == nullptr) - return ""; - - CORE_ADDR tag = value_as_address (tag_value); - - return string_printf ("0x%s", phex_nz (tag, sizeof (tag))); -} /* AArch64 Linux implementation of the report_signal_info gdbarch hook. Displays information about possible memory tag violations. */ @@ -2900,24 +2751,6 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* Register a hook for checking if an address is tagged or not. */ set_gdbarch_tagged_address_p (gdbarch, aarch64_linux_tagged_address_p); - /* Register a hook for checking if there is a memory tag match. */ - set_gdbarch_memtag_matches_p (gdbarch, - aarch64_linux_memtag_matches_p); - - /* Register a hook for setting the logical/allocation tags for - a range of addresses. */ - set_gdbarch_set_memtags (gdbarch, aarch64_linux_set_memtags); - - /* Register a hook for extracting the logical/allocation tag from an - address. */ - set_gdbarch_get_memtag (gdbarch, aarch64_linux_get_memtag); - - /* Set the allocation tag granule size to 16 bytes. */ - set_gdbarch_memtag_granule_size (gdbarch, AARCH64_MTE_GRANULE_SIZE); - - /* Register a hook for converting a memory tag to a string. */ - set_gdbarch_memtag_to_string (gdbarch, aarch64_linux_memtag_to_string); - set_gdbarch_report_signal_info (gdbarch, aarch64_linux_report_signal_info); diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index e4bca6c..8a2a9b1 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -45,6 +45,7 @@ #include "aarch64-tdep.h" #include "aarch64-ravenscar-thread.h" +#include "arch/aarch64-mte.h" #include "record.h" #include "record-full.h" @@ -1727,16 +1728,15 @@ pass_in_v (struct gdbarch *gdbarch, { int regnum = AARCH64_V0_REGNUM + info->nsrn; /* Enough space for a full vector register. */ - gdb_byte reg[register_size (gdbarch, regnum)]; - gdb_assert (len <= sizeof (reg)); + gdb::byte_vector reg (register_size (gdbarch, regnum), 0); + gdb_assert (len <= reg.size ()); info->argnum++; info->nsrn++; - memset (reg, 0, sizeof (reg)); /* PCS C.1, the argument is allocated to the least significant bits of V register. */ - memcpy (reg, buf, len); + memcpy (reg.data (), buf, len); regcache->cooked_write (regnum, reg); aarch64_debug_printf ("arg %d in %s", info->argnum, @@ -2543,8 +2543,8 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs, { int regno = AARCH64_V0_REGNUM + i; /* Enough space for a full vector register. */ - gdb_byte buf[register_size (gdbarch, regno)]; - gdb_assert (len <= sizeof (buf)); + gdb::byte_vector buf (register_size (gdbarch, regno)); + gdb_assert (len <= buf.size ()); aarch64_debug_printf ("read HFA or HVA return value element %d from %s", @@ -2552,7 +2552,7 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs, regs->cooked_read (regno, buf); - memcpy (valbuf, buf, len); + memcpy (valbuf, buf.data (), len); valbuf += len; } } @@ -2657,8 +2657,8 @@ aarch64_store_return_value (struct type *type, struct regcache *regs, { int regno = AARCH64_V0_REGNUM + i; /* Enough space for a full vector register. */ - gdb_byte tmpbuf[register_size (gdbarch, regno)]; - gdb_assert (len <= sizeof (tmpbuf)); + gdb::byte_vector tmpbuf (register_size (gdbarch, regno)); + gdb_assert (len <= tmpbuf.size ()); aarch64_debug_printf ("write HFA or HVA return value element %d to %s", @@ -2669,7 +2669,7 @@ aarch64_store_return_value (struct type *type, struct regcache *regs, original contents of the register before overriding it with a new value that has a potential size <= 16 bytes. */ regs->cooked_read (regno, tmpbuf); - memcpy (tmpbuf, valbuf, + memcpy (tmpbuf.data (), valbuf, len > V_REGISTER_SIZE ? V_REGISTER_SIZE : len); regs->cooked_write (regno, tmpbuf); valbuf += len; @@ -3302,18 +3302,16 @@ aarch64_pseudo_write_1 (gdbarch *gdbarch, const frame_info_ptr &next_frame, { unsigned raw_regnum = AARCH64_V0_REGNUM + regnum_offset; - /* Enough space for a full vector register. */ - int raw_reg_size = register_size (gdbarch, raw_regnum); - gdb_byte raw_buf[raw_reg_size]; - static_assert (AARCH64_V0_REGNUM == AARCH64_SVE_Z0_REGNUM); + /* Enough space for a full vector register. - /* Ensure the register buffer is zero, we want gdb writes of the + Ensure the register buffer is zero, we want gdb writes of the various 'scalar' pseudo registers to behavior like architectural writes, register width bytes are written the remainder are set to zero. */ - memset (raw_buf, 0, register_size (gdbarch, AARCH64_V0_REGNUM)); + gdb::byte_vector raw_buf (register_size (gdbarch, raw_regnum), 0); + static_assert (AARCH64_V0_REGNUM == AARCH64_SVE_Z0_REGNUM); - gdb::array_view<gdb_byte> raw_view (raw_buf, raw_reg_size); + gdb::array_view<gdb_byte> raw_view (raw_buf); copy (buf, raw_view.slice (0, buf.size ())); put_frame_register (next_frame, raw_regnum, raw_view); } @@ -4088,6 +4086,156 @@ aarch64_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc) return streq (inst.opcode->name, "ret"); } +/* Helper to get the allocation tag from a 64-bit ADDRESS. + + Return the allocation tag if successful and nullopt otherwise. */ + +std::optional<CORE_ADDR> +aarch64_mte_get_atag (CORE_ADDR address) +{ + gdb::byte_vector tags; + + /* Attempt to fetch the allocation tag. */ + if (!target_fetch_memtags (address, 1, tags, + static_cast<int> (memtag_type::allocation))) + return {}; + + /* Only one tag should've been returned. Make sure we got exactly that. */ + if (tags.size () != 1) + error (_("Target returned an unexpected number of tags.")); + + /* Although our tags are 4 bits in size, they are stored in a + byte. */ + return tags[0]; +} + +/* Implement the memtag_matches_p gdbarch method. */ + +static bool +aarch64_memtag_matches_p (struct gdbarch *gdbarch, + struct value *address) +{ + gdb_assert (address != nullptr); + + CORE_ADDR addr = value_as_address (address); + + /* Fetch the allocation tag for ADDRESS. */ + std::optional<CORE_ADDR> atag + = aarch64_mte_get_atag (gdbarch_remove_non_address_bits (gdbarch, addr)); + + if (!atag.has_value ()) + return true; + + /* Fetch the logical tag for ADDRESS. */ + gdb_byte ltag = aarch64_mte_get_ltag (addr); + + /* Are the tags the same? */ + return ltag == *atag; +} + +/* Implement the set_memtags gdbarch method. */ + +static bool +aarch64_set_memtags (struct gdbarch *gdbarch, struct value *address, + size_t length, const gdb::byte_vector &tags, + memtag_type tag_type) +{ + gdb_assert (!tags.empty ()); + gdb_assert (address != nullptr); + + CORE_ADDR addr = value_as_address (address); + + /* Set the logical tag or the allocation tag. */ + if (tag_type == memtag_type::logical) + { + /* When setting logical tags, we don't care about the length, since + we are only setting a single logical tag. */ + addr = aarch64_mte_set_ltag (addr, tags[0]); + + /* Update the value's content with the tag. */ + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + gdb_byte *srcbuf = address->contents_raw ().data (); + store_unsigned_integer (srcbuf, sizeof (addr), byte_order, addr); + } + else + { + /* Remove the top byte. */ + addr = gdbarch_remove_non_address_bits (gdbarch, addr); + + /* With G being the number of tag granules and N the number of tags + passed in, we can have the following cases: + + 1 - G == N: Store all the N tags to memory. + + 2 - G < N : Warn about having more tags than granules, but write G + tags. + + 3 - G > N : This is a "fill tags" operation. We should use the tags + as a pattern to fill the granules repeatedly until we have + written G tags to memory. + */ + + size_t g = aarch64_mte_get_tag_granules (addr, length, + AARCH64_MTE_GRANULE_SIZE); + size_t n = tags.size (); + + if (g < n) + warning (_("Got more tags than memory granules. Tags will be " + "truncated.")); + else if (g > n) + warning (_("Using tag pattern to fill memory range.")); + + if (!target_store_memtags (addr, length, tags, + static_cast<int> (memtag_type::allocation))) + return false; + } + return true; +} + +/* Implement the get_memtag gdbarch method. */ + +static struct value * +aarch64_get_memtag (struct gdbarch *gdbarch, struct value *address, + memtag_type tag_type) +{ + gdb_assert (address != nullptr); + + CORE_ADDR addr = value_as_address (address); + CORE_ADDR tag = 0; + + /* Get the logical tag or the allocation tag. */ + if (tag_type == memtag_type::logical) + tag = aarch64_mte_get_ltag (addr); + else + { + /* Remove the top byte. */ + addr = gdbarch_remove_non_address_bits (gdbarch, addr); + std::optional<CORE_ADDR> atag = aarch64_mte_get_atag (addr); + + if (!atag.has_value ()) + return nullptr; + + tag = *atag; + } + + /* Convert the tag to a value. */ + return value_from_ulongest (builtin_type (gdbarch)->builtin_unsigned_int, + tag); +} + +/* Implement the memtag_to_string gdbarch method. */ + +static std::string +aarch64_memtag_to_string (struct gdbarch *gdbarch, struct value *tag_value) +{ + if (tag_value == nullptr) + return ""; + + CORE_ADDR tag = value_as_address (tag_value); + + return string_printf ("0x%s", phex_nz (tag, sizeof (tag))); +} + /* AArch64 implementation of the remove_non_address_bits gdbarch hook. Remove non address bits from a pointer value. */ @@ -4504,6 +4652,23 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) aarch64_pseudo_register_reggroup_p); set_gdbarch_cannot_store_register (gdbarch, aarch64_cannot_store_register); + /* Set the allocation tag granule size to 16 bytes. */ + set_gdbarch_memtag_granule_size (gdbarch, AARCH64_MTE_GRANULE_SIZE); + + /* Register a hook for checking if there is a memory tag match. */ + set_gdbarch_memtag_matches_p (gdbarch, aarch64_memtag_matches_p); + + /* Register a hook for setting the logical/allocation tags for + a range of addresses. */ + set_gdbarch_set_memtags (gdbarch, aarch64_set_memtags); + + /* Register a hook for extracting the logical/allocation tag from an + address. */ + set_gdbarch_get_memtag (gdbarch, aarch64_get_memtag); + + /* Register a hook for converting a memory tag to a string. */ + set_gdbarch_memtag_to_string (gdbarch, aarch64_memtag_to_string); + /* ABI */ set_gdbarch_short_bit (gdbarch, 16); set_gdbarch_int_bit (gdbarch, 32); diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h index 0e6024b..50166fb 100644 --- a/gdb/aarch64-tdep.h +++ b/gdb/aarch64-tdep.h @@ -203,4 +203,6 @@ void aarch64_displaced_step_fixup (struct gdbarch *gdbarch, bool aarch64_displaced_step_hw_singlestep (struct gdbarch *gdbarch); +std::optional<CORE_ADDR> aarch64_mte_get_atag (CORE_ADDR address); + #endif /* aarch64-tdep.h */ diff --git a/gdb/ada-exp.y b/gdb/ada-exp.y index 0126db5..cdfaa3a 100644 --- a/gdb/ada-exp.y +++ b/gdb/ada-exp.y @@ -1831,7 +1831,7 @@ write_var_or_type (struct parser_state *par_state, if (block != nullptr) objfile = block->objfile (); - struct bound_minimal_symbol msym + bound_minimal_symbol msym = ada_lookup_simple_minsym (decoded_name.c_str (), objfile); if (msym.minsym != NULL) { @@ -1857,7 +1857,9 @@ write_var_or_type (struct parser_state *par_state, } } - if (!have_full_symbols () && !have_partial_symbols () && block == NULL) + if (!have_full_symbols (current_program_space) + && !have_partial_symbols (current_program_space) + && block == NULL) error (_("No symbol table is loaded. Use the \"file\" command.")); if (block == par_state->expression_context_block) error (_("No definition of \"%s\" in current context."), name0.ptr); diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 46c2057..f293af6 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -798,7 +798,6 @@ ada_get_decoded_type (struct type *type) const char * ada_main_name () { - struct bound_minimal_symbol msym; static gdb::unique_xmalloc_ptr<char> main_program_name; /* For Ada, the name of the main procedure is stored in a specific @@ -806,7 +805,9 @@ ada_main_name () extract its address, and then read that string. If we didn't find that string, then most probably the main procedure is not written in Ada. */ - msym = lookup_minimal_symbol (ADA_MAIN_PROGRAM_SYMBOL_NAME, NULL, NULL); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, + ADA_MAIN_PROGRAM_SYMBOL_NAME); if (msym.minsym != NULL) { @@ -4921,10 +4922,10 @@ add_defn_to_vec (std::vector<struct block_symbol> &result, specially: "standard__" is first stripped off, and only static and global symbols are searched. */ -struct bound_minimal_symbol +bound_minimal_symbol ada_lookup_simple_minsym (const char *name, struct objfile *objfile) { - struct bound_minimal_symbol result; + bound_minimal_symbol result; symbol_name_match_type match_type = name_match_type_from_name (name); lookup_name_info lookup_name (name, match_type); @@ -11195,16 +11196,9 @@ ada_funcall_operation::evaluate (struct type *expect_type, } return call_function_by_hand (callee, expect_type, argvec); case TYPE_CODE_INTERNAL_FUNCTION: - if (noside == EVAL_AVOID_SIDE_EFFECTS) - /* We don't know anything about what the internal - function might return, but we have to return - something. */ - return value::zero (builtin_type (exp->gdbarch)->builtin_int, - not_lval); - else return call_internal_function (exp->gdbarch, exp->language_defn, callee, nargs, - argvec.data ()); + argvec.data (), noside); case TYPE_CODE_STRUCT: { @@ -11702,8 +11696,9 @@ ada_has_this_exception_support (const struct exception_support_info *einfo) the name of the exception being raised (this name is printed in the catchpoint message, and is also used when trying to catch a specific exception). We do not handle this case for now. */ - struct bound_minimal_symbol msym - = lookup_minimal_symbol (einfo->catch_exception_sym, NULL, NULL); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, + einfo->catch_exception_sym); if (msym.minsym && msym.minsym->type () != mst_solib_trampoline) error (_("Your Ada runtime appears to be missing some debugging " @@ -11722,8 +11717,9 @@ ada_has_this_exception_support (const struct exception_support_info *einfo) sym = standard_lookup (einfo->catch_handlers_sym, NULL, SEARCH_VFT); if (sym == NULL) { - struct bound_minimal_symbol msym - = lookup_minimal_symbol (einfo->catch_handlers_sym, NULL, NULL); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, + einfo->catch_handlers_sym); if (msym.minsym && msym.minsym->type () != mst_solib_trampoline) error (_("Your Ada runtime appears to be missing some debugging " @@ -13884,7 +13880,7 @@ static struct cmd_list_element *show_ada_list; static void ada_new_objfile_observer (struct objfile *objfile) { - ada_clear_symbol_cache (objfile->pspace); + ada_clear_symbol_cache (objfile->pspace ()); } /* This module's 'free_objfile' observer. */ @@ -13892,7 +13888,7 @@ ada_new_objfile_observer (struct objfile *objfile) static void ada_free_objfile_observer (struct objfile *objfile) { - ada_clear_symbol_cache (objfile->pspace); + ada_clear_symbol_cache (objfile->pspace ()); } /* Charsets known to GNAT. */ diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h index d14bfd4..77193ef 100644 --- a/gdb/ada-lang.h +++ b/gdb/ada-lang.h @@ -239,8 +239,7 @@ extern struct block_symbol ada_lookup_symbol (const char *, extern block_symbol ada_lookup_encoded_symbol (const char *name, const struct block *block, domain_search_flags domain); -extern struct bound_minimal_symbol ada_lookup_simple_minsym (const char *, - objfile *); +extern bound_minimal_symbol ada_lookup_simple_minsym (const char *, objfile *); extern int ada_scan_number (const char *, int, LONGEST *, int *); diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c index 83059d7..01ee2fb 100644 --- a/gdb/ada-tasks.c +++ b/gdb/ada-tasks.c @@ -600,7 +600,7 @@ ada_get_tcb_types_info (void) /* Check for the CPU offset. */ bound_minimal_symbol first_id_sym - = lookup_bound_minimal_symbol ("__gnat_gdb_cpu_first_id"); + = lookup_minimal_symbol (current_program_space, "__gnat_gdb_cpu_first_id"); unsigned int first_id = 0; if (first_id_sym.minsym != nullptr) { @@ -712,9 +712,7 @@ read_atcb (CORE_ADDR task_id, struct ada_task_info *task_info) sizeof (task_info->name) - 1); else { - struct bound_minimal_symbol msym; - - msym = lookup_minimal_symbol_by_pc (task_id); + bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (task_id); if (msym.minsym) { const char *full_name = msym.minsym->linkage_name (); @@ -914,7 +912,6 @@ read_known_tasks_list (struct ada_tasks_inferior_data *data) static void ada_tasks_inferior_data_sniffer (struct ada_tasks_inferior_data *data) { - struct bound_minimal_symbol msym; struct symbol *sym; /* Return now if already set. */ @@ -923,7 +920,8 @@ ada_tasks_inferior_data_sniffer (struct ada_tasks_inferior_data *data) /* Try array. */ - msym = lookup_minimal_symbol (KNOWN_TASKS_NAME, NULL, NULL); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, KNOWN_TASKS_NAME); if (msym.minsym != NULL) { data->known_tasks_kind = ADA_TASKS_ARRAY; @@ -970,7 +968,7 @@ ada_tasks_inferior_data_sniffer (struct ada_tasks_inferior_data *data) /* Try list. */ - msym = lookup_minimal_symbol (KNOWN_TASKS_LIST, NULL, NULL); + msym = lookup_minimal_symbol (current_program_space, KNOWN_TASKS_LIST); if (msym.minsym != NULL) { data->known_tasks_kind = ADA_TASKS_LIST; @@ -1495,7 +1493,7 @@ ada_tasks_clear_pspace_data (program_space *pspace) static void ada_tasks_new_objfile_observer (objfile *objfile) { - ada_tasks_clear_pspace_data (objfile->pspace); + ada_tasks_clear_pspace_data (objfile->pspace ()); } /* The qcs command line flags for the "task apply" commands. Keep diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c index 327f560..9e6952b 100644 --- a/gdb/aix-thread.c +++ b/gdb/aix-thread.c @@ -78,7 +78,6 @@ static bool debug_aix_thread; struct aix_thread_info : public private_thread_info { pthdb_pthread_t pdtid; /* thread's libpthdebug id */ - pthdb_tid_t tid; /* kernel thread id */ }; /* Return the aix_thread_info attached to THREAD. */ @@ -377,7 +376,6 @@ pid_to_prc (ptid_t *ptidp) static int pdc_symbol_addrs (pthdb_user_t user_current_pid, pthdb_symbol_t *symbols, int count) { - struct bound_minimal_symbol ms; int i; char *name; @@ -397,7 +395,8 @@ pdc_symbol_addrs (pthdb_user_t user_current_pid, pthdb_symbol_t *symbols, int co symbols[i].addr = 0; else { - ms = lookup_minimal_symbol (name, NULL, NULL); + bound_minimal_symbol ms + = lookup_minimal_symbol (current_program_space, name); if (ms.minsym == NULL) { if (debug_aix_thread) @@ -805,7 +804,9 @@ sync_threadlists (pid_t pid) if (status != PTHDB_SUCCESS || pthid == PTHDB_INVALID_PTID) continue; - ptid_t ptid (pid, 0, pthid); + status = pthdb_pthread_tid (data->pd_session, pdtid, &tid); + ptid_t ptid (pid, tid, pthid); + status = pthdb_pthread_state (data->pd_session, pdtid, &state); in_queue_threads.insert (pdtid); @@ -822,8 +823,6 @@ sync_threadlists (pid_t pid) aix_thread_info *priv = new aix_thread_info; /* init priv */ priv->pdtid = pdtid; - status = pthdb_pthread_tid (data->pd_session, pdtid, &tid); - priv->tid = tid; /* Check if this is the main thread. If it is, then change its ptid and add its private data. */ if (in_thread_list (proc_target, ptid_t (pid))) @@ -875,9 +874,7 @@ static int iter_tid (struct thread_info *thread, void *tidp) { const pthdb_tid_t tid = *(pthdb_tid_t *)tidp; - aix_thread_info *priv = get_aix_thread_info (thread); - - return priv->tid == tid; + return thread->ptid.lwp () == tid; } /* Synchronize libpthdebug's state with the inferior and with GDB, @@ -959,7 +956,6 @@ pd_enable (inferior *inf) { int status; char *stub_name; - struct bound_minimal_symbol ms; struct aix_thread_variables *data; if (inf == NULL) @@ -983,7 +979,8 @@ pd_enable (inferior *inf) return; /* Set a breakpoint on the returned stub function. */ - ms = lookup_minimal_symbol (stub_name, NULL, NULL); + bound_minimal_symbol ms + = lookup_minimal_symbol (current_program_space, stub_name); if (ms.minsym == NULL) return; data->pd_brk_addr = ms.value_address (); @@ -1079,7 +1076,7 @@ aix_thread_target::resume (ptid_t ptid, int step, enum gdb_signal sig) aix_thread_info *priv = get_aix_thread_info (thread); - tid[0] = priv->tid; + tid[0] = ptid.lwp (); if (tid[0] == PTHDB_INVALID_TID) error (_("aix-thread resume: no tid for pthread %ld"), ptid.lwp ()); @@ -1468,7 +1465,7 @@ aix_thread_target::fetch_registers (struct regcache *regcache, int regno) { thread = current_inferior ()->find_thread (regcache->ptid ()); aix_thread_info *priv = get_aix_thread_info (thread); - tid = priv->tid; + tid = regcache->ptid().lwp (); if (tid == PTHDB_INVALID_TID) fetch_regs_user_thread (regcache, priv->pdtid); @@ -1933,7 +1930,7 @@ aix_thread_target::store_registers (struct regcache *regcache, int regno) { thread = current_inferior ()->find_thread (regcache->ptid ()); aix_thread_info *priv = get_aix_thread_info (thread); - tid = priv->tid; + tid = regcache->ptid ().lwp (); if (tid == PTHDB_INVALID_TID) store_regs_user_thread (regcache, priv->pdtid); @@ -1997,7 +1994,7 @@ aix_thread_target::pid_to_str (ptid_t ptid) aix_thread_info *priv = get_aix_thread_info (thread_info); return string_printf (_("Thread %s (tid %s)"), pulongest (ptid.tid ()), - pulongest (priv->tid)); + pulongest (ptid.lwp ())); } return beneath ()->pid_to_str (ptid); diff --git a/gdb/amd-dbgapi-target.c b/gdb/amd-dbgapi-target.c index 073270f..e9c5a47 100644 --- a/gdb/amd-dbgapi-target.c +++ b/gdb/amd-dbgapi-target.c @@ -684,7 +684,7 @@ amd_dbgapi_target::resume (ptid_t scope_ptid, int step, enum gdb_signal signo) switch (signo) { case GDB_SIGNAL_BUS: - exception = AMD_DBGAPI_EXCEPTION_WAVE_APERTURE_VIOLATION; + exception = AMD_DBGAPI_EXCEPTION_WAVE_ADDRESS_ERROR; break; case GDB_SIGNAL_SEGV: exception = AMD_DBGAPI_EXCEPTION_WAVE_MEMORY_VIOLATION; @@ -1167,7 +1167,7 @@ process_one_event (amd_dbgapi_event_id_t event_id, ws.set_thread_exited (0); else if (status == AMD_DBGAPI_STATUS_SUCCESS) { - if (stop_reason & AMD_DBGAPI_WAVE_STOP_REASON_APERTURE_VIOLATION) + if (stop_reason & AMD_DBGAPI_WAVE_STOP_REASON_ADDRESS_ERROR) ws.set_stopped (GDB_SIGNAL_BUS); else if (stop_reason & AMD_DBGAPI_WAVE_STOP_REASON_MEMORY_VIOLATION) @@ -1992,19 +1992,35 @@ amd_dbgapi_inferior_pre_detach (inferior *inf) detach_amd_dbgapi (inf); } -/* get_os_pid callback. */ +/* client_process_get_info callback. */ static amd_dbgapi_status_t -amd_dbgapi_get_os_pid_callback - (amd_dbgapi_client_process_id_t client_process_id, pid_t *pid) +amd_dbgapi_client_process_get_info_callback + (amd_dbgapi_client_process_id_t client_process_id, + amd_dbgapi_client_process_info_t query, size_t value_size, void *value) { inferior *inf = reinterpret_cast<inferior *> (client_process_id); if (inf->pid == 0) return AMD_DBGAPI_STATUS_ERROR_PROCESS_EXITED; - *pid = inf->pid; - return AMD_DBGAPI_STATUS_SUCCESS; + if (value == nullptr) + return AMD_DBGAPI_STATUS_ERROR_INVALID_ARGUMENT; + + switch (query) + { + case AMD_DBGAPI_CLIENT_PROCESS_INFO_OS_PID: + if (value_size != sizeof (amd_dbgapi_os_process_id_t)) + return AMD_DBGAPI_STATUS_ERROR_INVALID_ARGUMENT_COMPATIBILITY; + + *static_cast<amd_dbgapi_os_process_id_t *> (value) = inf->pid; + return AMD_DBGAPI_STATUS_SUCCESS; + + case AMD_DBGAPI_CLIENT_PROCESS_INFO_CORE_STATE: + return AMD_DBGAPI_STATUS_ERROR_NOT_AVAILABLE; + } + + return AMD_DBGAPI_STATUS_ERROR_INVALID_ARGUMENT; } /* insert_breakpoint callback. */ @@ -2060,6 +2076,50 @@ amd_dbgapi_remove_breakpoint_callback return AMD_DBGAPI_STATUS_SUCCESS; } +/* xfer_global_memory callback. */ + +static amd_dbgapi_status_t +amd_dbgapi_xfer_global_memory_callback + (amd_dbgapi_client_process_id_t client_process_id, + amd_dbgapi_global_address_t global_address, + amd_dbgapi_size_t *value_size, void *read_buffer, + const void *write_buffer) +{ + if ((read_buffer != nullptr) == (write_buffer != nullptr)) + return AMD_DBGAPI_STATUS_ERROR_INVALID_ARGUMENT_COMPATIBILITY; + + inferior *inf = reinterpret_cast<inferior *> (client_process_id); + + /* We need to set inferior_ptid / current_inferior as those are + used by the target which will process the xfer_partial request. + + Note that we end up here when amd-dbgapi tries to access device memory or + register content which are at this point mapped/saved in the host process + memory. As a consequence, unwinding GPU frames will most likely call into + here. If we used switch_to_thread to select a host thread, this would + implicitly call reinit_frame_cache. We do not want to clear the frame + cache while trying to build it. */ + scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid); + scoped_restore_current_inferior restore_current_inferior; + scoped_restore_current_program_space restore_program_space; + inferior_ptid = ptid_t (inf->pid); + set_current_inferior (inf); + set_current_program_space (inf->pspace); + + target_xfer_status status + = target_xfer_partial (inf->top_target (), TARGET_OBJECT_RAW_MEMORY, + nullptr, static_cast<gdb_byte *> (read_buffer), + static_cast<const gdb_byte *> (write_buffer), + global_address, *value_size, value_size); + + if (status == TARGET_XFER_EOF) + return AMD_DBGAPI_STATUS_ERROR_PROCESS_EXITED; + else if (status != TARGET_XFER_OK) + return AMD_DBGAPI_STATUS_ERROR_MEMORY_ACCESS; + + return AMD_DBGAPI_STATUS_SUCCESS; +} + /* signal_received observer. */ static void @@ -2138,9 +2198,10 @@ amd_dbgapi_log_message_callback (amd_dbgapi_log_level_t level, static amd_dbgapi_callbacks_t dbgapi_callbacks = { .allocate_memory = malloc, .deallocate_memory = free, - .get_os_pid = amd_dbgapi_get_os_pid_callback, + .client_process_get_info = amd_dbgapi_client_process_get_info_callback, .insert_breakpoint = amd_dbgapi_insert_breakpoint_callback, .remove_breakpoint = amd_dbgapi_remove_breakpoint_callback, + .xfer_global_memory = amd_dbgapi_xfer_global_memory_callback, .log_message = amd_dbgapi_log_message_callback, }; diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c index aa9295d..823c1f7 100644 --- a/gdb/amd64-linux-nat.c +++ b/gdb/amd64-linux-nat.c @@ -235,22 +235,21 @@ amd64_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum) if (have_ptrace_getregset == TRIBOOL_TRUE) { - char xstateregs[tdep->xsave_layout.sizeof_xsave]; - struct iovec iov; - /* Pre-4.14 kernels have a bug (fixed by commit 0852b374173b "x86/fpu: Add FPU state copying quirk to handle XRSTOR failure on Intel Skylake CPUs") that sometimes causes the mxcsr location in xstateregs not to be copied by PTRACE_GETREGSET. Make sure that the location is at least initialized with a defined value. */ - memset (xstateregs, 0, sizeof (xstateregs)); - iov.iov_base = xstateregs; - iov.iov_len = sizeof (xstateregs); + gdb::byte_vector xstateregs (tdep->xsave_layout.sizeof_xsave, 0); + struct iovec iov; + + iov.iov_base = xstateregs.data (); + iov.iov_len = xstateregs.size (); if (ptrace (PTRACE_GETREGSET, tid, (unsigned int) NT_X86_XSTATE, (long) &iov) < 0) perror_with_name (_("Couldn't get extended state status")); - amd64_supply_xsave (regcache, -1, xstateregs); + amd64_supply_xsave (regcache, -1, xstateregs.data ()); } else { @@ -300,16 +299,16 @@ amd64_linux_nat_target::store_registers (struct regcache *regcache, int regnum) if (have_ptrace_getregset == TRIBOOL_TRUE) { - char xstateregs[tdep->xsave_layout.sizeof_xsave]; + gdb::byte_vector xstateregs (tdep->xsave_layout.sizeof_xsave); struct iovec iov; - iov.iov_base = xstateregs; - iov.iov_len = sizeof (xstateregs); + iov.iov_base = xstateregs.data (); + iov.iov_len = xstateregs.size (); if (ptrace (PTRACE_GETREGSET, tid, (unsigned int) NT_X86_XSTATE, (long) &iov) < 0) perror_with_name (_("Couldn't get extended state status")); - amd64_collect_xsave (regcache, regnum, xstateregs, 0); + amd64_collect_xsave (regcache, regnum, xstateregs.data (), 0); if (ptrace (PTRACE_SETREGSET, tid, (unsigned int) NT_X86_XSTATE, (long) &iov) < 0) diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c index 9636201..5adc7d5 100644 --- a/gdb/amd64-windows-tdep.c +++ b/gdb/amd64-windows-tdep.c @@ -435,11 +435,10 @@ amd64_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) if (target_read_memory (pc + 1, buf, sizeof buf) == 0) { - struct bound_minimal_symbol s; CORE_ADDR call_dest; call_dest = pc + 5 + extract_signed_integer (buf, 4, byte_order); - s = lookup_minimal_symbol_by_pc (call_dest); + bound_minimal_symbol s = lookup_minimal_symbol_by_pc (call_dest); if (s.minsym != NULL && s.minsym->linkage_name () != NULL && strcmp (s.minsym->linkage_name (), "__main") == 0) diff --git a/gdb/amdgpu-tdep.c b/gdb/amdgpu-tdep.c index 49996ae..6fe7973 100644 --- a/gdb/amdgpu-tdep.c +++ b/gdb/amdgpu-tdep.c @@ -28,8 +28,6 @@ #include "gdbsupport/selftest.h" #include "gdbtypes.h" #include "inferior.h" -#include "objfiles.h" -#include "observable.h" #include "producer.h" #include "reggroups.h" diff --git a/gdb/annotate.c b/gdb/annotate.c index 8818029..c1d4229 100644 --- a/gdb/annotate.c +++ b/gdb/annotate.c @@ -457,7 +457,7 @@ annotate_source_line (struct symtab *s, int line, int mid_statement, /* Update the current symtab and line. */ symtab_and_line sal; - sal.pspace = s->compunit ()->objfile ()->pspace; + sal.pspace = s->compunit ()->objfile ()->pspace (); sal.symtab = s; sal.line = line; set_current_source_symtab_and_line (sal); diff --git a/gdb/arc-linux-tdep.c b/gdb/arc-linux-tdep.c index 30bd40c..01c591f 100644 --- a/gdb/arc-linux-tdep.c +++ b/gdb/arc-linux-tdep.c @@ -506,8 +506,8 @@ arc_linux_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc) So we look for the symbol `_dl_linux_resolver', and if we are there, gdb sets a breakpoint at the return address, and continues. */ - struct bound_minimal_symbol resolver - = lookup_minimal_symbol ("_dl_linux_resolver", NULL, NULL); + bound_minimal_symbol resolver + = lookup_minimal_symbol (current_program_space, "_dl_linux_resolver"); if (arc_debug) { diff --git a/gdb/arc-tdep.c b/gdb/arc-tdep.c index 9491107..4fc1ea1 100644 --- a/gdb/arc-tdep.c +++ b/gdb/arc-tdep.c @@ -861,7 +861,7 @@ arc_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp, CORE_ADDR funaddr, struct regcache *regcache) { *real_pc = funaddr; - *bp_addr = entry_point_address (); + *bp_addr = entry_point_address (current_program_space); return sp; } diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 83e2947..6ffa410 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" @@ -56,7 +57,7 @@ displaced_step_at_entry_point (struct gdbarch *gdbarch) CORE_ADDR addr; int bp_len; - addr = entry_point_address (); + addr = entry_point_address (current_program_space); /* Inferior calls also use the entry point as a breakpoint location. We don't want displaced stepping to interfere with those @@ -404,13 +405,13 @@ set_endian (const char *ignore_args, int from_tty, struct cmd_list_element *c) if (set_endian_string == endian_auto) { target_byte_order_user = BFD_ENDIAN_UNKNOWN; - if (! gdbarch_update_p (info)) + if (!gdbarch_update_p (current_inferior (), info)) internal_error (_("set_endian: architecture update failed")); } else if (set_endian_string == endian_little) { info.byte_order = BFD_ENDIAN_LITTLE; - if (! gdbarch_update_p (info)) + if (!gdbarch_update_p (current_inferior (), info)) gdb_printf (gdb_stderr, _("Little endian target not supported by GDB\n")); else @@ -419,7 +420,7 @@ set_endian (const char *ignore_args, int from_tty, struct cmd_list_element *c) else if (set_endian_string == endian_big) { info.byte_order = BFD_ENDIAN_BIG; - if (! gdbarch_update_p (info)) + if (!gdbarch_update_p (current_inferior (), info)) gdb_printf (gdb_stderr, _("Big endian target not supported by GDB\n")); else @@ -561,7 +562,7 @@ set_architecture (const char *ignore_args, if (strcmp (set_architecture_string, "auto") == 0) { target_architecture_user = NULL; - if (!gdbarch_update_p (info)) + if (!gdbarch_update_p (current_inferior (), info)) internal_error (_("could not select an architecture automatically")); } else @@ -569,7 +570,7 @@ set_architecture (const char *ignore_args, info.bfd_arch_info = bfd_scan_arch (set_architecture_string); if (info.bfd_arch_info == NULL) internal_error (_("set_architecture: bfd_scan_arch failed")); - if (gdbarch_update_p (info)) + if (gdbarch_update_p (current_inferior (), info)) target_architecture_user = info.bfd_arch_info; else gdb_printf (gdb_stderr, @@ -579,22 +580,23 @@ set_architecture (const char *ignore_args, show_architecture (gdb_stdout, from_tty, NULL, NULL); } -/* Try to select a global architecture that matches "info". Return - non-zero if the attempt succeeds. */ +/* See arch-utils.h. */ + int -gdbarch_update_p (struct gdbarch_info info) +gdbarch_update_p (inferior *inf, struct gdbarch_info info) { struct gdbarch *new_gdbarch; /* Check for the current file. */ if (info.abfd == NULL) - info.abfd = current_program_space->exec_bfd (); + info.abfd = inf->pspace->exec_bfd (); + if (info.abfd == NULL) - info.abfd = current_program_space->core_bfd (); + info.abfd = inf->pspace->core_bfd (); /* Check for the current target description. */ if (info.target_desc == NULL) - info.target_desc = target_current_description (); + info.target_desc = target_current_description (inf); new_gdbarch = gdbarch_find_by_info (info); @@ -609,7 +611,7 @@ gdbarch_update_p (struct gdbarch_info info) /* If it is the same old architecture, accept the request (but don't swap anything). */ - if (new_gdbarch == current_inferior ()->arch ()) + if (new_gdbarch == inf->arch ()) { if (gdbarch_debug) gdb_printf (gdb_stdlog, "gdbarch_update_p: " @@ -626,7 +628,7 @@ gdbarch_update_p (struct gdbarch_info info) host_address_to_string (new_gdbarch), gdbarch_bfd_arch_info (new_gdbarch)->printable_name); - current_inferior ()->set_arch (new_gdbarch); + inf->set_arch (new_gdbarch); return 1; } @@ -653,7 +655,7 @@ set_gdbarch_from_file (bfd *abfd) struct gdbarch *gdbarch; info.abfd = abfd; - info.target_desc = target_current_description (); + info.target_desc = target_current_description (current_inferior ()); gdbarch = gdbarch_find_by_info (info); if (gdbarch == NULL) @@ -751,7 +753,7 @@ initialize_current_architecture (void) info.byte_order = default_byte_order; info.byte_order_for_code = info.byte_order; - if (! gdbarch_update_p (info)) + if (!gdbarch_update_p (current_inferior (), info)) internal_error (_("initialize_current_architecture: Selection of " "initial architecture failed")); @@ -1040,7 +1042,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. */ @@ -1192,7 +1198,7 @@ pstring_list (const char *const *list) return ret; } -#include "gdbarch.c" +#include "gdbarch-gen.c" enum return_value_convention default_gdbarch_return_value diff --git a/gdb/arch/aarch64-mte-linux.c b/gdb/arch/aarch64-mte-linux.c index e0b441e..49426d7 100644 --- a/gdb/arch/aarch64-mte-linux.c +++ b/gdb/arch/aarch64-mte-linux.c @@ -75,59 +75,3 @@ aarch64_mte_unpack_tags (gdb::byte_vector &tags, bool skip_first) tags = std::move (unpacked_tags); } -/* See arch/aarch64-mte-linux.h */ - -size_t -aarch64_mte_get_tag_granules (CORE_ADDR addr, size_t len, size_t granule_size) -{ - /* An empty range has 0 tag granules. */ - if (len == 0) - return 0; - - /* Start address */ - CORE_ADDR s_addr = align_down (addr, granule_size); - /* End address */ - CORE_ADDR e_addr = align_down (addr + len - 1, granule_size); - - /* We always have at least 1 granule because len is non-zero at this - point. */ - return 1 + (e_addr - s_addr) / granule_size; -} - -/* See arch/aarch64-mte-linux.h */ - -CORE_ADDR -aarch64_mte_make_ltag_bits (CORE_ADDR value) -{ - return value & AARCH64_MTE_LOGICAL_MAX_VALUE; -} - -/* See arch/aarch64-mte-linux.h */ - -CORE_ADDR -aarch64_mte_make_ltag (CORE_ADDR value) -{ - return (aarch64_mte_make_ltag_bits (value) - << AARCH64_MTE_LOGICAL_TAG_START_BIT); -} - -/* See arch/aarch64-mte-linux.h */ - -CORE_ADDR -aarch64_mte_set_ltag (CORE_ADDR address, CORE_ADDR tag) -{ - /* Remove the existing tag. */ - address &= ~aarch64_mte_make_ltag (AARCH64_MTE_LOGICAL_MAX_VALUE); - - /* Return the new tagged address. */ - return address | aarch64_mte_make_ltag (tag); -} - -/* See arch/aarch64-mte-linux.h */ - -CORE_ADDR -aarch64_mte_get_ltag (CORE_ADDR address) -{ - CORE_ADDR ltag_addr = address >> AARCH64_MTE_LOGICAL_TAG_START_BIT; - return aarch64_mte_make_ltag_bits (ltag_addr); -} diff --git a/gdb/arch/aarch64-mte-linux.h b/gdb/arch/aarch64-mte-linux.h index 460b10e..686749f 100644 --- a/gdb/arch/aarch64-mte-linux.h +++ b/gdb/arch/aarch64-mte-linux.h @@ -29,12 +29,6 @@ /* The MTE regset consists of a single 64-bit register. */ #define AARCH64_LINUX_SIZEOF_MTE 8 -/* We have one tag per 16 bytes of memory. */ -#define AARCH64_MTE_GRANULE_SIZE 16 -#define AARCH64_MTE_TAG_BIT_SIZE 4 -#define AARCH64_MTE_LOGICAL_TAG_START_BIT 56 -#define AARCH64_MTE_LOGICAL_MAX_VALUE 0xf - /* Memory tagging definitions. */ #ifndef SEGV_MTEAERR # define SEGV_MTEAERR 8 @@ -50,27 +44,6 @@ enum class aarch64_memtag_type mte_allocation }; -/* Return the number of tag granules in the memory range - [ADDR, ADDR + LEN) given GRANULE_SIZE. */ -extern size_t aarch64_mte_get_tag_granules (CORE_ADDR addr, size_t len, - size_t granule_size); - -/* Return the 4-bit tag made from VALUE. */ -extern CORE_ADDR aarch64_mte_make_ltag_bits (CORE_ADDR value); - -/* Return the 4-bit tag that can be OR-ed to an address. */ -extern CORE_ADDR aarch64_mte_make_ltag (CORE_ADDR value); - -/* Helper to set the logical TAG for a 64-bit ADDRESS. - - It is always possible to set the logical tag. */ -extern CORE_ADDR aarch64_mte_set_ltag (CORE_ADDR address, CORE_ADDR tag); - -/* Helper to get the logical tag from a 64-bit ADDRESS. - - It is always possible to get the logical tag. */ -extern CORE_ADDR aarch64_mte_get_ltag (CORE_ADDR address); - /* Given a TAGS vector containing 1 MTE tag per byte, pack the data as 2 tags per byte and resize the vector. */ extern void aarch64_mte_pack_tags (gdb::byte_vector &tags); diff --git a/gdb/arch/aarch64-mte.c b/gdb/arch/aarch64-mte.c new file mode 100644 index 0000000..908e12c --- /dev/null +++ b/gdb/arch/aarch64-mte.c @@ -0,0 +1,77 @@ +/* Common AArch64 functionality for MTE + + Copyright (C) 2021-2024 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "arch/aarch64-mte.h" + +/* See arch/aarch64-mte.h */ + +size_t +aarch64_mte_get_tag_granules (CORE_ADDR addr, size_t len, size_t granule_size) +{ + /* An empty range has 0 tag granules. */ + if (len == 0) + return 0; + + /* Start address */ + CORE_ADDR s_addr = align_down (addr, granule_size); + /* End address */ + CORE_ADDR e_addr = align_down (addr + len - 1, granule_size); + + /* We always have at least 1 granule because len is non-zero at this + point. */ + return 1 + (e_addr - s_addr) / granule_size; +} + +/* See arch/aarch64-mte.h */ + +CORE_ADDR +aarch64_mte_make_ltag_bits (CORE_ADDR value) +{ + return value & AARCH64_MTE_LOGICAL_MAX_VALUE; +} + +/* See arch/aarch64-mte.h */ + +CORE_ADDR +aarch64_mte_make_ltag (CORE_ADDR value) +{ + return (aarch64_mte_make_ltag_bits (value) + << AARCH64_MTE_LOGICAL_TAG_START_BIT); +} + +/* See arch/aarch64-mte.h */ + +CORE_ADDR +aarch64_mte_set_ltag (CORE_ADDR address, CORE_ADDR tag) +{ + /* Remove the existing tag. */ + address &= ~aarch64_mte_make_ltag (AARCH64_MTE_LOGICAL_MAX_VALUE); + + /* Return the new tagged address. */ + return address | aarch64_mte_make_ltag (tag); +} + +/* See arch/aarch64-mte.h */ + +CORE_ADDR +aarch64_mte_get_ltag (CORE_ADDR address) +{ + CORE_ADDR ltag_addr = address >> AARCH64_MTE_LOGICAL_TAG_START_BIT; + return aarch64_mte_make_ltag_bits (ltag_addr); +} diff --git a/gdb/arch/aarch64-mte.h b/gdb/arch/aarch64-mte.h new file mode 100644 index 0000000..7d8445e --- /dev/null +++ b/gdb/arch/aarch64-mte.h @@ -0,0 +1,51 @@ +/* Common AArch64 definitions for MTE + + Copyright (C) 2021-2024 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef ARCH_AARCH64_MTE_H +#define ARCH_AARCH64_MTE_H + + +/* We have one tag per 16 bytes of memory. */ +#define AARCH64_MTE_GRANULE_SIZE 16 +#define AARCH64_MTE_TAG_BIT_SIZE 4 +#define AARCH64_MTE_LOGICAL_TAG_START_BIT 56 +#define AARCH64_MTE_LOGICAL_MAX_VALUE 0xf + +/* Return the number of tag granules in the memory range + [ADDR, ADDR + LEN) given GRANULE_SIZE. */ +extern size_t aarch64_mte_get_tag_granules (CORE_ADDR addr, size_t len, + size_t granule_size); + +/* Return the 4-bit tag made from VALUE. */ +extern CORE_ADDR aarch64_mte_make_ltag_bits (CORE_ADDR value); + +/* Return the 4-bit tag that can be OR-ed to an address. */ +extern CORE_ADDR aarch64_mte_make_ltag (CORE_ADDR value); + +/* Helper to set the logical TAG for a 64-bit ADDRESS. + + It is always possible to set the logical tag. */ +extern CORE_ADDR aarch64_mte_set_ltag (CORE_ADDR address, CORE_ADDR tag); + +/* Helper to get the logical tag from a 64-bit ADDRESS. + + It is always possible to get the logical tag. */ +extern CORE_ADDR aarch64_mte_get_ltag (CORE_ADDR address); + +#endif /* ARCH_AARCH64_MTE_H */ diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c index ac53bed..7b4faac 100644 --- a/gdb/arm-linux-nat.c +++ b/gdb/arm-linux-nat.c @@ -876,6 +876,14 @@ arm_hwbp_control_is_enabled (arm_hwbp_control_t control) return control & 0x1; } +/* Is the breakpoint control value CONTROL initialized? */ + +static int +arm_hwbp_control_is_initialized (arm_hwbp_control_t control) +{ + return control != 0; +} + /* Change a breakpoint control word so that it is in the disabled state. */ static arm_hwbp_control_t arm_hwbp_control_disable (arm_hwbp_control_t control) @@ -1234,6 +1242,34 @@ arm_linux_nat_target::low_delete_thread (struct arch_lwp_info *arch_lwp) xfree (arch_lwp); } +/* For PID, set the address register of hardware breakpoint pair I to + ADDRESS. */ + +static void +sethbpregs_hwbp_address (int pid, int i, unsigned int address) +{ + PTRACE_TYPE_ARG3 address_reg = (PTRACE_TYPE_ARG3) ((i << 1) + 1); + + errno = 0; + + if (ptrace (PTRACE_SETHBPREGS, pid, address_reg, &address) < 0) + perror_with_name (_("Unexpected error updating breakpoint address")); +} + +/* For PID, set the control register of hardware breakpoint pair I to + CONTROL. */ + +static void +sethbpregs_hwbp_control (int pid, int i, arm_hwbp_control_t control) +{ + PTRACE_TYPE_ARG3 control_reg = (PTRACE_TYPE_ARG3) ((i << 1) + 2); + + errno = 0; + + if (ptrace (PTRACE_SETHBPREGS, pid, control_reg, &control) < 0) + perror_with_name (_("Unexpected error setting breakpoint control")); +} + /* Called when resuming a thread. The hardware debug registers are updated when there is any change. */ @@ -1257,16 +1293,58 @@ arm_linux_nat_target::low_prepare_to_resume (struct lwp_info *lwp) for (i = 0; i < arm_linux_get_hw_breakpoint_count (); i++) if (arm_lwp_info->bpts_changed[i]) { - errno = 0; - if (arm_hwbp_control_is_enabled (bpts[i].control)) - if (ptrace (PTRACE_SETHBPREGS, pid, - (PTRACE_TYPE_ARG3) ((i << 1) + 1), &bpts[i].address) < 0) - perror_with_name (_("Unexpected error setting breakpoint")); - - if (bpts[i].control != 0) - if (ptrace (PTRACE_SETHBPREGS, pid, - (PTRACE_TYPE_ARG3) ((i << 1) + 2), &bpts[i].control) < 0) - perror_with_name (_("Unexpected error setting breakpoint")); + unsigned int address = bpts[i].address; + arm_hwbp_control_t control = bpts[i].control; + + if (!arm_hwbp_control_is_initialized (control)) + { + /* Nothing to do. */ + } + else if (!arm_hwbp_control_is_enabled (control)) + { + /* Disable hardware breakpoint, just write the control + register. */ + sethbpregs_hwbp_control (pid, i, control); + } + else + { + /* We used to do here simply: + 1. address_reg = address + 2. control_reg = control + but the write to address_reg can fail for thumb2 instructions if + the address is not 4-byte aligned. + + It's not clear whether this is a kernel bug or not, partly + because PTRACE_SETHBPREGS is undocumented. + + The context is that we're using two ptrace calls to set the two + halves of a register pair. For each ptrace call, the kernel must + check the arguments, and return -1 and set errno appropriately if + something is wrong. One of the aspects that needs validation is + whether, in terms of hw_breakpoint_arch_parse, the breakpoint + address matches the breakpoint length. This aspect can only be + checked by looking in both registers, which only makes sense + once a pair is written in full. + + The problem is that the kernel checks this aspect after each + ptrace call, and consequently for the first call it may be + checking this aspect using a default or previous value for the + part of the pair not written by the call. A possible fix for + this would be to only check this aspect when writing the + control reg. + + Work around this by first using an inoffensive address, which is + guaranteed to hit the offset == 0 case in + hw_breakpoint_arch_parse. */ + unsigned int aligned_address = address & ~0x7U; + if (aligned_address != address) + { + sethbpregs_hwbp_address (pid, i, aligned_address); + sethbpregs_hwbp_control (pid, i, control); + } + sethbpregs_hwbp_address (pid, i, address); + sethbpregs_hwbp_control (pid, i, control); + } arm_lwp_info->bpts_changed[i] = 0; } diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index f36ce63..6b235a0 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -712,7 +712,6 @@ arm_find_mapping_symbol (CORE_ADDR memaddr, CORE_ADDR *start) int arm_pc_is_thumb (struct gdbarch *gdbarch, CORE_ADDR memaddr) { - struct bound_minimal_symbol sym; char type; arm_displaced_step_copy_insn_closure *dsc = nullptr; arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch); @@ -752,7 +751,7 @@ arm_pc_is_thumb (struct gdbarch *gdbarch, CORE_ADDR memaddr) return type == 't'; /* Thumb functions have a "special" bit set in minimal symbols. */ - sym = lookup_minimal_symbol_by_pc (memaddr); + bound_minimal_symbol sym = lookup_minimal_symbol_by_pc (memaddr); if (sym.minsym) return (MSYMBOL_IS_SPECIAL (sym.minsym)); @@ -913,9 +912,8 @@ static int skip_prologue_function (struct gdbarch *gdbarch, CORE_ADDR pc, int is_thumb) { enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); - struct bound_minimal_symbol msym; - msym = lookup_minimal_symbol_by_pc (pc); + bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (pc); if (msym.minsym != NULL && msym.value_address () == pc && msym.minsym->linkage_name () != NULL) @@ -1684,7 +1682,6 @@ arm_skip_stack_protector(CORE_ADDR pc, struct gdbarch *gdbarch) { enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); unsigned int basereg; - struct bound_minimal_symbol stack_chk_guard; int offset; int is_thumb = arm_pc_is_thumb (gdbarch, pc); CORE_ADDR addr; @@ -1695,7 +1692,7 @@ arm_skip_stack_protector(CORE_ADDR pc, struct gdbarch *gdbarch) if (!addr) return pc; - stack_chk_guard = lookup_minimal_symbol_by_pc (addr); + bound_minimal_symbol stack_chk_guard = lookup_minimal_symbol_by_pc (addr); /* ADDR must correspond to a symbol whose name is __stack_chk_guard. Otherwise, this sequence cannot be for stack protector. */ if (stack_chk_guard.minsym == NULL @@ -9391,9 +9388,8 @@ arm_skip_cmse_entry (CORE_ADDR pc, const char *name, struct objfile *objfile) char *target_name = (char *) alloca (target_len); xsnprintf (target_name, target_len, "%s%s", "__acle_se_", name); - struct bound_minimal_symbol minsym - = lookup_minimal_symbol (target_name, NULL, objfile); - + bound_minimal_symbol minsym + = lookup_minimal_symbol (current_program_space, target_name, objfile); if (minsym.minsym != nullptr) return minsym.value_address (); @@ -9467,7 +9463,6 @@ arm_skip_stub (const frame_info_ptr &frame, CORE_ADDR pc) { char *target_name; int target_len = namelen - 2; - struct bound_minimal_symbol minsym; struct objfile *objfile; struct obj_section *sec; @@ -9482,7 +9477,8 @@ arm_skip_stub (const frame_info_ptr &frame, CORE_ADDR pc) sec = find_pc_section (pc); objfile = (sec == NULL) ? NULL : sec->objfile; - minsym = lookup_minimal_symbol (target_name, NULL, objfile); + bound_minimal_symbol minsym + = lookup_minimal_symbol (current_program_space, target_name, objfile); if (minsym.minsym != NULL) return minsym.value_address (); else @@ -9508,7 +9504,7 @@ arm_update_current_architecture (void) /* Update the architecture. */ gdbarch_info info; - if (!gdbarch_update_p (info)) + if (!gdbarch_update_p (current_inferior (), info)) internal_error (_("could not update architecture")); } diff --git a/gdb/arm-wince-tdep.c b/gdb/arm-wince-tdep.c index eab496c..403795f 100644 --- a/gdb/arm-wince-tdep.c +++ b/gdb/arm-wince-tdep.c @@ -40,7 +40,6 @@ arm_pe_skip_trampoline_code (const frame_info_ptr &frame, CORE_ADDR pc) struct gdbarch *gdbarch = get_frame_arch (frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ULONGEST indirect; - struct bound_minimal_symbol indsym; const char *symname; CORE_ADDR next_pc; @@ -61,7 +60,7 @@ arm_pe_skip_trampoline_code (const frame_info_ptr &frame, CORE_ADDR pc) if (indirect == 0) return 0; - indsym = lookup_minimal_symbol_by_pc (indirect); + bound_minimal_symbol indsym = lookup_minimal_symbol_by_pc (indirect); if (indsym.minsym == NULL) return 0; @@ -100,7 +99,7 @@ arm_wince_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) long offset = sign_extend (this_instr & 0x000fffff, 23) << 2; CORE_ADDR call_dest = (pc + 8 + offset) & 0xffffffffU; - struct bound_minimal_symbol s = lookup_minimal_symbol_by_pc (call_dest); + bound_minimal_symbol s = lookup_minimal_symbol_by_pc (call_dest); if (s.minsym != NULL && s.minsym->linkage_name () != NULL diff --git a/gdb/auto-load.c b/gdb/auto-load.c index afc98eb..839be08 100644 --- a/gdb/auto-load.c +++ b/gdb/auto-load.c @@ -783,7 +783,7 @@ auto_load_objfile_script_1 (struct objfile *objfile, const char *realname, /* Add this script to the hash table too so "info auto-load ${lang}-scripts" can print it. */ pspace_info - = get_auto_load_pspace_data_for_loading (objfile->pspace); + = get_auto_load_pspace_data_for_loading (objfile->pspace ()); maybe_add_script_file (pspace_info, is_safe, debugfile, debugfile, language); @@ -1048,7 +1048,7 @@ source_section_scripts (struct objfile *objfile, const char *section_name, const char *start, const char *end) { auto_load_pspace_info *pspace_info - = get_auto_load_pspace_data_for_loading (objfile->pspace); + = get_auto_load_pspace_data_for_loading (objfile->pspace ()); for (const char *p = start; p < end; ++p) { @@ -81,7 +81,6 @@ ld_so_xfer_auxv (gdb_byte *readbuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) { - struct bound_minimal_symbol msym; CORE_ADDR data_address, pointer_address; gdbarch *arch = current_inferior ()->arch (); type *ptr_type = builtin_type (arch)->builtin_data_ptr; @@ -91,7 +90,8 @@ ld_so_xfer_auxv (gdb_byte *readbuf, LONGEST retval; size_t block; - msym = lookup_minimal_symbol ("_dl_auxv", NULL, NULL); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, "_dl_auxv"); if (msym.minsym == NULL) return TARGET_XFER_E_IO; diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c index 1e39f85..9c97d3c 100644 --- a/gdb/avr-tdep.c +++ b/gdb/avr-tdep.c @@ -530,7 +530,6 @@ avr_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR pc_beg, CORE_ADDR pc_end, int i; unsigned short insn; int scan_stage = 0; - struct bound_minimal_symbol msymbol; unsigned char prologue[AVR_MAX_PROLOGUE_SIZE]; int vpc = 0; int len; @@ -623,7 +622,8 @@ avr_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR pc_beg, CORE_ADDR pc_end, body_addr |= ((insn & 0xf) | ((insn & 0x0f00) >> 4)) << 8; pc_offset += 2; - msymbol = lookup_minimal_symbol ("__prologue_saves__", NULL, NULL); + bound_minimal_symbol msymbol + = lookup_minimal_symbol (current_program_space, "__prologue_saves__"); if (!msymbol.minsym) break; diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c index ab5e800..3d61901 100644 --- a/gdb/ax-gdb.c +++ b/gdb/ax-gdb.c @@ -598,9 +598,9 @@ gen_var_ref (struct agent_expr *ax, struct axs_value *value, struct symbol *var) case LOC_UNRESOLVED: { - struct bound_minimal_symbol msym - = lookup_minimal_symbol (var->linkage_name (), NULL, NULL); - + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, + var->linkage_name ()); if (!msym.minsym) error (_("Couldn't resolve symbol `%s'."), var->print_name ()); diff --git a/gdb/block.c b/gdb/block.c index 511689c..acf21e2 100644 --- a/gdb/block.c +++ b/gdb/block.c @@ -227,7 +227,7 @@ call_site_for_pc (struct gdbarch *gdbarch, CORE_ADDR pc) if (cs == nullptr) { - struct bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (pc); + bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (pc); /* DW_TAG_gnu_call_site will be missing just if GCC could not determine the call target. */ @@ -438,7 +438,7 @@ get_block_compunit_symtab (const struct block *block) static void initialize_block_iterator (const struct block *block, struct block_iterator *iter, - const lookup_name_info *name = nullptr) + const lookup_name_info *name) { enum block_enum which; struct compunit_symtab *cu; diff --git a/gdb/blockframe.c b/gdb/blockframe.c index 55e82fb..7275eb1 100644 --- a/gdb/blockframe.c +++ b/gdb/blockframe.c @@ -85,7 +85,6 @@ CORE_ADDR get_pc_function_start (CORE_ADDR pc) { const struct block *bl; - struct bound_minimal_symbol msymbol; bl = block_for_pc (pc); if (bl) @@ -99,7 +98,7 @@ get_pc_function_start (CORE_ADDR pc) } } - msymbol = lookup_minimal_symbol_by_pc (pc); + bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc); if (msymbol.minsym) { CORE_ADDR fstart = msymbol.value_address (); @@ -216,9 +215,9 @@ find_pc_partial_function_sym (CORE_ADDR pc, { struct obj_section *section; struct symbol *f; - struct bound_minimal_symbol msymbol; struct compunit_symtab *compunit_symtab = NULL; CORE_ADDR mapped_pc; + bound_minimal_symbol msymbol; /* To ensure that the symbol returned belongs to the correct section (and that the last [random] symbol from the previous section diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index a973518..17bd627 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -283,9 +283,6 @@ static bool strace_marker_p (struct breakpoint *b); static void bkpt_probe_create_sals_from_location_spec (location_spec *locspec, struct linespec_result *canonical); -static void tracepoint_probe_create_sals_from_location_spec - (location_spec *locspec, - struct linespec_result *canonical); const struct breakpoint_ops code_breakpoint_ops = { @@ -300,10 +297,11 @@ static const struct breakpoint_ops bkpt_probe_breakpoint_ops = create_breakpoints_sal, }; -/* Tracepoints set on probes. */ +/* Tracepoints set on probes. We use the same methods as for breakpoints + on probes. */ static const struct breakpoint_ops tracepoint_probe_breakpoint_ops = { - tracepoint_probe_create_sals_from_location_spec, + bkpt_probe_create_sals_from_location_spec, create_breakpoints_sal, }; @@ -3468,7 +3466,7 @@ create_internal_breakpoint (struct gdbarch *gdbarch, static struct breakpoint * create_internal_breakpoint (struct gdbarch *gdbarch, - struct bound_minimal_symbol &msym, enum bptype type) + bound_minimal_symbol &msym, enum bptype type) { CORE_ADDR address; @@ -3500,10 +3498,10 @@ static const char *const longjmp_names[] = struct breakpoint_objfile_data { /* Minimal symbol for "_ovly_debug_event" (if any). */ - struct bound_minimal_symbol overlay_msym; + bound_minimal_symbol overlay_msym; /* Minimal symbol(s) for "longjmp", "siglongjmp", etc. (if any). */ - struct bound_minimal_symbol longjmp_msym[NUM_LONGJMP_NAMES]; + bound_minimal_symbol longjmp_msym[NUM_LONGJMP_NAMES]; /* True if we have looked for longjmp probes. */ int longjmp_searched = 0; @@ -3513,10 +3511,10 @@ struct breakpoint_objfile_data std::vector<probe *> longjmp_probes; /* Minimal symbol for "std::terminate()" (if any). */ - struct bound_minimal_symbol terminate_msym; + bound_minimal_symbol terminate_msym; /* Minimal symbol for "_Unwind_DebugHook" (if any). */ - struct bound_minimal_symbol exception_msym; + bound_minimal_symbol exception_msym; /* True if we have looked for exception probes. */ int exception_searched = 0; @@ -3572,9 +3570,9 @@ create_overlay_event_breakpoint (void) if (bp_objfile_data->overlay_msym.minsym == NULL) { - struct bound_minimal_symbol m; - - m = lookup_minimal_symbol_text (func_name, objfile); + bound_minimal_symbol m + = lookup_minimal_symbol_text (current_program_space, func_name, + objfile); if (m.minsym == NULL) { /* Avoid future lookups in this objfile. */ @@ -3677,9 +3675,9 @@ create_longjmp_master_breakpoint_names (objfile *objfile) func_name = longjmp_names[i]; if (bp_objfile_data->longjmp_msym[i].minsym == NULL) { - struct bound_minimal_symbol m; - - m = lookup_minimal_symbol_text (func_name, objfile); + bound_minimal_symbol m + = lookup_minimal_symbol_text (objfile->pspace (), func_name, + objfile); if (m.minsym == NULL) { /* Prevent future lookups in this objfile. */ @@ -3710,7 +3708,7 @@ create_longjmp_master_breakpoint (void) { set_current_program_space (pspace); - for (objfile *obj : current_program_space->objfiles ()) + for (objfile *obj : pspace->objfiles ()) { /* Skip separate debug object, it's handled in the loop below. */ if (obj->separate_debug_objfile_backlink != nullptr) @@ -3736,14 +3734,13 @@ create_std_terminate_master_breakpoint (void) const char *const func_name = "std::terminate()"; scoped_restore_current_program_space restore_pspace; - scoped_restore_current_language save_language; - set_language (language_cplus); + scoped_restore_current_language save_language (language_cplus); for (struct program_space *pspace : program_spaces) { set_current_program_space (pspace); - for (objfile *objfile : current_program_space->objfiles ()) + for (objfile *objfile : pspace->objfiles ()) { struct breakpoint *b; struct breakpoint_objfile_data *bp_objfile_data; @@ -3755,9 +3752,9 @@ create_std_terminate_master_breakpoint (void) if (bp_objfile_data->terminate_msym.minsym == NULL) { - struct bound_minimal_symbol m; - - m = lookup_minimal_symbol (func_name, NULL, objfile); + bound_minimal_symbol m + = lookup_minimal_symbol (current_program_space, func_name, + objfile); if (m.minsym == NULL || (m.minsym->type () != mst_text && m.minsym->type () != mst_file_text)) { @@ -3848,9 +3845,8 @@ create_exception_master_breakpoint_hook (objfile *objfile) if (bp_objfile_data->exception_msym.minsym == NULL) { - struct bound_minimal_symbol debug_hook; - - debug_hook = lookup_minimal_symbol_text (func_name, objfile); + bound_minimal_symbol debug_hook + = lookup_minimal_symbol_text (objfile->pspace (), func_name, objfile); if (debug_hook.minsym == NULL) { bp_objfile_data->exception_msym.minsym = &msym_not_found; @@ -6592,7 +6588,7 @@ print_one_breakpoint_location (struct breakpoint *b, } } - if (loc != NULL && !header_of_multiple) + if (loc != nullptr && !header_of_multiple && !loc->shlib_disabled) { std::vector<int> inf_nums; int mi_only = 1; @@ -8092,7 +8088,7 @@ disable_breakpoints_in_freed_objfile (struct objfile *objfile) if (loc.shlib_disabled != 0) continue; - if (objfile->pspace != loc.pspace) + if (objfile->pspace () != loc.pspace) continue; if (loc.loc_type != bp_loc_hardware_breakpoint @@ -8825,8 +8821,6 @@ static void parse_breakpoint_sals (location_spec *locspec, struct linespec_result *canonical) { - struct symtab_and_line cursal; - if (locspec->type () == LINESPEC_LOCATION_SPEC) { const char *spec @@ -8875,7 +8869,8 @@ parse_breakpoint_sals (location_spec *locspec, ObjC: However, don't match an Objective-C method name which may have a '+' or '-' succeeded by a '['. */ - cursal = get_current_source_symtab_and_line (); + symtab_and_line cursal + = get_current_source_symtab_and_line (current_program_space); if (last_displayed_sal_is_valid ()) { const char *spec = NULL; @@ -12406,17 +12401,6 @@ tracepoint::print_recreate (struct ui_file *fp) const gdb_printf (fp, " passcount %d\n", pass_count); } -/* Virtual table for tracepoints on static probes. */ - -static void -tracepoint_probe_create_sals_from_location_spec - (location_spec *locspec, - struct linespec_result *canonical) -{ - /* We use the same method for breakpoint on probes. */ - bkpt_probe_create_sals_from_location_spec (locspec, canonical); -} - void dprintf_breakpoint::re_set () { @@ -12933,6 +12917,13 @@ locations_are_equal (const bp_location_list &a, const bp_location_range &b) if (a_iter->disabled_by_cond != b_iter->disabled_by_cond) return false; + + /* When a breakpoint is set by address, it is not created as + pending; but then during an solib event or the like it may + acquire a symbol. So, check this here. */ + if (a_iter->symbol != b_iter->symbol + || a_iter->msymbol != b_iter->msymbol) + return false; } return (a_iter == a.end ()) == (b_iter == b.end ()); @@ -13215,17 +13206,6 @@ create_sals_from_location_spec_default (location_spec *locspec, parse_breakpoint_sals (locspec, canonical); } -/* Reset a breakpoint. */ - -static void -breakpoint_re_set_one (breakpoint *b) -{ - input_radix = b->input_radix; - set_language (b->language); - - b->re_set (); -} - /* Re-set breakpoint locations for the current program space. Locations bound to other program spaces are left untouched. */ @@ -13237,12 +13217,11 @@ breakpoint_re_set (void) scoped_restore save_input_radix = make_scoped_restore (&input_radix); scoped_restore_current_pspace_and_thread restore_pspace_thread; - /* breakpoint_re_set_one sets the current_language to the language - of the breakpoint it is resetting (see prepare_re_set_context) - before re-evaluating the breakpoint's location. This change can - unfortunately get undone by accident if the language_mode is set - to auto, and we either switch frames, or more likely in this context, - we select the current frame. + /* To ::re_set each breakpoint we set the current_language to the + language of the breakpoint before re-evaluating the breakpoint's + location. This change can unfortunately get undone by accident if + the language_mode is set to auto, and we either switch frames, or + more likely in this context, we select the current frame. We prevent this by temporarily turning the language_mode to language_mode_manual. We restore it once all breakpoints @@ -13259,7 +13238,9 @@ breakpoint_re_set (void) { try { - breakpoint_re_set_one (&b); + input_radix = b.input_radix; + set_language (b.language); + b.re_set (); } catch (const gdb_exception &ex) { diff --git a/gdb/bsd-uthread.c b/gdb/bsd-uthread.c index a686f17..eb1ed42 100644 --- a/gdb/bsd-uthread.c +++ b/gdb/bsd-uthread.c @@ -157,9 +157,8 @@ static int bsd_uthread_active; static CORE_ADDR bsd_uthread_lookup_address (const char *name, struct objfile *objfile) { - struct bound_minimal_symbol sym; - - sym = lookup_minimal_symbol (name, NULL, objfile); + bound_minimal_symbol sym + = lookup_minimal_symbol (current_program_space, name, objfile); if (sym.minsym) return sym.value_address (); diff --git a/gdb/btrace.c b/gdb/btrace.c index 66f20ee..95ff27c 100644 --- a/gdb/btrace.c +++ b/gdb/btrace.c @@ -32,6 +32,7 @@ #include "gdbsupport/rsp-low.h" #include "cli/cli-cmds.h" #include "cli/cli-utils.h" +#include "extension.h" #include "gdbarch.h" /* For maintenance commands. */ @@ -40,6 +41,7 @@ #include <inttypes.h> #include <ctype.h> #include <algorithm> +#include <string> /* Command lists for btrace maintenance commands. */ static struct cmd_list_element *maint_btrace_cmdlist; @@ -547,7 +549,6 @@ ftrace_new_gap (struct btrace_thread_info *btinfo, int errcode, static struct btrace_function * ftrace_update_function (struct btrace_thread_info *btinfo, CORE_ADDR pc) { - struct bound_minimal_symbol bmfun; struct minimal_symbol *mfun; struct symbol *fun; struct btrace_function *bfun; @@ -556,7 +557,7 @@ ftrace_update_function (struct btrace_thread_info *btinfo, CORE_ADDR pc) to avoid surprises when we sometimes get a full symbol and sometimes only a minimal symbol. */ fun = find_pc_function (pc); - bmfun = lookup_minimal_symbol_by_pc (pc); + bound_minimal_symbol bmfun = lookup_minimal_symbol_by_pc (pc); mfun = bmfun.minsym; if (fun == NULL && mfun == NULL) @@ -665,6 +666,9 @@ ftrace_update_insns (struct btrace_function *bfun, const btrace_insn &insn) { bfun->insn.push_back (insn); + if (insn.iclass == BTRACE_INSN_AUX) + bfun->flags |= BFUN_CONTAINS_AUX; + if (record_debug > 1) ftrace_debug (bfun, "update insn"); } @@ -1201,6 +1205,24 @@ pt_btrace_insn (const struct pt_insn &insn) pt_btrace_insn_flags (insn)}; } +#if defined (HAVE_PT_INSN_EVENT) +/* Helper for events that will result in an aux_insn. */ + +static void +handle_pt_aux_insn (btrace_thread_info *btinfo, btrace_function *bfun, + std::string &aux_str, CORE_ADDR ip) +{ + btinfo->aux_data.emplace_back (std::move (aux_str)); + bfun = ftrace_update_function (btinfo, ip); + + btrace_insn insn {btinfo->aux_data.size () - 1, 0, + BTRACE_INSN_AUX, 0}; + + ftrace_update_insns (bfun, insn); +} + +#endif /* defined (HAVE_PT_INSN_EVENT) */ + /* Handle instruction decode events (libipt-v2). */ static int @@ -1249,6 +1271,60 @@ handle_pt_insn_events (struct btrace_thread_info *btinfo, bfun->insn_offset - 1, offset); break; +#if defined (HAVE_STRUCT_PT_EVENT_VARIANT_PTWRITE) + case ptev_ptwrite: + { + uint64_t pc = 0; + std::optional<std::string> ptw_string; + + /* Lookup the PC if available. The event often doesn't provide + one, so we look into the last function segment as well. + Looking further back makes limited sense for ptwrite. */ + if (event.ip_suppressed == 0) + pc = event.variant.ptwrite.ip; + else if (!btinfo->functions.empty ()) + { + std::vector<btrace_insn> &insns + = btinfo->functions.back ().insn; + for (auto insn = insns.rbegin (); insn != insns.rend (); + ++insn) + { + switch (insn->iclass) + { + case BTRACE_INSN_AUX: + continue; + + case BTRACE_INSN_OTHER: + case BTRACE_INSN_CALL: + case BTRACE_INSN_RETURN: + case BTRACE_INSN_JUMP: + pc = insn->pc; + break; + /* No default to rely on compiler warnings. */ + } + break; + } + } + + if (pc == 0) + warning (_("Failed to determine the PC for ptwrite.")); + + if (btinfo->ptw_callback_fun != nullptr) + ptw_string + = btinfo->ptw_callback_fun (event.variant.ptwrite.payload, + pc, btinfo->ptw_context); + + if (ptw_string.has_value () && (*ptw_string).empty ()) + continue; + + if (!ptw_string.has_value ()) + *ptw_string = hex_string (event.variant.ptwrite.payload); + + handle_pt_aux_insn (btinfo, bfun, *ptw_string, pc); + + break; + } +#endif /* defined (HAVE_STRUCT_PT_EVENT_VARIANT_PTWRITE) */ } } #endif /* defined (HAVE_PT_INSN_EVENT) */ @@ -1314,6 +1390,9 @@ ftrace_add_pt (struct btrace_thread_info *btinfo, uint64_t offset; int status; + /* Register the ptwrite filter. */ + apply_ext_lang_ptwrite_filter (btinfo); + for (;;) { struct pt_insn insn; @@ -1820,6 +1899,8 @@ btrace_clear_history (struct btrace_thread_info *btinfo) btinfo->insn_history = NULL; btinfo->call_history = NULL; btinfo->replay = NULL; + + btinfo->aux_data.clear (); } /* Clear the branch trace maintenance histories in BTINFO. */ @@ -2649,6 +2730,14 @@ pt_print_packet (const struct pt_packet *packet) case ppt_mnt: gdb_printf (("mnt %" PRIx64 ""), packet->payload.mnt.payload); break; + +#if (LIBIPT_VERSION >= 0x200) + case ppt_ptw: + gdb_printf (("ptw %u: 0x%" PRIx64 "%s"), packet->payload.ptw.plc, + packet->payload.ptw.payload, + packet->payload.ptw.ip ? (" ip") : ("")); + break; +#endif /* defined (LIBIPT_VERSION >= 0x200) */ } } diff --git a/gdb/btrace.h b/gdb/btrace.h index f05ec2b..34f8d2b 100644 --- a/gdb/btrace.h +++ b/gdb/btrace.h @@ -35,6 +35,7 @@ #endif #include <vector> +#include <string> struct thread_info; struct btrace_function; @@ -52,7 +53,10 @@ enum btrace_insn_class BTRACE_INSN_RETURN, /* The instruction is an unconditional jump. */ - BTRACE_INSN_JUMP + BTRACE_INSN_JUMP, + + /* The instruction is a pseudo instruction containing auxiliary data. */ + BTRACE_INSN_AUX }; /* Instruction flags. */ @@ -68,8 +72,19 @@ DEF_ENUM_FLAGS_TYPE (enum btrace_insn_flag, btrace_insn_flags); This represents a single instruction in a branch trace. */ struct btrace_insn { - /* The address of this instruction. */ - CORE_ADDR pc; + union + { + /* The address of this instruction. Applies to btrace_insn with + iclass == BTRACE_INSN_OTHER or + iclass == BTRACE_INSN_CALL or + iclass == BTRACE_INSN_RETURN or + iclass == BTRACE_INSN_JUMP. */ + CORE_ADDR pc; + + /* Index into btrace_info::aux_data. Applies to btrace_insn with + iclass == BTRACE_INSN_AUX. */ + uint64_t aux_data_index; + }; /* The size of this instruction in bytes. */ gdb_byte size; @@ -91,7 +106,11 @@ enum btrace_function_flag /* The 'up' link points to a tail call. This obviously only makes sense if bfun_up_links_to_ret is clear. */ - BFUN_UP_LINKS_TO_TAILCALL = (1 << 1) + BFUN_UP_LINKS_TO_TAILCALL = (1 << 1), + + /* Indicates that at least one auxiliary instruction is in the current + function segment. */ + BFUN_CONTAINS_AUX = (1 << 2) }; DEF_ENUM_FLAGS_TYPE (enum btrace_function_flag, btrace_function_flags); @@ -330,6 +349,20 @@ struct btrace_thread_info function segment i will be at index (i - 1). */ std::vector<btrace_function> functions; + /* Optional auxiliary information that is printed in all commands + displaying or stepping through the execution history. */ + std::vector<std::string> aux_data; + + /* Function pointer to the ptwrite callback. Returns the string returned + by the ptwrite filter function. */ + std::optional<std::string> (*ptw_callback_fun) (const uint64_t payload, + const uint64_t ip, + const void *ptw_context) + = nullptr; + + /* Context for the ptw_callback_fun. */ + void *ptw_context = nullptr; + /* The function level offset. When added to each function's LEVEL, this normalizes the function levels such that the smallest level becomes zero. */ diff --git a/gdb/build-id.c b/gdb/build-id.c index 8ce94f1..32fbe17 100644 --- a/gdb/build-id.c +++ b/gdb/build-id.c @@ -73,50 +73,149 @@ build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check) return retval; } -/* Helper for build_id_to_debug_bfd. LINK is a path to a potential - build-id-based separate debug file, potentially a symlink to the real file. - If the file exists and matches BUILD_ID, return a BFD reference to it. */ +/* Helper for build_id_to_debug_bfd. ORIGINAL_LINK with SUFFIX appended is + a path to a potential build-id-based separate debug file, potentially a + symlink to the real file. If the file exists and matches BUILD_ID, + return a BFD reference to it. */ static gdb_bfd_ref_ptr -build_id_to_debug_bfd_1 (const std::string &link, size_t build_id_len, - const bfd_byte *build_id) +build_id_to_debug_bfd_1 (const std::string &original_link, + size_t build_id_len, const bfd_byte *build_id, + const char *suffix) { - separate_debug_file_debug_printf ("Trying %s...", link.c_str ()); - - /* lrealpath() is expensive even for the usually non-existent files. */ - gdb::unique_xmalloc_ptr<char> filename_holder; - const char *filename = nullptr; - if (is_target_filename (link)) - filename = link.c_str (); - else if (access (link.c_str (), F_OK) == 0) + tribool supports_target_stat = TRIBOOL_UNKNOWN; + + /* Drop the 'target:' prefix if the target filesystem is local. */ + std::string_view original_link_view (original_link); + if (is_target_filename (original_link) && target_filesystem_is_local ()) + original_link_view + = original_link_view.substr (strlen (TARGET_SYSROOT_PREFIX)); + + /* The upper bound of '10' here is completely arbitrary. The loop should + terminate via 'break' when either (a) a readable symlink is found, or + (b) a non-existing entry is found. + + However, for remote targets, we rely on the remote returning sane + error codes. If a remote sends back the wrong error code then it + might trick GDB into thinking that the symlink exists, but points to a + missing file, in which case GDB will try the next seqno. We don't + want a broken remote to cause GDB to spin here forever, hence a fixed + upper bound. */ + + for (unsigned seqno = 0; seqno < 10; seqno++) { - filename_holder.reset (lrealpath (link.c_str ())); - filename = filename_holder.get (); - } + std::string link (original_link_view); - if (filename == NULL) - { - separate_debug_file_debug_printf ("unable to compute real path"); - return {}; - } + if (seqno > 0) + string_appendf (link, ".%u", seqno); - /* We expect to be silent on the non-existing files. */ - gdb_bfd_ref_ptr debug_bfd = gdb_bfd_open (filename, gnutarget); + link += suffix; - if (debug_bfd == NULL) - { - separate_debug_file_debug_printf ("unable to open."); - return {}; - } + separate_debug_file_debug_printf ("Trying %s...", link.c_str ()); - if (!build_id_verify (debug_bfd.get(), build_id_len, build_id)) - { - separate_debug_file_debug_printf ("build-id does not match."); - return {}; + gdb::unique_xmalloc_ptr<char> filename_holder; + const char *filename = nullptr; + if (is_target_filename (link)) + { + gdb_assert (link.length () >= strlen (TARGET_SYSROOT_PREFIX)); + const char *link_on_target + = link.c_str () + strlen (TARGET_SYSROOT_PREFIX); + + fileio_error target_errno; + if (supports_target_stat != TRIBOOL_FALSE) + { + struct stat sb; + int res = target_fileio_stat (nullptr, link_on_target, &sb, + &target_errno); + + if (res != 0 && target_errno != FILEIO_ENOSYS) + { + separate_debug_file_debug_printf ("path doesn't exist"); + break; + } + else if (res != 0 && target_errno == FILEIO_ENOSYS) + supports_target_stat = TRIBOOL_FALSE; + else + { + supports_target_stat = TRIBOOL_TRUE; + filename = link.c_str (); + } + } + + if (supports_target_stat == TRIBOOL_FALSE) + { + gdb_assert (filename == nullptr); + + /* Connecting to a target that doesn't support 'stat'. Try + 'readlink' as an alternative. This isn't ideal, but is + maybe better than nothing. Returns EINVAL if the path + isn't a symbolic link, which hints that the path is + available -- there are other errors e.g. ENOENT for when + the path doesn't exist, but we just assume that anything + other than EINVAL indicates the path doesn't exist. */ + std::optional<std::string> link_target + = target_fileio_readlink (nullptr, link_on_target, + &target_errno); + if (link_target.has_value () + || target_errno == FILEIO_EINVAL) + filename = link.c_str (); + else + { + separate_debug_file_debug_printf ("path doesn't exist"); + break; + } + } + } + else + { + struct stat buf; + + /* The `access' call below automatically dereferences LINK, but + we want to stop incrementing SEQNO once we find a symlink + that doesn't exist. */ + if (lstat (link.c_str (), &buf) != 0) + { + separate_debug_file_debug_printf ("path doesn't exist"); + break; + } + + /* Can LINK be accessed, or if LINK is a symlink, can the file + pointed too be accessed? Do this as lrealpath() is + expensive, even for the usually non-existent files. */ + if (access (link.c_str (), F_OK) == 0) + { + filename_holder.reset (lrealpath (link.c_str ())); + filename = filename_holder.get (); + } + } + + if (filename == nullptr) + { + separate_debug_file_debug_printf ("unable to compute real path"); + continue; + } + + /* We expect to be silent on the non-existing files. */ + gdb_bfd_ref_ptr debug_bfd = gdb_bfd_open (filename, gnutarget); + + if (debug_bfd == NULL) + { + separate_debug_file_debug_printf ("unable to open `%s`", filename); + continue; + } + + if (!build_id_verify (debug_bfd.get(), build_id_len, build_id)) + { + separate_debug_file_debug_printf ("build-id does not match"); + continue; + } + + separate_debug_file_debug_printf ("found a match"); + return debug_bfd; } - separate_debug_file_debug_printf ("found a match"); - return debug_bfd; + separate_debug_file_debug_printf ("no suitable file found"); + return {}; } /* Common code for finding BFDs of a given build-id. This function @@ -156,10 +255,8 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id, while (size-- > 0) string_appendf (link, "%02x", (unsigned) *data++); - link += suffix; - gdb_bfd_ref_ptr debug_bfd - = build_id_to_debug_bfd_1 (link, build_id_len, build_id); + = build_id_to_debug_bfd_1 (link, build_id_len, build_id, suffix); if (debug_bfd != NULL) return debug_bfd; @@ -176,7 +273,8 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id, || !target_filesystem_is_local ())) { link = gdb_sysroot + link; - debug_bfd = build_id_to_debug_bfd_1 (link, build_id_len, build_id); + debug_bfd = build_id_to_debug_bfd_1 (link, build_id_len, build_id, + suffix); if (debug_bfd != NULL) return debug_bfd; } diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 6022317..ca411dc 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -1210,10 +1210,11 @@ variable: name_not_typename std::string arg = copy_name ($1.stoken); bound_minimal_symbol msymbol - = lookup_bound_minimal_symbol (arg.c_str ()); + = lookup_minimal_symbol (current_program_space, arg.c_str ()); if (msymbol.minsym == NULL) { - if (!have_full_symbols () && !have_partial_symbols ()) + if (!have_full_symbols (current_program_space) + && !have_partial_symbols (current_program_space)) error (_("No symbol table is loaded. Use the \"file\" command.")); else error (_("No symbol \"%s\" in current context."), @@ -3149,7 +3150,7 @@ classify_name (struct parser_state *par_state, const struct block *block, if (bsym.symbol == NULL && par_state->language ()->la_language == language_cplus && is_a_field_of_this.type == NULL - && lookup_minimal_symbol (copy.c_str (), NULL, NULL).minsym == NULL) + && lookup_minimal_symbol (current_program_space, copy.c_str ()).minsym == nullptr) return UNKNOWN_CPP_NAME; return NAME; diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c index ca24b15..bad9490 100644 --- a/gdb/c-valprint.c +++ b/gdb/c-valprint.c @@ -176,8 +176,7 @@ print_unpacked_pointer (struct type *type, struct type *elttype, { /* Print vtbl's nicely. */ CORE_ADDR vt_address = unpack_pointer (type, valaddr + embedded_offset); - struct bound_minimal_symbol msymbol = - lookup_minimal_symbol_by_pc (vt_address); + bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (vt_address); /* If 'symbol_print' is set, we did the work above. */ if (!options->symbol_print diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c index 3af794c..92bb8fc 100644 --- a/gdb/cli/cli-cmds.c +++ b/gdb/cli/cli-cmds.c @@ -984,7 +984,7 @@ edit_command (const char *arg, int from_tty) if (arg == 0) { set_default_source_symtab_and_line (); - sal = get_current_source_symtab_and_line (); + sal = get_current_source_symtab_and_line (current_program_space); } /* Bare "edit" edits file with present line. */ @@ -1240,7 +1240,8 @@ list_command (const char *arg, int from_tty) if (get_first_line_listed () == 0 && (arg == nullptr || arg[0] != '.')) { set_default_source_symtab_and_line (); - list_around_line (arg, get_current_source_symtab_and_line ()); + list_around_line + (arg, get_current_source_symtab_and_line (current_program_space)); } /* "l" and "l +" lists the next few lines, unless we're listing past @@ -1248,7 +1249,8 @@ list_command (const char *arg, int from_tty) else if (arg == nullptr || arg[0] == '+') { set_default_source_symtab_and_line (); - const symtab_and_line cursal = get_current_source_symtab_and_line (); + const symtab_and_line cursal + = get_current_source_symtab_and_line (current_program_space); if (last_symtab_line (cursal.symtab) >= cursal.line) print_source_lines (cursal.symtab, source_lines_range (cursal.line), 0); @@ -1262,7 +1264,8 @@ list_command (const char *arg, int from_tty) else if (arg[0] == '-') { set_default_source_symtab_and_line (); - const symtab_and_line cursal = get_current_source_symtab_and_line (); + const symtab_and_line cursal + = get_current_source_symtab_and_line (current_program_space); if (get_first_line_listed () == 1) error (_("Already at the start of %s."), @@ -1295,7 +1298,7 @@ list_command (const char *arg, int from_tty) { /* The inferior is not running, so reset the current source location to the default (usually the main function). */ - clear_current_source_symtab_and_line (); + clear_current_source_symtab_and_line (current_program_space); try { set_default_source_symtab_and_line (); @@ -1305,7 +1308,8 @@ list_command (const char *arg, int from_tty) error (_("Insufficient debug info for showing source " "lines at default location")); } - cursal = get_current_source_symtab_and_line (); + cursal + = get_current_source_symtab_and_line (current_program_space); gdb_assert (cursal.symtab != nullptr); } @@ -1327,7 +1331,8 @@ list_command (const char *arg, int from_tty) and clear NO_END; however, if one of the arguments is blank, set DUMMY_BEG or DUMMY_END to record that fact. */ - if (!have_full_symbols () && !have_partial_symbols ()) + if (!have_full_symbols (current_program_space) + && !have_partial_symbols (current_program_space)) error (_("No symbol table is loaded. Use the \"file\" command.")); std::vector<symtab_and_line> sals; diff --git a/gdb/coff-pe-read.c b/gdb/coff-pe-read.c index 0da4f12..ed5e533 100644 --- a/gdb/coff-pe-read.c +++ b/gdb/coff-pe-read.c @@ -174,7 +174,6 @@ add_pe_forwarded_sym (minimal_symbol_reader &reader, const char *forward_func_name, int ordinal, const char *dll_name, struct objfile *objfile) { - struct bound_minimal_symbol msymbol; enum minimal_symbol_type msymtype; int forward_dll_name_len = strlen (forward_dll_name); short section; @@ -183,15 +182,17 @@ add_pe_forwarded_sym (minimal_symbol_reader &reader, forward_dll_name, forward_func_name); - msymbol = lookup_bound_minimal_symbol (forward_qualified_name.c_str ()); - + bound_minimal_symbol msymbol + = lookup_minimal_symbol (current_program_space, + forward_qualified_name.c_str ()); if (!msymbol.minsym) { int i; for (i = 0; i < forward_dll_name_len; i++) forward_qualified_name[i] = tolower (forward_qualified_name[i]); - msymbol = lookup_bound_minimal_symbol (forward_qualified_name.c_str ()); + msymbol = lookup_minimal_symbol (current_program_space, + forward_qualified_name.c_str ()); } if (!msymbol.minsym) diff --git a/gdb/coffread.c b/gdb/coffread.c index daae3ff..3e67ebd 100644 --- a/gdb/coffread.c +++ b/gdb/coffread.c @@ -574,12 +574,13 @@ coff_read_minsyms (file_ptr symtab_offset, unsigned int nsyms, { int lead = bfd_get_symbol_leading_char (objfile->obfd.get ()); - struct bound_minimal_symbol found; if (lead != '\0' && *name1 == lead) name1 += 1; - found = lookup_minimal_symbol (name1, NULL, objfile); + bound_minimal_symbol found + = lookup_minimal_symbol (current_program_space, name1, + objfile); /* If found, there are symbols named "_imp_foo" and "foo" respectively in OBJFILE. Set the type of symbol "foo" diff --git a/gdb/command.h b/gdb/command.h index 615f4e5..0ceaf3e 100644 --- a/gdb/command.h +++ b/gdb/command.h @@ -876,7 +876,7 @@ extern void cmd_show_list (struct cmd_list_element *, int); /* Used everywhere whenever at least one parameter is required and none is specified. */ -extern void error_no_arg (const char *) ATTRIBUTE_NORETURN; +[[noreturn]] extern void error_no_arg (const char *); /* Command line saving and repetition. diff --git a/gdb/compile/compile-c-symbols.c b/gdb/compile/compile-c-symbols.c index 20e8550..7a38d3a 100644 --- a/gdb/compile/compile-c-symbols.c +++ b/gdb/compile/compile-c-symbols.c @@ -259,8 +259,7 @@ convert_symbol_sym (compile_c_instance *context, const char *identifier, to use and BMSYM is the minimal symbol to convert. */ static void -convert_symbol_bmsym (compile_c_instance *context, - struct bound_minimal_symbol bmsym) +convert_symbol_bmsym (compile_c_instance *context, bound_minimal_symbol bmsym) { struct minimal_symbol *msym = bmsym.minsym; struct objfile *objfile = bmsym.objfile; @@ -356,9 +355,8 @@ gcc_convert_symbol (void *datum, } else if (request == GCC_C_ORACLE_SYMBOL) { - struct bound_minimal_symbol bmsym; - - bmsym = lookup_minimal_symbol (identifier, NULL, NULL); + bound_minimal_symbol bmsym + = lookup_minimal_symbol (current_program_space, identifier); if (bmsym.minsym != NULL) { convert_symbol_bmsym (context, bmsym); @@ -413,9 +411,8 @@ gcc_symbol_address (void *datum, struct gcc_c_context *gcc_context, } else { - struct bound_minimal_symbol msym; - - msym = lookup_bound_minimal_symbol (identifier); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, identifier); if (msym.minsym != NULL) { if (compile_debug) diff --git a/gdb/compile/compile-cplus-symbols.c b/gdb/compile/compile-cplus-symbols.c index 9b95cdd..6c482e7 100644 --- a/gdb/compile/compile-cplus-symbols.c +++ b/gdb/compile/compile-cplus-symbols.c @@ -275,7 +275,7 @@ convert_symbol_sym (compile_cplus_instance *instance, static void convert_symbol_bmsym (compile_cplus_instance *instance, - struct bound_minimal_symbol bmsym) + bound_minimal_symbol bmsym) { struct minimal_symbol *msym = bmsym.minsym; struct objfile *objfile = bmsym.objfile; @@ -453,9 +453,8 @@ gcc_cplus_symbol_address (void *datum, struct gcc_cp_context *gcc_context, } else { - struct bound_minimal_symbol msym; - - msym = lookup_bound_minimal_symbol (identifier); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, identifier); if (msym.minsym != nullptr) { if (compile_debug) diff --git a/gdb/compile/compile-object-load.c b/gdb/compile/compile-object-load.c index 08e30be..df48b1c 100644 --- a/gdb/compile/compile-object-load.c +++ b/gdb/compile/compile-object-load.c @@ -604,7 +604,6 @@ compile_object_load (const compile_file_names &file_names, CORE_ADDR regs_addr, out_value_addr = 0; struct symbol *func_sym; struct type *func_type; - struct bound_minimal_symbol bmsym; long storage_needed; asymbol **symbol_table, **symp; long number_of_symbols, missing_symbols; @@ -765,7 +764,8 @@ compile_object_load (const compile_file_names &file_names, continue; } - bmsym = lookup_minimal_symbol (sym->name, NULL, NULL); + bound_minimal_symbol bmsym + = lookup_minimal_symbol (current_program_space, sym->name); switch (bmsym.minsym == NULL ? mst_unknown : bmsym.minsym->type ()) { diff --git a/gdb/compile/compile.c b/gdb/compile/compile.c index 88531a2..8896b44 100644 --- a/gdb/compile/compile.c +++ b/gdb/compile/compile.c @@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "progspace.h" #include "ui.h" #include "ui-out.h" #include "command.h" @@ -487,7 +488,8 @@ get_expr_block_and_pc (CORE_ADDR *pc) if (block == NULL) { - struct symtab_and_line cursal = get_current_source_symtab_and_line (); + symtab_and_line cursal + = get_current_source_symtab_and_line (current_program_space); if (cursal.symtab) block = cursal.symtab->compunit ()->blockvector ()->static_block (); diff --git a/gdb/config.in b/gdb/config.in index 0c144c8..57be033 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -481,6 +481,9 @@ /* Define to 1 if `pl_tdname' is a member of `struct ptrace_lwpinfo'. */ #undef HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME +/* Define to 1 if `variant.ptwrite' is a member of `struct pt_event'. */ +#undef HAVE_STRUCT_PT_EVENT_VARIANT_PTWRITE + /* Define to 1 if `enabled' is a member of `struct pt_insn'. */ #undef HAVE_STRUCT_PT_INSN_ENABLED diff --git a/gdb/configure b/gdb/configure index 15ececf..53eaad4 100755 --- a/gdb/configure +++ b/gdb/configure @@ -21512,6 +21512,17 @@ _ACEOF fi + ac_fn_c_check_member "$LINENO" "struct pt_event" "variant.ptwrite" "ac_cv_member_struct_pt_event_variant_ptwrite" "#include <intel-pt.h> +" +if test "x$ac_cv_member_struct_pt_event_variant_ptwrite" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_PT_EVENT_VARIANT_PTWRITE 1 +_ACEOF + + +fi + LIBS=$save_LIBS fi fi @@ -24993,19 +25004,19 @@ if test "$gdb_require_amd_dbgapi" = true \ # version of the library. pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for amd-dbgapi >= 0.68.0" >&5 -$as_echo_n "checking for amd-dbgapi >= 0.68.0... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for amd-dbgapi >= 0.75.0" >&5 +$as_echo_n "checking for amd-dbgapi >= 0.75.0... " >&6; } if test -n "$AMD_DBGAPI_CFLAGS"; then pkg_cv_AMD_DBGAPI_CFLAGS="$AMD_DBGAPI_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"amd-dbgapi >= 0.68.0\""; } >&5 - ($PKG_CONFIG --exists --print-errors "amd-dbgapi >= 0.68.0") 2>&5 + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"amd-dbgapi >= 0.75.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "amd-dbgapi >= 0.75.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_AMD_DBGAPI_CFLAGS=`$PKG_CONFIG --cflags "amd-dbgapi >= 0.68.0" 2>/dev/null` + pkg_cv_AMD_DBGAPI_CFLAGS=`$PKG_CONFIG --cflags "amd-dbgapi >= 0.75.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -25017,12 +25028,12 @@ if test -n "$AMD_DBGAPI_LIBS"; then pkg_cv_AMD_DBGAPI_LIBS="$AMD_DBGAPI_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"amd-dbgapi >= 0.68.0\""; } >&5 - ($PKG_CONFIG --exists --print-errors "amd-dbgapi >= 0.68.0") 2>&5 + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"amd-dbgapi >= 0.75.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "amd-dbgapi >= 0.75.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_AMD_DBGAPI_LIBS=`$PKG_CONFIG --libs "amd-dbgapi >= 0.68.0" 2>/dev/null` + pkg_cv_AMD_DBGAPI_LIBS=`$PKG_CONFIG --libs "amd-dbgapi >= 0.75.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -25067,9 +25078,9 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - AMD_DBGAPI_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "amd-dbgapi >= 0.68.0" 2>&1` + AMD_DBGAPI_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "amd-dbgapi >= 0.75.0" 2>&1` else - AMD_DBGAPI_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "amd-dbgapi >= 0.68.0" 2>&1` + AMD_DBGAPI_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "amd-dbgapi >= 0.75.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$AMD_DBGAPI_PKG_ERRORS" >&5 @@ -31188,7 +31199,7 @@ build_warnings="-Wall -Wpointer-arith \ -Wredundant-move \ -Wmissing-declarations \ -Wstrict-null-sentinel \ --Wno-vla-cxx-extension \ +-Wvla \ " # The -Wmissing-prototypes flag will be accepted by GCC, but results diff --git a/gdb/configure.ac b/gdb/configure.ac index e70edb7..8368fea 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -281,7 +281,7 @@ if test "$gdb_require_amd_dbgapi" = true \ # stability until amd-dbgapi hits 1.0, but for convenience, still check for # greater or equal that version. It can be handy when testing with a newer # version of the library. - PKG_CHECK_MODULES([AMD_DBGAPI], [amd-dbgapi >= 0.68.0], + PKG_CHECK_MODULES([AMD_DBGAPI], [amd-dbgapi >= 0.75.0], [has_amd_dbgapi=yes], [has_amd_dbgapi=no]) if test "$has_amd_dbgapi" = "yes"; then diff --git a/gdb/configure.host b/gdb/configure.host index da71675..22855cd 100644 --- a/gdb/configure.host +++ b/gdb/configure.host @@ -110,7 +110,6 @@ i[34567]86-*-mingw32*) gdb_host=mingw i[34567]86-*-msdosdjgpp*) gdb_host=go32 ;; i[34567]86-*-linux*) gdb_host=linux ;; i[34567]86-*-gnu*) gdb_host=i386gnu ;; -i[3456]86-*-nto*) gdb_host=nto ;; i[34567]86-*-openbsd*) gdb_host=obsd ;; i[34567]86-*-solaris2* | x86_64-*-solaris2*) gdb_host=sol2 ;; diff --git a/gdb/configure.nat b/gdb/configure.nat index f88c9c2..9e78091 100644 --- a/gdb/configure.nat +++ b/gdb/configure.nat @@ -426,15 +426,6 @@ case ${gdb_host} in esac ;; - nto) - case ${gdb_host_cpu} in - i386) - # Host: Intel 386 running QNX. - NATDEPFILES='nto-procfs.o' - NAT_FILE='config/nm-nto.h' - ;; - esac - ;; obsd) case ${gdb_host_cpu} in i386) diff --git a/gdb/configure.tgt b/gdb/configure.tgt index 8326c45..8d85a59 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -59,7 +59,8 @@ amd64_tobjs="ravenscar-thread.o amd64-ravenscar-thread.o \ case "${targ}" in aarch64*-*-*) cpu_obs="aarch32-tdep.o aarch64-tdep.o arch/aarch32.o \ - arch/aarch64-insn.o arch/aarch64.o ravenscar-thread.o \ + arch/aarch64-insn.o arch/aarch64.o arch/aarch64-mte.o \ + ravenscar-thread.o \ aarch64-ravenscar-thread.o";; alpha*-*-*) @@ -304,11 +305,6 @@ i[34567]86-*-openbsd*) # Target: OpenBSD/i386 gdb_target_obs="i386-bsd-tdep.o i386-obsd-tdep.o bsd-uthread.o" ;; -i[34567]86-*-nto*) - # Target: Intel 386 running qnx6. - gdb_target_obs="solib-svr4.o \ - i386-nto-tdep.o nto-tdep.o" - ;; i[34567]86-*-solaris2* | x86_64-*-solaris2*) # Target: Solaris x86_64 gdb_target_obs="${i386_tobjs} ${amd64_tobjs} \ @@ -808,7 +804,6 @@ case "${targ}" in gdb_osabi=GDB_OSABI_FREEBSD ;; *-*-linux* | *-*-uclinux*) gdb_osabi=GDB_OSABI_LINUX ;; -*-*-nto*) gdb_osabi=GDB_OSABI_QNXNTO ;; m68*-*-openbsd* | m88*-*-openbsd* | vax-*-openbsd*) ;; *-*-openbsd*) gdb_osabi=GDB_OSABI_OPENBSD ;; *-*-solaris*) gdb_osabi=GDB_OSABI_SOLARIS ;; diff --git a/gdb/cris-tdep.c b/gdb/cris-tdep.c index 692aa9a..769b930 100644 --- a/gdb/cris-tdep.c +++ b/gdb/cris-tdep.c @@ -3883,7 +3883,7 @@ set_cris_version (const char *ignore_args, int from_tty, usr_cmd_cris_version_valid = 1; /* Update the current architecture, if needed. */ - if (!gdbarch_update_p (info)) + if (!gdbarch_update_p (current_inferior (), info)) internal_error (_("cris_gdbarch_update: failed to update architecture.")); } @@ -3894,7 +3894,7 @@ set_cris_mode (const char *ignore_args, int from_tty, struct gdbarch_info info; /* Update the current architecture, if needed. */ - if (!gdbarch_update_p (info)) + if (!gdbarch_update_p (current_inferior (), info)) internal_error ("cris_gdbarch_update: failed to update architecture."); } @@ -3905,7 +3905,7 @@ set_cris_dwarf2_cfi (const char *ignore_args, int from_tty, struct gdbarch_info info; /* Update the current architecture, if needed. */ - if (!gdbarch_update_p (info)) + if (!gdbarch_update_p (current_inferior (), info)) internal_error (_("cris_gdbarch_update: failed to update architecture.")); } diff --git a/gdb/csky-tdep.c b/gdb/csky-tdep.c index 1b6c08e..d69b8e5 100644 --- a/gdb/csky-tdep.c +++ b/gdb/csky-tdep.c @@ -2097,7 +2097,7 @@ csky_frame_unwind_cache (const frame_info_ptr &this_frame) func_size = bl->end () - bl->start (); else { - struct bound_minimal_symbol msymbol + bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (prologue_start); if (msymbol.minsym != NULL) func_size = msymbol.minsym->size (); diff --git a/gdb/ctfread.c b/gdb/ctfread.c index d8606d3..9eb9537 100644 --- a/gdb/ctfread.c +++ b/gdb/ctfread.c @@ -323,9 +323,8 @@ get_bitsize (ctf_dict_t *fp, ctf_id_t tid, uint32_t kind) static void set_symbol_address (struct objfile *of, struct symbol *sym, const char *name) { - struct bound_minimal_symbol msym; - - msym = lookup_minimal_symbol (name, nullptr, of); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, name, of); if (msym.minsym != NULL) { sym->set_value_address (msym.value_address ()); diff --git a/gdb/d-exp.y b/gdb/d-exp.y index 13d2cfa..df89cb6 100644 --- a/gdb/d-exp.y +++ b/gdb/d-exp.y @@ -435,7 +435,7 @@ PrimaryExpression: '(' Expression ')' { /* Do nothing. */ } | IdentifierExp - { struct bound_minimal_symbol msymbol; + { std::string copy = copy_name ($1); struct field_of_this_result is_a_field_of_this; struct block_symbol sym; @@ -463,10 +463,12 @@ PrimaryExpression: else { /* Lookup foreign name in global static symbols. */ - msymbol = lookup_bound_minimal_symbol (copy.c_str ()); + bound_minimal_symbol msymbol + = lookup_minimal_symbol (current_program_space, copy.c_str ()); if (msymbol.minsym != NULL) pstate->push_new<var_msym_value_operation> (msymbol); - else if (!have_full_symbols () && !have_partial_symbols ()) + else if (!have_full_symbols (current_program_space) + && !have_partial_symbols (current_program_space)) error (_("No symbol table is loaded. Use the \"file\" command")); else error (_("No symbol \"%s\" in current context."), diff --git a/gdb/d-lang.c b/gdb/d-lang.c index d4f9956..32d9cc8 100644 --- a/gdb/d-lang.c +++ b/gdb/d-lang.c @@ -38,9 +38,8 @@ static const char D_MAIN[] = "D main"; const char * d_main_name (void) { - struct bound_minimal_symbol msym; - - msym = lookup_minimal_symbol (D_MAIN, NULL, NULL); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, D_MAIN); if (msym.minsym != NULL) return D_MAIN; diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in index f529656..f9472f4 100644 --- a/gdb/data-directory/Makefile.in +++ b/gdb/data-directory/Makefile.in @@ -79,6 +79,7 @@ PYTHON_FILE_LIST = \ gdb/missing_debug.py \ gdb/printing.py \ gdb/prompt.py \ + gdb/ptwrite.py \ gdb/styling.py \ gdb/types.py \ gdb/unwinder.py \ diff --git a/gdb/dbxread.c b/gdb/dbxread.c index 830dd1c..31eb51f 100644 --- a/gdb/dbxread.c +++ b/gdb/dbxread.c @@ -891,11 +891,10 @@ set_namestring (struct objfile *objfile, const struct internal_nlist *nlist) return namestring; } -static struct bound_minimal_symbol +static bound_minimal_symbol find_stab_function (const char *namestring, const char *filename, struct objfile *objfile) { - struct bound_minimal_symbol msym; int n; const char *colon = strchr (namestring, ':'); @@ -908,7 +907,8 @@ find_stab_function (const char *namestring, const char *filename, strncpy (p, namestring, n); p[n] = 0; - msym = lookup_minimal_symbol (p, filename, objfile); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, p, objfile, filename); if (msym.minsym == NULL) { /* Sun Fortran appends an underscore to the minimal symbol name, @@ -916,21 +916,22 @@ find_stab_function (const char *namestring, const char *filename, was not found. */ p[n] = '_'; p[n + 1] = 0; - msym = lookup_minimal_symbol (p, filename, objfile); + msym + = lookup_minimal_symbol (current_program_space, p, objfile, filename); } if (msym.minsym == NULL && filename != NULL) { /* Try again without the filename. */ p[n] = 0; - msym = lookup_minimal_symbol (p, NULL, objfile); + msym = lookup_minimal_symbol (current_program_space, p, objfile); } if (msym.minsym == NULL && filename != NULL) { /* And try again for Sun Fortran, but without the filename. */ p[n] = '_'; p[n + 1] = 0; - msym = lookup_minimal_symbol (p, NULL, objfile); + msym = lookup_minimal_symbol (current_program_space, p, objfile); } return msym; @@ -1678,10 +1679,9 @@ read_dbx_symtab (minimal_symbol_reader &reader, if (nlist.n_value == 0 && gdbarch_sofun_address_maybe_missing (gdbarch)) { - struct bound_minimal_symbol minsym + bound_minimal_symbol minsym = find_stab_function (namestring, - pst ? pst->filename : NULL, - objfile); + pst ? pst->filename : NULL, objfile); if (minsym.minsym != NULL) nlist.n_value = CORE_ADDR (minsym.minsym->unrelocated_address ()); @@ -1737,10 +1737,9 @@ read_dbx_symtab (minimal_symbol_reader &reader, if (nlist.n_value == 0 && gdbarch_sofun_address_maybe_missing (gdbarch)) { - struct bound_minimal_symbol minsym + bound_minimal_symbol minsym = find_stab_function (namestring, - pst ? pst->filename : NULL, - objfile); + pst ? pst->filename : NULL, objfile); if (minsym.minsym != NULL) nlist.n_value = CORE_ADDR (minsym.minsym->unrelocated_address ()); @@ -2036,7 +2035,6 @@ dbx_end_psymtab (struct objfile *objfile, psymtab_storage *partial_symtabs, && gdbarch_sofun_address_maybe_missing (gdbarch)) { int n; - struct bound_minimal_symbol minsym; const char *colon = strchr (last_function_name, ':'); if (colon == NULL) @@ -2047,7 +2045,9 @@ dbx_end_psymtab (struct objfile *objfile, psymtab_storage *partial_symtabs, strncpy (p, last_function_name, n); p[n] = 0; - minsym = lookup_minimal_symbol (p, pst->filename, objfile); + bound_minimal_symbol minsym + = lookup_minimal_symbol (current_program_space, p, objfile, + pst->filename); if (minsym.minsym == NULL) { /* Sun Fortran appends an underscore to the minimal symbol name, @@ -2055,7 +2055,8 @@ dbx_end_psymtab (struct objfile *objfile, psymtab_storage *partial_symtabs, was not found. */ p[n] = '_'; p[n + 1] = 0; - minsym = lookup_minimal_symbol (p, pst->filename, objfile); + minsym = lookup_minimal_symbol (current_program_space, p, objfile, + pst->filename); } if (minsym.minsym) @@ -2840,7 +2841,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name, && valu == section_offsets[SECT_OFF_TEXT (objfile)] && gdbarch_sofun_address_maybe_missing (gdbarch)) { - struct bound_minimal_symbol minsym + bound_minimal_symbol minsym = find_stab_function (name, get_last_source_file (), objfile); if (minsym.minsym != NULL) diff --git a/gdb/disasm-flags.h b/gdb/disasm-flags.h index 4f71125..10cb95d 100644 --- a/gdb/disasm-flags.h +++ b/gdb/disasm-flags.h @@ -34,6 +34,7 @@ enum gdb_disassembly_flag : unsigned DISASSEMBLY_SOURCE = (0x1 << 5), DISASSEMBLY_SPECULATIVE = (0x1 << 6), DISASSEMBLY_RAW_BYTES = (0x1 << 7), + DISASSEMBLY_OMIT_AUX_INSN = (0x1 << 8), }; DEF_ENUM_FLAGS_TYPE (enum gdb_disassembly_flag, gdb_disassembly_flags); 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/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 86cd420..7938b07 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -2742,7 +2742,7 @@ environment: @end smallexample This command is available when debugging locally on most targets, excluding -@sc{djgpp}, Cygwin, MS Windows, and QNX Neutrino. +@sc{djgpp}, Cygwin, and MS Windows. @kindex set startup-with-shell @anchor{set startup-with-shell} @@ -7784,6 +7784,9 @@ Moxie, PowerPC, PowerPC64, S/390, and x86 (i386/amd64) running GNU/Linux. Process record and replay can be used both when native debugging, and when remote debugging via @code{gdbserver}. +When recording an inferior, @value{GDBN} may print auxiliary information +during stepping commands and commands displaying the execution history. + For architecture environments that support process record and replay, @value{GDBN} provides the following commands: @@ -8199,6 +8202,9 @@ To better align the printed instructions when the trace contains instructions from more than one function, the function name may be omitted by specifying the @code{/f} modifier. +Printing auxiliary information is enabled by default and can be +omitted with the @code{/a} modifier. + Speculatively executed instructions are prefixed with @samp{?}. This feature is not available for all recording formats. @@ -8252,8 +8258,9 @@ that function, the source lines for this instruction sequence (if the @code{/l} modifier is specified), and the instructions numbers that form the sequence (if the @code{/i} modifier is specified). The function names are indented to reflect the call stack depth if the @code{/c} modifier is -specified. The @code{/l}, @code{/i}, and @code{/c} modifiers can be given -together. +specified. Printing auxiliary information is enabled by default and can be +omitted with the @code{/a} modifier. The @code{/l}, @code{/i}, @code{/a}, +and @code{/c} modifiers can be given together. @smallexample (@value{GDBP}) @b{list 1, 10} @@ -22011,7 +22018,7 @@ name and remembers it that way. @cindex shared libraries @anchor{Shared Libraries} @value{GDBN} supports @sc{gnu}/Linux, MS-Windows, SunOS, -Darwin/Mach-O, SVr4, IBM RS/6000 AIX, QNX Neutrino, FDPIC (FR-V), and +Darwin/Mach-O, SVr4, IBM RS/6000 AIX, FDPIC (FR-V), and DSBT (TIC6X) shared libraries. On MS-Windows @value{GDBN} must be linked with the Expat library to support @@ -24534,6 +24541,10 @@ future connections is shown. The available settings are: @tab @code{vFile:fstat} @tab Host I/O +@item @code{hostio-stat-packet} +@tab @code{vFile:stat} +@tab Host I/O + @item @code{hostio-setfs-packet} @tab @code{vFile:setfs} @tab Host I/O @@ -25203,16 +25214,6 @@ Show the file to which @code{procfs} API trace is written. These commands enable and disable tracing of entries into and exits from the @code{syscall} interface. -@item info pidlist -@kindex info pidlist -@cindex process list, QNX Neutrino -For QNX Neutrino only, this command displays the list of all the -processes and all the threads within each process. - -@item info meminfo -@kindex info meminfo -@cindex mapinfo list, QNX Neutrino -For QNX Neutrino only, this command displays the list of all mapinfos. @end table @node DJGPP Native @@ -29224,9 +29225,21 @@ files. @cindex arguments, to user-defined commands A @dfn{user-defined command} is a sequence of @value{GDBN} commands to which you assign a new name as a command. This is done with the -@code{define} command. User commands may accept an unlimited number of arguments -separated by whitespace. Arguments are accessed within the user command -via @code{$arg0@dots{}$argN}. A trivial example: +@code{define} command. + +User commands may accept an unlimited number of arguments separated by +whitespace. Arguments are accessed within the user command via +@code{$arg0@dots{}$argN}. The arguments are text substitutions, so +they may reference variables, use complex expressions, or even perform +inferior functions calls. Note, however, that this textual +substitution means that working with certain arguments is difficult. +For example, there is no way for the user to pass an argument +containing a space; and while stringifying an argument can be done +using an expression like @code{"$arg1"}, this will fail if the +argument contains a quote. For more complicated and robust commands, +we recommend writing them in Python; see @ref{CLI Commands In Python}. + +A trivial example: @smallexample define adder @@ -29243,9 +29256,7 @@ adder 1 2 3 @noindent This defines the command @code{adder}, which prints the sum of -its three arguments. Note the arguments are text substitutions, so they may -reference variables, use complex expressions, or even perform inferior -functions calls. +its three arguments. @cindex argument count in user-defined commands @cindex how many arguments (user-defined commands) @@ -41430,7 +41441,8 @@ This command is useful for debugging the agent version of dynamic printf (@pxref{Dynamic Printf}). @kindex maint info breakpoints -@item @anchor{maint info breakpoints}maint info breakpoints +@anchor{maint info breakpoints} +@item maint info breakpoints Using the same format as @samp{info breakpoints}, display both the breakpoints you've set explicitly, and those @value{GDBN} is using for internal purposes. Internal breakpoints are shown with negative @@ -44795,6 +44807,11 @@ These are the currently defined stub features and their properties: @tab @samp{-} @tab Yes +@item @samp{Qbtrace-conf:pt:ptwrite} +@tab Yes +@tab @samp{-} +@tab Yes + @item @samp{QNonStop} @tab No @tab @samp{-} @@ -45116,6 +45133,9 @@ The remote stub understands the @samp{Qbtrace-conf:bts:size} packet. @item Qbtrace-conf:pt:size The remote stub understands the @samp{Qbtrace-conf:pt:size} packet. +@item Qbtrace-conf:pt:ptwrite +The remote stub understands the @samp{Qbtrace-conf:pt:ptwrite} packet. + @item swbreak The remote stub reports the @samp{swbreak} stop reason for memory breakpoints. @@ -45605,6 +45625,18 @@ Reply: The ring buffer size has been set. @end table +@item Qbtrace-conf:pt:ptwrite=@var{(yes|no)} +Indicate support for @code{PTWRITE} packets. This allows for backwards +compatibility. + +Reply: +@table @samp +@item OK +The ptwrite config parameter has been set. +@item E.errtext +A badly formed request or an error was encountered. +@end table + @end table @node Architecture-Specific Protocol Details @@ -46326,6 +46358,13 @@ and the return value is the size of this attachment in bytes. If an error occurs the return value is -1. The format of the returned binary attachment is as described in @ref{struct stat}. +@item vFile:stat: @var{filename} +Get information about the file @var{filename} on the target. +On success the information is returned as a binary attachment +and the return value is the size of this attachment in bytes. +If an error occurs the return value is -1. The format of the +returned binary attachment is as described in @ref{struct stat}. + @item vFile:unlink: @var{filename} Delete the file at @var{filename} on the target. Return 0, or -1 if an error occurs. The @var{filename} is a string. @@ -48239,6 +48278,7 @@ The formal DTD for the branch trace configuration format is given below: <!ELEMENT pt EMPTY> <!ATTLIST pt size CDATA #IMPLIED> +<!ATTLIST pt ptwrite (yes | no) #IMPLIED> @end smallexample @include agentexpr.texi @@ -51011,7 +51051,7 @@ Richard M. Stallman and Roland H. Pesch, July 1991. @format @c man begin SYNOPSIS gcore -gcore [-a] [-o @var{prefix}] @var{pid1} [@var{pid2}...@var{pidN}] +gcore [-a] [-o @var{prefix}] [-d @var{directory}] @var{pid1} [@var{pid2}...@var{pidN}] @c man end @end format @@ -51039,6 +51079,10 @@ when composing the file names of the core dumps. The file name is composed as @file{@var{prefix}.@var{pid}}, where @var{pid} is the process ID of the running program being analyzed by @command{gcore}. If not specified, @var{prefix} defaults to @var{gcore}. + +@item -d @var{directory} +Use @var{directory} as the data directory when invoking @value{GDBN} for running +the gcore command. This argument is optional. @end table @c man end diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index 86ccc14..bb1f205 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -4314,6 +4314,11 @@ A @code{gdb.Record} object has the following methods: Move the replay position to the given @var{instruction}. @end defun +@defun Record.clear () +Clear the trace data of the current recording. This forces re-decoding of the +trace for successive commands. +@end defun + The common @code{gdb.Instruction} class that recording method specific instruction objects inherit from, has the following attributes: @@ -4369,6 +4374,19 @@ the current recording method. A human readable string with the reason for the gap. @end defvar +Some @value{GDBN} features write auxiliary information into the execution +history. This information is represented by a @code{gdb.RecordAuxiliary} object +in the instruction list. It has the following attributes: + +@defvar RecordAuxiliary.@var{number} +An integer identifying this auxiliary. @var{number} corresponds to the numbers +seen in @code{record instruction-history} (@pxref{Process Record and Replay}). +@end defvar + +@defvar RecordAuxiliary.data +A string representation of the auxiliary data. +@end defvar + A @code{gdb.RecordFunctionSegment} object has the following attributes: @defvar RecordFunctionSegment.number @@ -8206,6 +8224,7 @@ registering objfile-specific pretty-printers and frame-filters. * gdb.printing:: Building and registering pretty-printers. * gdb.types:: Utilities for working with types. * gdb.prompt:: Utilities for prompt value substitution. +* gdb.ptwrite:: Utilities for PTWRITE filter registration. @end menu @node gdb.printing @@ -8396,3 +8415,153 @@ substitute_prompt ("frame: \f, args: \p@{print frame-arguments@}") "frame: main, args: scalars" @end smallexample @end table + +@node gdb.ptwrite +@subsubsection gdb.ptwrite +@cindex gdb.ptwrite + +This module provides additional functionality for recording programs that +make use of the @code{PTWRITE} instruction. @code{PTWRITE} is a x86 +instruction that allows to write values into the Intel Processor Trace +(@pxref{Process Record and Replay}). +The @value{NGCC} intrinsics for it are: +@smallexample +void _ptwrite32 (unsigned int a) +void _ptwrite64 (unsigned __int64 a) +@end smallexample + +If an inferior uses the instruction, @value{GDBN} by default inserts the +raw payload value as auxiliary information into the execution history. +Auxiliary information is by default printed during +@code{record instruction-history}, @code{record function-call-history}, +and all stepping commands, and is accessible in Python as a +@code{RecordAuxiliary} object (@pxref{Recordings In Python}). + +@exdent Sample program: +@smallexample +@group +#include <immintrin.h> + +void +ptwrite64 (unsigned long long value) +@{ + _ptwrite64 (value); +@} +@end group + +@group +int +main (void) +@{ + ptwrite64 (0x42); + return 0; /* break here. */ +@} +@end group +@end smallexample + + +@exdent @value{GDBN} output after recording the sample program in pt format: +@smallexample +@group +(gdb) record instruction-history 12,14 +12 0x0040074c <ptwrite64+16>: ptwrite %rbx +13 [0x42] +14 0x00400751 <ptwrite64+21>: mov -0x8(%rbp),%rbx +(gdb) record function-call-history +1 main +2 ptwrite64 + [0x42] +3 main +@end group +@end smallexample + +The @code{gdb.ptwrite} module allows customizing the default output of +@code{PTWRITE} auxiliary information. A custom Python function can be +registered as the @code{PTWRITE} filter function. This function will be +called with the @code{PTWRITE} payload and PC as arguments during trace +decoding. The function can return a string, which will be printed by +@value{GDBN} during the aforementioned commands, or @code{None}, resulting +in no output. To register such a filter function, the user needs to +provide a filter factory function, which returns a new filter function +object to be called by @value{GDBN}. + +@findex gdb.ptwrite.register_filter_factory +@defun register_filter_factory (filter_factory) +Used to register the @code{PTWRITE} filter factory. This filter factory can +be any callable object that accepts one argument, the current thread as +a @code{gdb.InferiorThread}. +It can return None or a callable. This callable is the @code{PTWRITE} filter +function for the specified thread. If @code{None} is returned by the factory +function, the default auxiliary information will be printed. +@end defun + +@findex gdb.ptwrite.get_filter +@defun get_filter () +Return the currently active @code{PTWRITE} filter function. +@end defun + +An example: + +@smallexample +@group +(gdb) python-interactive +>>> class my_filter(): +... def __init__(self): +... self.var = 0 +... def __call__(self, payload, ip): +... self.var += 1 +... return f"counter: @{self.var@}, ip: @{ip:#x@}" +... +>>> def my_filter_factory(thread): +... if thread.global_num == 1: +... return my_filter() +... else: +... return None +... +>>> import gdb.ptwrite +>>> gdb.ptwrite.register_filter_factory(my_filter_factory) +>>> +@end group + +@group +(gdb) record function-call-history 59,64 +59 pthread_create@@GLIBC_2.2.5 +60 job() +61 task(void*) +62 ptwrite64(unsigned long) + [counter: 1, ip: 0x401156] +63 task(void*) +64 ptwrite32(unsigned int) + [counter: 2, ip: 0x40116c] +@end group + +@group +(gdb) info threads +* 1 Thread 0x7ffff7fd8740 (LWP 25796) "ptw_threads" task () + at bin/ptwrite/ptw_threads.c:45 + 2 Thread 0x7ffff6eb8700 (LWP 25797) "ptw_threads" task () + at bin/ptwrite/ptw_threads.c:45 +@end group + +@group +(gdb) thread 2 +[Switching to thread 2 (Thread 0x7ffff6eb8700 (LWP 25797))] +#0 task (arg=0x0) at ptwrite_threads.c:45 +45 return NULL; +@end group + +@group +(gdb) record function-call-history 10,14 +10 start_thread +11 task(void*) +12 ptwrite64(unsigned long) + [0x42] +13 task(void*) +14 ptwrite32(unsigned int) + [0x43] +@end group +@end smallexample + +This @value{GDBN} feature is dependent on hardware and operating system +support and requires the Intel Processor Trace decoder library in version +2.0.0 or newer. diff --git a/gdb/dwarf2/ada-imported.c b/gdb/dwarf2/ada-imported.c index 9ec0d51..eabbab1 100644 --- a/gdb/dwarf2/ada-imported.c +++ b/gdb/dwarf2/ada-imported.c @@ -20,6 +20,7 @@ #include "symtab.h" #include "value.h" #include "dwarf2/loc.h" +#include "objfiles.h" /* Helper to get the imported symbol's real name. */ static const char * @@ -34,7 +35,8 @@ static struct value * ada_imported_read_variable (struct symbol *symbol, const frame_info_ptr &frame) { const char *name = get_imported_name (symbol); - bound_minimal_symbol minsym = lookup_minimal_symbol_linkage (name, false); + bound_minimal_symbol minsym + = lookup_minimal_symbol_linkage (symbol->objfile ()->pspace (), name, false); if (minsym.minsym == nullptr) error (_("could not find imported name %s"), name); return value_at (symbol->type (), minsym.value_address ()); diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h index efd03e6..fa8b2fc 100644 --- a/gdb/dwarf2/cooked-index.h +++ b/gdb/dwarf2/cooked-index.h @@ -788,7 +788,7 @@ struct cooked_index_functions : public dwarf2_base_index_functions domain_search_flags domain) override; struct compunit_symtab *find_pc_sect_compunit_symtab - (struct objfile *objfile, struct bound_minimal_symbol msymbol, + (struct objfile *objfile, bound_minimal_symbol msymbol, CORE_ADDR pc, struct obj_section *section, int warn_if_readin) override { wait (objfile, true); diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c index 5fea668..80c86bb 100644 --- a/gdb/dwarf2/loc.c +++ b/gdb/dwarf2/loc.c @@ -667,9 +667,8 @@ call_site_target::iterate_over_addresses (gdbarch *call_site_gdbarch, dwarf_block = m_loc.dwarf_block; if (dwarf_block == NULL) { - struct bound_minimal_symbol msym; - - msym = lookup_minimal_symbol_by_pc (call_site->pc () - 1); + bound_minimal_symbol msym + = lookup_minimal_symbol_by_pc (call_site->pc () - 1); throw_error (NO_ENTRY_VALUE_ERROR, _("DW_AT_call_target is not specified at %s in %s"), paddress (call_site_gdbarch, call_site->pc ()), @@ -679,9 +678,8 @@ call_site_target::iterate_over_addresses (gdbarch *call_site_gdbarch, } if (caller_frame == NULL) { - struct bound_minimal_symbol msym; - - msym = lookup_minimal_symbol_by_pc (call_site->pc () - 1); + bound_minimal_symbol msym + = lookup_minimal_symbol_by_pc (call_site->pc () - 1); throw_error (NO_ENTRY_VALUE_ERROR, _("DW_AT_call_target DWARF block resolving " "requires known frame which is currently not " @@ -708,12 +706,12 @@ call_site_target::iterate_over_addresses (gdbarch *call_site_gdbarch, case call_site_target::PHYSNAME: { const char *physname; - struct bound_minimal_symbol msym; physname = m_loc.physname; /* Handle both the mangled and demangled PHYSNAME. */ - msym = lookup_minimal_symbol (physname, NULL, NULL); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, physname); if (msym.minsym == NULL) { msym = lookup_minimal_symbol_by_pc (call_site->pc () - 1); @@ -820,9 +818,8 @@ func_verify_no_selftailcall (struct gdbarch *gdbarch, CORE_ADDR verify_addr) { if (target_addr == verify_addr) { - struct bound_minimal_symbol msym; - - msym = lookup_minimal_symbol_by_pc (verify_addr); + bound_minimal_symbol msym + = lookup_minimal_symbol_by_pc (verify_addr); throw_error (NO_ENTRY_VALUE_ERROR, _("DW_OP_entry_value resolving has found " "function \"%s\" at %s can call itself via tail " @@ -846,7 +843,7 @@ static void tailcall_dump (struct gdbarch *gdbarch, const struct call_site *call_site) { CORE_ADDR addr = call_site->pc (); - struct bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (addr - 1); + bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (addr - 1); gdb_printf (gdb_stdlog, " %s(%s)", paddress (gdbarch, addr), (msym.minsym == NULL ? "???" @@ -1064,10 +1061,10 @@ call_site_find_chain_1 (struct gdbarch *gdbarch, CORE_ADDR caller_pc, if (retval == NULL) { - struct bound_minimal_symbol msym_caller, msym_callee; - - msym_caller = lookup_minimal_symbol_by_pc (caller_pc); - msym_callee = lookup_minimal_symbol_by_pc (callee_pc); + bound_minimal_symbol msym_caller + = lookup_minimal_symbol_by_pc (caller_pc); + bound_minimal_symbol msym_callee + = lookup_minimal_symbol_by_pc (callee_pc); throw_error (NO_ENTRY_VALUE_ERROR, _("There are no unambiguously determinable intermediate " "callers or callees between caller function \"%s\" at %s " @@ -1165,8 +1162,7 @@ dwarf_expr_reg_to_entry_parameter (const frame_info_ptr &initial_frame, caller_frame = get_prev_frame (frame); if (gdbarch != frame_unwind_arch (frame)) { - struct bound_minimal_symbol msym - = lookup_minimal_symbol_by_pc (func_addr); + bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (func_addr); struct gdbarch *caller_gdbarch = frame_unwind_arch (frame); throw_error (NO_ENTRY_VALUE_ERROR, @@ -1181,8 +1177,7 @@ dwarf_expr_reg_to_entry_parameter (const frame_info_ptr &initial_frame, if (caller_frame == NULL) { - struct bound_minimal_symbol msym - = lookup_minimal_symbol_by_pc (func_addr); + bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (func_addr); throw_error (NO_ENTRY_VALUE_ERROR, _("DW_OP_entry_value resolving " "requires caller of %s (%s)"), @@ -2253,7 +2248,7 @@ dwarf2_get_symbol_read_needs (gdb::array_view<const gdb_byte> expr, /* A helper function that throws an unimplemented error mentioning a given DWARF operator. */ -static void ATTRIBUTE_NORETURN +[[noreturn]] static void unimplemented (unsigned int op) { const char *name = get_DW_OP_name (op); diff --git a/gdb/dwarf2/macro.c b/gdb/dwarf2/macro.c index bc781c2..5371acf 100644 --- a/gdb/dwarf2/macro.c +++ b/gdb/dwarf2/macro.c @@ -160,9 +160,7 @@ parse_macro_definition (struct macro_source_file *file, int line, /* It's a function-like macro. */ gdb_assert (*p == '('); std::string name (body, p - body); - int argc = 0; - int argv_size = 1; - char **argv = XNEWVEC (char *, argv_size); + std::vector<std::string> argv; p++; @@ -178,18 +176,12 @@ parse_macro_definition (struct macro_source_file *file, int line, p++; if (! *p || p == arg_start) - dwarf2_macro_malformed_definition_complaint (body); - else { - /* Make sure argv has room for the new argument. */ - if (argc >= argv_size) - { - argv_size *= 2; - argv = XRESIZEVEC (char *, argv, argv_size); - } - - argv[argc++] = savestring (arg_start, p - arg_start); + dwarf2_macro_malformed_definition_complaint (body); + return; } + else + argv.emplace_back (arg_start, p); p = consume_improper_spaces (p, body); @@ -208,16 +200,12 @@ parse_macro_definition (struct macro_source_file *file, int line, if (*p == ' ') /* Perfectly formed definition, no complaints. */ - macro_define_function (file, line, name.c_str (), - argc, (const char **) argv, - p + 1); + macro_define_function (file, line, name.c_str (), argv, p + 1); else if (*p == '\0') { /* Complain, but do define it. */ dwarf2_macro_malformed_definition_complaint (body); - macro_define_function (file, line, name.c_str (), - argc, (const char **) argv, - p); + macro_define_function (file, line, name.c_str (), argv, p); } else /* Just complain. */ @@ -226,11 +214,6 @@ parse_macro_definition (struct macro_source_file *file, int line, else /* Just complain. */ dwarf2_macro_malformed_definition_complaint (body); - - for (int i = 0; i < argc; i++) - xfree (argv[i]); - - xfree (argv); } /* Skip some bytes from BYTES according to the form given in FORM. diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 71237d0..fde8eee 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -863,9 +863,10 @@ static struct type *read_type_die_1 (struct die_info *, struct dwarf2_cu *); static const char *determine_prefix (struct die_info *die, struct dwarf2_cu *); -static char *typename_concat (struct obstack *obs, const char *prefix, - const char *suffix, int physname, - struct dwarf2_cu *cu); +static gdb::unique_xmalloc_ptr<char> typename_concat (const char *prefix, + const char *suffix, + int physname, + struct dwarf2_cu *cu); static void read_file_scope (struct die_info *, struct dwarf2_cu *); @@ -2997,7 +2998,7 @@ recursively_find_pc_sect_compunit_symtab (struct compunit_symtab *cust, struct compunit_symtab * dwarf2_base_index_functions::find_pc_sect_compunit_symtab (struct objfile *objfile, - struct bound_minimal_symbol msymbol, + bound_minimal_symbol msymbol, CORE_ADDR pc, struct obj_section *section, int warn_if_readin) @@ -6673,7 +6674,7 @@ dwarf2_compute_name (const char *name, if (*prefix != '\0') { gdb::unique_xmalloc_ptr<char> prefixed_name - (typename_concat (NULL, prefix, name, physname, cu)); + = typename_concat (prefix, name, physname, cu); buf.puts (prefixed_name.get ()); } @@ -13986,9 +13987,12 @@ read_namespace_type (struct die_info *die, struct dwarf2_cu *cu) /* Now build the name of the current namespace. */ previous_prefix = determine_prefix (die, cu); + gdb::unique_xmalloc_ptr<char> name_storage; if (previous_prefix[0] != '\0') - name = typename_concat (&objfile->objfile_obstack, - previous_prefix, name, 0, cu); + { + name_storage = typename_concat (previous_prefix, name, 0, cu); + name = name_storage.get (); + } /* Create the type. */ type = type_allocator (objfile, cu->lang ()).new_type (TYPE_CODE_NAMESPACE, @@ -19998,17 +20002,15 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu) } } -/* Return a newly-allocated string formed by concatenating PREFIX and SUFFIX - with appropriate separator. If PREFIX or SUFFIX is NULL or empty, then - simply copy the SUFFIX or PREFIX, respectively. If OBS is non-null, perform - an obconcat, otherwise allocate storage for the result. The CU argument is - used to determine the language and hence, the appropriate separator. */ - -#define MAX_SEP_LEN 7 /* strlen ("__") + strlen ("_MOD_") */ +/* Return a newly-allocated string formed by concatenating PREFIX and + SUFFIX with appropriate separator. If PREFIX or SUFFIX is NULL or + empty, then simply copy the SUFFIX or PREFIX, respectively. The CU + argument is used to determine the language and hence, the + appropriate separator. */ -static char * -typename_concat (struct obstack *obs, const char *prefix, const char *suffix, - int physname, struct dwarf2_cu *cu) +static gdb::unique_xmalloc_ptr<char> +typename_concat (const char *prefix, const char *suffix, int physname, + struct dwarf2_cu *cu) { const char *lead = ""; const char *sep; @@ -20044,23 +20046,8 @@ typename_concat (struct obstack *obs, const char *prefix, const char *suffix, if (suffix == NULL) suffix = ""; - if (obs == NULL) - { - char *retval - = ((char *) - xmalloc (strlen (prefix) + MAX_SEP_LEN + strlen (suffix) + 1)); - - strcpy (retval, lead); - strcat (retval, prefix); - strcat (retval, sep); - strcat (retval, suffix); - return retval; - } - else - { - /* We have an obstack. */ - return obconcat (obs, lead, prefix, sep, suffix, (char *) NULL); - } + return gdb::unique_xmalloc_ptr<char> (concat (lead, prefix, sep, suffix, + nullptr)); } /* Return a generic name for a DW_TAG_template_type_param or diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h index e55d053..40e1f55 100644 --- a/gdb/dwarf2/read.h +++ b/gdb/dwarf2/read.h @@ -844,7 +844,7 @@ struct dwarf2_base_index_functions : public quick_symbol_functions void expand_all_symtabs (struct objfile *objfile) override; struct compunit_symtab *find_pc_sect_compunit_symtab - (struct objfile *objfile, struct bound_minimal_symbol msymbol, + (struct objfile *objfile, bound_minimal_symbol msymbol, CORE_ADDR pc, struct obj_section *section, int warn_if_readin) override; diff --git a/gdb/elfread.c b/gdb/elfread.c index 7a6a8ca..c71a142 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -694,13 +694,12 @@ elf_gnu_ifunc_cache_eq (const void *a_voidp, const void *b_voidp) static int elf_gnu_ifunc_record_cache (const char *name, CORE_ADDR addr) { - struct bound_minimal_symbol msym; struct objfile *objfile; htab_t htab; struct elf_gnu_ifunc_cache entry_local, *entry_p; void **slot; - msym = lookup_minimal_symbol_by_pc (addr); + bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (addr); if (msym.minsym == NULL) return 0; if (msym.value_address () != addr) @@ -843,9 +842,10 @@ elf_gnu_ifunc_resolve_by_got (const char *name, CORE_ADDR *addr_p) CORE_ADDR pointer_address, addr; asection *plt; gdb_byte *buf = (gdb_byte *) alloca (ptr_size); - bound_minimal_symbol msym; - msym = lookup_minimal_symbol (name_got_plt, NULL, objfile); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, name_got_plt, + objfile); if (msym.minsym == NULL) return 0; if (msym.minsym->type () != mst_slot_got_plt) @@ -622,11 +622,7 @@ evaluate_subexp_do_call (expression *exp, enum noside noside, if (ftype->code () == TYPE_CODE_INTERNAL_FUNCTION) { - /* We don't know anything about what the internal - function might return, but we have to return - something. */ - return value::zero (builtin_type (exp->gdbarch)->builtin_int, - not_lval); + /* The call to call_internal_function below handles noside. */ } else if (ftype->code () == TYPE_CODE_XMETHOD) { @@ -666,7 +662,8 @@ evaluate_subexp_do_call (expression *exp, enum noside noside, { case TYPE_CODE_INTERNAL_FUNCTION: return call_internal_function (exp->gdbarch, exp->language_defn, - callee, argvec.size (), argvec.data ()); + callee, argvec.size (), argvec.data (), + noside); case TYPE_CODE_XMETHOD: return callee->call_xmethod (argvec); default: @@ -1957,7 +1954,8 @@ eval_op_objc_msgcall (struct type *expect_type, struct expression *exp, if (value_as_long (target) == 0) return value_from_longest (long_type, 0); - if (lookup_minimal_symbol ("objc_msg_lookup", 0, 0).minsym) + if (lookup_minimal_symbol (current_program_space, "objc_msg_lookup").minsym + != nullptr) gnu_runtime = 1; /* Find the method dispatch (Apple runtime) or method lookup diff --git a/gdb/event-top.c b/gdb/event-top.c index b81970d..cdc7874 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -894,7 +894,7 @@ unblock_signal (int sig) /* Called to handle fatal signals. SIG is the signal number. */ -static void ATTRIBUTE_NORETURN +[[noreturn]] static void handle_fatal_signal (int sig) { #ifdef TUI 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/extension-priv.h b/gdb/extension-priv.h index 1365988..653fd51 100644 --- a/gdb/extension-priv.h +++ b/gdb/extension-priv.h @@ -188,6 +188,11 @@ struct extension_language_ops enum ext_lang_frame_args args_type, struct ui_out *out, int frame_low, int frame_high); + /* Used for registering the ptwrite filter to the current thread. */ + void (*apply_ptwrite_filter) + (const struct extension_language_defn *extlang, + struct btrace_thread_info *btinfo); + /* Update values held by the extension language when OBJFILE is discarded. New global types must be created for every such value, which must then be updated to use the new types. diff --git a/gdb/extension.c b/gdb/extension.c index 99e7190..c488fc7 100644 --- a/gdb/extension.c +++ b/gdb/extension.c @@ -562,6 +562,19 @@ apply_ext_lang_frame_filter (const frame_info_ptr &frame, return EXT_LANG_BT_NO_FILTERS; } +/* Used for registering the ptwrite filter to the current thread. */ + +void +apply_ext_lang_ptwrite_filter (btrace_thread_info *btinfo) +{ + for (const struct extension_language_defn *extlang : extension_languages) + { + if (extlang->ops != nullptr + && extlang->ops->apply_ptwrite_filter != nullptr) + extlang->ops->apply_ptwrite_filter (extlang, btinfo); + } +} + /* Update values held by the extension language when OBJFILE is discarded. New global types must be created for every such value, which must then be updated to use the new types. diff --git a/gdb/extension.h b/gdb/extension.h index 258a77d..5b0830b 100644 --- a/gdb/extension.h +++ b/gdb/extension.h @@ -303,6 +303,9 @@ extern enum ext_lang_bt_status apply_ext_lang_frame_filter enum ext_lang_frame_args args_type, struct ui_out *out, int frame_low, int frame_high); +extern void apply_ext_lang_ptwrite_filter + (struct btrace_thread_info *btinfo); + extern void preserve_ext_lang_values (struct objfile *, htab_t copied_types); extern const struct extension_language_defn *get_breakpoint_cond_ext_lang diff --git a/gdb/f-exp.y b/gdb/f-exp.y index bdf9c32..259f274 100644 --- a/gdb/f-exp.y +++ b/gdb/f-exp.y @@ -754,7 +754,11 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */ | REAL_S8_KEYWORD { $$ = parse_f_type (pstate)->builtin_real_s8; } | REAL_S16_KEYWORD - { $$ = parse_f_type (pstate)->builtin_real_s16; } + { $$ = parse_f_type (pstate)->builtin_real_s16; + if ($$->code () == TYPE_CODE_ERROR) + error (_("unsupported type %s"), + TYPE_SAFE_NAME ($$)); + } | COMPLEX_KEYWORD { $$ = parse_f_type (pstate)->builtin_complex; } | COMPLEX_S4_KEYWORD @@ -762,7 +766,11 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */ | COMPLEX_S8_KEYWORD { $$ = parse_f_type (pstate)->builtin_complex_s8; } | COMPLEX_S16_KEYWORD - { $$ = parse_f_type (pstate)->builtin_complex_s16; } + { $$ = parse_f_type (pstate)->builtin_complex_s16; + if ($$->code () == TYPE_CODE_ERROR) + error (_("unsupported type %s"), + TYPE_SAFE_NAME ($$)); + } | SINGLE PRECISION { $$ = parse_f_type (pstate)->builtin_real;} | DOUBLE PRECISION @@ -1156,12 +1164,9 @@ push_kind_type (LONGEST val, struct type *type) type_stack->push (tp_kind); } -/* Called when a type has a '(kind=N)' modifier after it, for example - 'character(kind=1)'. The BASETYPE is the type described by 'character' - in our example, and KIND is the integer '1'. This function returns a - new type that represents the basetype of a specific kind. */ +/* Helper function for convert_to_kind_type. */ static struct type * -convert_to_kind_type (struct type *basetype, int kind) +convert_to_kind_type_1 (struct type *basetype, int kind) { if (basetype == parse_f_type (pstate)->builtin_character) { @@ -1211,13 +1216,25 @@ convert_to_kind_type (struct type *basetype, int kind) return parse_f_type (pstate)->builtin_integer_s8; } - error (_("unsupported kind %d for type %s"), - kind, TYPE_SAFE_NAME (basetype)); - - /* Should never get here. */ return nullptr; } +/* Called when a type has a '(kind=N)' modifier after it, for example + 'character(kind=1)'. The BASETYPE is the type described by 'character' + in our example, and KIND is the integer '1'. This function returns a + new type that represents the basetype of a specific kind. */ +static struct type * +convert_to_kind_type (struct type *basetype, int kind) +{ + struct type *res = convert_to_kind_type_1 (basetype, kind); + + if (res == nullptr || res->code () == TYPE_CODE_ERROR) + error (_("unsupported kind %d for type %s"), + kind, TYPE_SAFE_NAME (basetype)); + + return res; +} + struct f_token { /* The string to match against. */ diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c index 367f641..ac51f10 100644 --- a/gdb/fbsd-tdep.c +++ b/gdb/fbsd-tdep.c @@ -1943,7 +1943,8 @@ fbsd_get_syscall_number (struct gdbarch *gdbarch, thread_info *thread) static LONGEST fbsd_read_integer_by_name (struct gdbarch *gdbarch, const char *name) { - bound_minimal_symbol ms = lookup_minimal_symbol (name, NULL, NULL); + bound_minimal_symbol ms + = lookup_minimal_symbol (current_program_space, name); if (ms.minsym == NULL) error (_("Unable to resolve symbol '%s'"), name); @@ -2034,21 +2035,23 @@ fbsd_get_thread_local_address (struct gdbarch *gdbarch, CORE_ADDR dtv_addr, { LONGEST tls_index = fbsd_get_tls_index (gdbarch, lm_addr); - gdb_byte buf[gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT]; - if (target_read_memory (dtv_addr, buf, sizeof buf) != 0) + gdb::byte_vector buf (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT); + if (target_read_memory (dtv_addr, buf.data (), buf.size ()) != 0) throw_error (TLS_GENERIC_ERROR, _("Cannot find thread-local variables on this target")); const struct builtin_type *builtin = builtin_type (gdbarch); - CORE_ADDR addr = gdbarch_pointer_to_address (gdbarch, - builtin->builtin_data_ptr, buf); + CORE_ADDR addr + = gdbarch_pointer_to_address (gdbarch, builtin->builtin_data_ptr, + buf.data ()); addr += (tls_index + 1) * builtin->builtin_data_ptr->length (); - if (target_read_memory (addr, buf, sizeof buf) != 0) + if (target_read_memory (addr, buf.data (), buf.size ()) != 0) throw_error (TLS_GENERIC_ERROR, _("Cannot find thread-local variables on this target")); - addr = gdbarch_pointer_to_address (gdbarch, builtin->builtin_data_ptr, buf); + addr = gdbarch_pointer_to_address (gdbarch, builtin->builtin_data_ptr, + buf.data ()); return addr + offset; } @@ -2057,7 +2060,8 @@ fbsd_get_thread_local_address (struct gdbarch *gdbarch, CORE_ADDR dtv_addr, CORE_ADDR fbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc) { - struct bound_minimal_symbol msym = lookup_bound_minimal_symbol ("_rtld_bind"); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, "_rtld_bind"); if (msym.minsym != nullptr && msym.value_address () == pc) return frame_unwind_caller_pc (get_current_frame ()); diff --git a/gdb/features/btrace-conf.dtd b/gdb/features/btrace-conf.dtd index 57300ea..87a4a84 100644 --- a/gdb/features/btrace-conf.dtd +++ b/gdb/features/btrace-conf.dtd @@ -12,3 +12,4 @@ <!ELEMENT pt EMPTY> <!ATTLIST pt size CDATA #IMPLIED> +<!ATTLIST pt ptwrite (yes | no) #IMPLIED> diff --git a/gdb/findvar.c b/gdb/findvar.c index df4ab1a..f7760aa 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -449,8 +449,8 @@ language_defn::read_var_value (struct symbol *var, (var->arch (), [var, &bmsym] (objfile *objfile) { - bmsym = lookup_minimal_symbol (var->linkage_name (), nullptr, - objfile); + bmsym = lookup_minimal_symbol (current_program_space, + var->linkage_name (), objfile); /* Stop if a match is found. */ return bmsym.minsym != nullptr; diff --git a/gdb/frame.c b/gdb/frame.c index 43efac0..4d092d0 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -2584,7 +2584,7 @@ inside_main_func (const frame_info_ptr &this_frame) CORE_ADDR sym_addr = 0; const char *name = main_name (); bound_minimal_symbol msymbol - = lookup_minimal_symbol (name, NULL, + = lookup_minimal_symbol (current_program_space, name, current_program_space->symfile_object_file); if (msymbol.minsym != nullptr) @@ -2628,7 +2628,7 @@ inside_entry_func (const frame_info_ptr &this_frame) { CORE_ADDR entry_point; - if (!entry_point_address_query (&entry_point)) + if (!entry_point_address_query (current_program_space, &entry_point)) return false; return get_frame_func (this_frame) == entry_point; diff --git a/gdb/frv-tdep.c b/gdb/frv-tdep.c index 1b5e15f..6ae3f0d 100644 --- a/gdb/frv-tdep.c +++ b/gdb/frv-tdep.c @@ -1062,14 +1062,13 @@ frv_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) { LONGEST displ; CORE_ADDR call_dest; - struct bound_minimal_symbol s; displ = ((op & 0xfe000000) >> 7) | (op & 0x0003ffff); if ((displ & 0x00800000) != 0) displ |= ~((LONGEST) 0x00ffffff); call_dest = pc + 4 * displ; - s = lookup_minimal_symbol_by_pc (call_dest); + bound_minimal_symbol s = lookup_minimal_symbol_by_pc (call_dest); if (s.minsym != NULL && s.minsym->linkage_name () != NULL @@ -1374,14 +1373,14 @@ frv_frame_this_id (const frame_info_ptr &this_frame, = frv_frame_unwind_cache (this_frame, this_prologue_cache); CORE_ADDR base; CORE_ADDR func; - struct bound_minimal_symbol msym_stack; struct frame_id id; /* The FUNC is easy. */ func = get_frame_func (this_frame); /* Check if the stack is empty. */ - msym_stack = lookup_minimal_symbol ("_stack", NULL, NULL); + bound_minimal_symbol msym_stack + = lookup_minimal_symbol (current_program_space, "_stack"); if (msym_stack.minsym && info->base == msym_stack.value_address ()) return; diff --git a/gdb/ft32-tdep.c b/gdb/ft32-tdep.c index 647c584..15a585a 100644 --- a/gdb/ft32-tdep.c +++ b/gdb/ft32-tdep.c @@ -174,8 +174,8 @@ ft32_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr, ULONGEST inst; int isize = 0; int regnum, pushreg; - struct bound_minimal_symbol msymbol; const int first_saved_reg = 13; /* The first saved register. */ + /* PROLOGS are addresses of the subroutine prologs, PROLOGS[n] is the address of __prolog_$rN. __prolog_$rN pushes registers from 13 through n inclusive. @@ -195,7 +195,8 @@ ft32_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr, snprintf (prolog_symbol, sizeof (prolog_symbol), "__prolog_$r%02d", regnum); - msymbol = lookup_minimal_symbol (prolog_symbol, NULL, NULL); + bound_minimal_symbol msymbol + = lookup_minimal_symbol (current_program_space, prolog_symbol); if (msymbol.minsym) prologs[regnum] = msymbol.value_address (); else diff --git a/gdb/gcore.c b/gdb/gcore.c index 2ab00a0..969a854 100644 --- a/gdb/gcore.c +++ b/gdb/gcore.c @@ -269,13 +269,14 @@ call_target_sbrk (int sbrk_arg) struct value *sbrk_fn, *ret; bfd_vma tmp; - if (lookup_minimal_symbol ("sbrk", NULL, NULL).minsym != NULL) + if (lookup_minimal_symbol (current_program_space, "sbrk").minsym != nullptr) { sbrk_fn = find_function_in_inferior ("sbrk", &sbrk_objf); if (sbrk_fn == NULL) return (bfd_vma) 0; } - else if (lookup_minimal_symbol ("_sbrk", NULL, NULL).minsym != NULL) + else if (lookup_minimal_symbol (current_program_space, "_sbrk").minsym + != nullptr) { sbrk_fn = find_function_in_inferior ("_sbrk", &sbrk_objf); if (sbrk_fn == NULL) diff --git a/gdb/gcore.in b/gdb/gcore.in index 982c854..0c40e5a 100644 --- a/gdb/gcore.in +++ b/gdb/gcore.in @@ -27,7 +27,9 @@ prefix=core # to ensure gdb dumps all mappings (OS dependent). dump_all_cmds=() -while getopts :ao: opt; do +data_directory_opt=() + +while getopts :ao:d: opt; do case "$opt" in a) case "$OSTYPE" in @@ -40,8 +42,11 @@ while getopts :ao: opt; do o) prefix=$OPTARG ;; + d) + data_directory_opt=("--data-directory" "$OPTARG") + ;; *) - echo "usage: @GCORE_TRANSFORM_NAME@ [-a] [-o prefix] pid1 [pid2...pidN]" + echo "usage: @GCORE_TRANSFORM_NAME@ [-a] [-o prefix] [-d data-directory] pid1 [pid2...pidN]" exit 2 ;; esac @@ -51,7 +56,7 @@ shift $((OPTIND-1)) if [ "$#" -eq "0" ] then - echo "usage: @GCORE_TRANSFORM_NAME@ [-a] [-o prefix] pid1 [pid2...pidN]" + echo "usage: @GCORE_TRANSFORM_NAME@ [-a] [-o prefix] [-d data-directory] pid1 [pid2...pidN]" exit 2 fi @@ -98,6 +103,7 @@ do # `</dev/null' to avoid touching interactive terminal if it is # available but not accessible as GDB would get stopped on SIGTTIN. "$binary_path/@GDB_TRANSFORM_NAME@" </dev/null \ + "${data_directory_opt[@]}" \ --nx --batch --readnever -iex 'set debuginfod enabled off' \ -ex "set pagination off" -ex "set height 0" -ex "set width 0" \ "${dump_all_cmds[@]}" \ diff --git a/gdb/gdb-gdb.py.in b/gdb/gdb-gdb.py.in index b5a7fa4..7cab694 100644 --- a/gdb/gdb-gdb.py.in +++ b/gdb/gdb-gdb.py.in @@ -342,7 +342,7 @@ class IntrusiveListPrinter: corresponding intrusive_list_node. """ - assert elem_ptr.type.code == gdb.TYPE_CODE_PTR + assert elem_ptr.type.strip_typedefs().code == gdb.TYPE_CODE_PTR if self._uses_member_node(): # Node as a member: add the member node offset from to the element's diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c index 7e272c7..0854d57 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/gdbarch.c b/gdb/gdbarch-gen.c index 58e9ebb..0d00cd7 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch-gen.c @@ -297,144 +297,144 @@ verify_gdbarch (struct gdbarch *gdbarch) if (gdbarch->bfd_arch_info == NULL) log.puts ("\n\tbfd_arch_info"); /* Check those that need to be defined for the given multi-arch level. */ - /* Skip verify of short_bit, invalid_p == 0 */ - /* Skip verify of int_bit, invalid_p == 0 */ - /* Skip verify of long_bit, invalid_p == 0 */ - /* Skip verify of long_long_bit, invalid_p == 0 */ - /* Skip verify of bfloat16_bit, invalid_p == 0 */ - /* Skip verify of bfloat16_format, invalid_p == 0 */ - /* Skip verify of half_bit, invalid_p == 0 */ - /* Skip verify of half_format, invalid_p == 0 */ - /* Skip verify of float_bit, invalid_p == 0 */ - /* Skip verify of float_format, invalid_p == 0 */ - /* Skip verify of double_bit, invalid_p == 0 */ - /* Skip verify of double_format, invalid_p == 0 */ - /* Skip verify of long_double_bit, invalid_p == 0 */ - /* Skip verify of long_double_format, invalid_p == 0 */ - /* Skip verify of wchar_bit, invalid_p == 0 */ + /* Skip verify of short_bit, invalid_p == 0. */ + /* Skip verify of int_bit, invalid_p == 0. */ + /* Skip verify of long_bit, invalid_p == 0. */ + /* Skip verify of long_long_bit, invalid_p == 0. */ + /* Skip verify of bfloat16_bit, invalid_p == 0. */ + /* Skip verify of bfloat16_format, invalid_p == 0. */ + /* Skip verify of half_bit, invalid_p == 0. */ + /* Skip verify of half_format, invalid_p == 0. */ + /* Skip verify of float_bit, invalid_p == 0. */ + /* Skip verify of float_format, invalid_p == 0. */ + /* Skip verify of double_bit, invalid_p == 0. */ + /* Skip verify of double_format, invalid_p == 0. */ + /* Skip verify of long_double_bit, invalid_p == 0. */ + /* Skip verify of long_double_format, invalid_p == 0. */ + /* Skip verify of wchar_bit, invalid_p == 0. */ if (gdbarch->wchar_signed == -1) gdbarch->wchar_signed = 1; - /* Skip verify of wchar_signed, invalid_p == 0 */ - /* Skip verify of floatformat_for_type, invalid_p == 0 */ - /* Skip verify of ptr_bit, invalid_p == 0 */ + /* Skip verify of wchar_signed, invalid_p == 0. */ + /* Skip verify of floatformat_for_type, invalid_p == 0. */ + /* Skip verify of ptr_bit, invalid_p == 0. */ if (gdbarch->addr_bit == 0) gdbarch->addr_bit = gdbarch_ptr_bit (gdbarch); - /* Skip verify of addr_bit, invalid_p == 0 */ + /* Skip verify of addr_bit, invalid_p == 0. */ if (gdbarch->dwarf2_addr_size == 0) gdbarch->dwarf2_addr_size = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT; - /* Skip verify of dwarf2_addr_size, invalid_p == 0 */ + /* Skip verify of dwarf2_addr_size, invalid_p == 0. */ if (gdbarch->char_signed == -1) gdbarch->char_signed = 1; - /* Skip verify of char_signed, invalid_p == 0 */ + /* Skip verify of char_signed, invalid_p == 0. */ /* Skip verify of read_pc, has predicate. */ /* Skip verify of write_pc, has predicate. */ - /* Skip verify of virtual_frame_pointer, invalid_p == 0 */ + /* Skip verify of virtual_frame_pointer, invalid_p == 0. */ /* Skip verify of pseudo_register_read, has predicate. */ /* Skip verify of pseudo_register_read_value, has predicate. */ /* Skip verify of pseudo_register_write, has predicate. */ /* Skip verify of deprecated_pseudo_register_write, has predicate. */ if (gdbarch->num_regs == -1) log.puts ("\n\tnum_regs"); - /* Skip verify of num_pseudo_regs, invalid_p == 0 */ + /* Skip verify of num_pseudo_regs, invalid_p == 0. */ /* Skip verify of ax_pseudo_register_collect, has predicate. */ /* Skip verify of ax_pseudo_register_push_stack, has predicate. */ /* Skip verify of report_signal_info, has predicate. */ - /* Skip verify of sp_regnum, invalid_p == 0 */ - /* Skip verify of pc_regnum, invalid_p == 0 */ - /* Skip verify of ps_regnum, invalid_p == 0 */ - /* Skip verify of fp0_regnum, invalid_p == 0 */ - /* Skip verify of stab_reg_to_regnum, invalid_p == 0 */ - /* Skip verify of ecoff_reg_to_regnum, invalid_p == 0 */ - /* Skip verify of sdb_reg_to_regnum, invalid_p == 0 */ - /* Skip verify of dwarf2_reg_to_regnum, invalid_p == 0 */ + /* Skip verify of sp_regnum, invalid_p == 0. */ + /* Skip verify of pc_regnum, invalid_p == 0. */ + /* Skip verify of ps_regnum, invalid_p == 0. */ + /* Skip verify of fp0_regnum, invalid_p == 0. */ + /* Skip verify of stab_reg_to_regnum, invalid_p == 0. */ + /* Skip verify of ecoff_reg_to_regnum, invalid_p == 0. */ + /* Skip verify of sdb_reg_to_regnum, invalid_p == 0. */ + /* Skip verify of dwarf2_reg_to_regnum, invalid_p == 0. */ if (gdbarch->register_name == 0) log.puts ("\n\tregister_name"); if (gdbarch->register_type == 0) log.puts ("\n\tregister_type"); - /* Skip verify of dummy_id, invalid_p == 0 */ - /* Skip verify of deprecated_fp_regnum, invalid_p == 0 */ + /* Skip verify of dummy_id, invalid_p == 0. */ + /* Skip verify of deprecated_fp_regnum, invalid_p == 0. */ /* Skip verify of push_dummy_call, has predicate. */ - /* Skip verify of call_dummy_location, invalid_p == 0 */ + /* Skip verify of call_dummy_location, invalid_p == 0. */ /* Skip verify of push_dummy_code, has predicate. */ - /* Skip verify of code_of_frame_writable, invalid_p == 0 */ - /* Skip verify of print_registers_info, invalid_p == 0 */ - /* Skip verify of print_float_info, invalid_p == 0 */ + /* Skip verify of code_of_frame_writable, invalid_p == 0. */ + /* Skip verify of print_registers_info, invalid_p == 0. */ + /* Skip verify of print_float_info, invalid_p == 0. */ /* Skip verify of print_vector_info, has predicate. */ - /* Skip verify of register_sim_regno, invalid_p == 0 */ - /* Skip verify of cannot_fetch_register, invalid_p == 0 */ - /* Skip verify of cannot_store_register, invalid_p == 0 */ + /* Skip verify of register_sim_regno, invalid_p == 0. */ + /* Skip verify of cannot_fetch_register, invalid_p == 0. */ + /* Skip verify of cannot_store_register, invalid_p == 0. */ /* Skip verify of get_longjmp_target, has predicate. */ - /* Skip verify of believe_pcc_promotion, invalid_p == 0 */ - /* Skip verify of convert_register_p, invalid_p == 0 */ - /* Skip verify of register_to_value, invalid_p == 0 */ - /* Skip verify of value_to_register, invalid_p == 0 */ - /* Skip verify of value_from_register, invalid_p == 0 */ - /* Skip verify of pointer_to_address, invalid_p == 0 */ - /* Skip verify of address_to_pointer, invalid_p == 0 */ + /* Skip verify of believe_pcc_promotion, invalid_p == 0. */ + /* Skip verify of convert_register_p, invalid_p == 0. */ + /* Skip verify of register_to_value, invalid_p == 0. */ + /* Skip verify of value_to_register, invalid_p == 0. */ + /* Skip verify of value_from_register, invalid_p == 0. */ + /* Skip verify of pointer_to_address, invalid_p == 0. */ + /* Skip verify of address_to_pointer, invalid_p == 0. */ /* Skip verify of integer_to_address, has predicate. */ - /* Skip verify of return_value, invalid_p == 0 */ + /* Skip verify of return_value, invalid_p == 0. */ if ((gdbarch->return_value_as_value == default_gdbarch_return_value) == (gdbarch->return_value == nullptr)) log.puts ("\n\treturn_value_as_value"); - /* Skip verify of get_return_buf_addr, invalid_p == 0 */ - /* Skip verify of dwarf2_omit_typedef_p, invalid_p == 0 */ - /* Skip verify of update_call_site_pc, invalid_p == 0 */ - /* Skip verify of return_in_first_hidden_param_p, invalid_p == 0 */ + /* Skip verify of get_return_buf_addr, invalid_p == 0. */ + /* Skip verify of dwarf2_omit_typedef_p, invalid_p == 0. */ + /* Skip verify of update_call_site_pc, invalid_p == 0. */ + /* Skip verify of return_in_first_hidden_param_p, invalid_p == 0. */ if (gdbarch->skip_prologue == 0) log.puts ("\n\tskip_prologue"); /* Skip verify of skip_main_prologue, has predicate. */ /* Skip verify of skip_entrypoint, has predicate. */ if (gdbarch->inner_than == 0) log.puts ("\n\tinner_than"); - /* Skip verify of breakpoint_from_pc, invalid_p == 0 */ + /* Skip verify of breakpoint_from_pc, invalid_p == 0. */ if (gdbarch->breakpoint_kind_from_pc == 0) log.puts ("\n\tbreakpoint_kind_from_pc"); - /* Skip verify of sw_breakpoint_from_kind, invalid_p == 0 */ - /* Skip verify of breakpoint_kind_from_current_state, invalid_p == 0 */ + /* Skip verify of sw_breakpoint_from_kind, invalid_p == 0. */ + /* Skip verify of breakpoint_kind_from_current_state, invalid_p == 0. */ /* Skip verify of adjust_breakpoint_address, has predicate. */ - /* Skip verify of memory_insert_breakpoint, invalid_p == 0 */ - /* Skip verify of memory_remove_breakpoint, invalid_p == 0 */ - /* Skip verify of decr_pc_after_break, invalid_p == 0 */ - /* Skip verify of deprecated_function_start_offset, invalid_p == 0 */ - /* Skip verify of remote_register_number, invalid_p == 0 */ + /* Skip verify of memory_insert_breakpoint, invalid_p == 0. */ + /* Skip verify of memory_remove_breakpoint, invalid_p == 0. */ + /* Skip verify of decr_pc_after_break, invalid_p == 0. */ + /* Skip verify of deprecated_function_start_offset, invalid_p == 0. */ + /* Skip verify of remote_register_number, invalid_p == 0. */ /* Skip verify of fetch_tls_load_module_address, has predicate. */ /* Skip verify of get_thread_local_address, has predicate. */ - /* Skip verify of frame_args_skip, invalid_p == 0 */ - /* Skip verify of unwind_pc, invalid_p == 0 */ - /* Skip verify of unwind_sp, invalid_p == 0 */ + /* Skip verify of frame_args_skip, invalid_p == 0. */ + /* Skip verify of unwind_pc, invalid_p == 0. */ + /* Skip verify of unwind_sp, invalid_p == 0. */ /* Skip verify of frame_num_args, has predicate. */ /* Skip verify of frame_align, has predicate. */ - /* Skip verify of stabs_argument_has_addr, invalid_p == 0 */ - /* Skip verify of frame_red_zone_size, invalid_p == 0 */ - /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */ - /* Skip verify of addr_bits_remove, invalid_p == 0 */ - /* Skip verify of remove_non_address_bits, invalid_p == 0 */ - /* Skip verify of memtag_to_string, invalid_p == 0 */ - /* Skip verify of tagged_address_p, invalid_p == 0 */ - /* Skip verify of memtag_matches_p, invalid_p == 0 */ - /* Skip verify of set_memtags, invalid_p == 0 */ - /* Skip verify of get_memtag, invalid_p == 0 */ - /* Skip verify of memtag_granule_size, invalid_p == 0 */ + /* Skip verify of stabs_argument_has_addr, invalid_p == 0. */ + /* Skip verify of frame_red_zone_size, invalid_p == 0. */ + /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0. */ + /* Skip verify of addr_bits_remove, invalid_p == 0. */ + /* Skip verify of remove_non_address_bits, invalid_p == 0. */ + /* Skip verify of memtag_to_string, invalid_p == 0. */ + /* Skip verify of tagged_address_p, invalid_p == 0. */ + /* Skip verify of memtag_matches_p, invalid_p == 0. */ + /* Skip verify of set_memtags, invalid_p == 0. */ + /* Skip verify of get_memtag, invalid_p == 0. */ + /* Skip verify of memtag_granule_size, invalid_p == 0. */ /* Skip verify of software_single_step, has predicate. */ /* Skip verify of single_step_through_delay, has predicate. */ - /* Skip verify of print_insn, invalid_p == 0 */ - /* Skip verify of skip_trampoline_code, invalid_p == 0 */ - /* Skip verify of so_ops, invalid_p == 0 */ - /* Skip verify of skip_solib_resolver, invalid_p == 0 */ - /* Skip verify of in_solib_return_trampoline, invalid_p == 0 */ - /* Skip verify of in_indirect_branch_thunk, invalid_p == 0 */ - /* Skip verify of stack_frame_destroyed_p, invalid_p == 0 */ + /* Skip verify of print_insn, invalid_p == 0. */ + /* Skip verify of skip_trampoline_code, invalid_p == 0. */ + /* Skip verify of so_ops, invalid_p == 0. */ + /* Skip verify of skip_solib_resolver, invalid_p == 0. */ + /* Skip verify of in_solib_return_trampoline, invalid_p == 0. */ + /* Skip verify of in_indirect_branch_thunk, invalid_p == 0. */ + /* Skip verify of stack_frame_destroyed_p, invalid_p == 0. */ /* Skip verify of elf_make_msymbol_special, has predicate. */ - /* Skip verify of coff_make_msymbol_special, invalid_p == 0 */ - /* Skip verify of make_symbol_special, invalid_p == 0 */ - /* Skip verify of adjust_dwarf2_addr, invalid_p == 0 */ - /* Skip verify of adjust_dwarf2_line, invalid_p == 0 */ - /* Skip verify of cannot_step_breakpoint, invalid_p == 0 */ - /* Skip verify of have_nonsteppable_watchpoint, invalid_p == 0 */ + /* Skip verify of coff_make_msymbol_special, invalid_p == 0. */ + /* Skip verify of make_symbol_special, invalid_p == 0. */ + /* Skip verify of adjust_dwarf2_addr, invalid_p == 0. */ + /* Skip verify of adjust_dwarf2_line, invalid_p == 0. */ + /* Skip verify of cannot_step_breakpoint, invalid_p == 0. */ + /* Skip verify of have_nonsteppable_watchpoint, invalid_p == 0. */ /* Skip verify of address_class_type_flags, has predicate. */ /* Skip verify of address_class_type_flags_to_name, has predicate. */ - /* Skip verify of execute_dwarf_cfa_vendor_op, invalid_p == 0 */ + /* Skip verify of execute_dwarf_cfa_vendor_op, invalid_p == 0. */ /* Skip verify of address_class_name_to_type_flags, has predicate. */ - /* Skip verify of register_reggroup_p, invalid_p == 0 */ + /* Skip verify of register_reggroup_p, invalid_p == 0. */ /* Skip verify of fetch_pointer_argument, has predicate. */ /* Skip verify of iterate_over_regset_sections, has predicate. */ /* Skip verify of make_corefile_notes, has predicate. */ @@ -449,19 +449,19 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of core_xfer_siginfo, has predicate. */ /* Skip verify of core_read_x86_xsave_layout, 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 */ - /* Skip verify of skip_permanent_breakpoint, invalid_p == 0 */ + /* Skip verify of vtable_function_descriptors, invalid_p == 0. */ + /* Skip verify of vbit_in_delta, invalid_p == 0. */ + /* Skip verify of skip_permanent_breakpoint, invalid_p == 0. */ /* Skip verify of max_insn_length, has predicate. */ /* Skip verify of displaced_step_copy_insn, has predicate. */ - /* Skip verify of displaced_step_hw_singlestep, invalid_p == 0 */ + /* Skip verify of displaced_step_hw_singlestep, invalid_p == 0. */ if ((gdbarch->displaced_step_copy_insn == nullptr) != (gdbarch->displaced_step_fixup == nullptr)) log.puts ("\n\tdisplaced_step_fixup"); /* Skip verify of displaced_step_prepare, has predicate. */ if ((! gdbarch->displaced_step_finish) != (! gdbarch->displaced_step_prepare)) log.puts ("\n\tdisplaced_step_finish"); /* Skip verify of displaced_step_copy_insn_closure_by_addr, has predicate. */ - /* Skip verify of displaced_step_restore_all_in_ptid, invalid_p == 0 */ + /* Skip verify of displaced_step_restore_all_in_ptid, invalid_p == 0. */ if (gdbarch->displaced_step_buffer_length == 0) gdbarch->displaced_step_buffer_length = gdbarch->max_insn_length; if (gdbarch->displaced_step_buffer_length < gdbarch->max_insn_length) @@ -469,7 +469,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of relocate_instruction, has predicate. */ /* Skip verify of overlay_update, has predicate. */ /* Skip verify of core_read_description, has predicate. */ - /* Skip verify of sofun_address_maybe_missing, invalid_p == 0 */ + /* Skip verify of sofun_address_maybe_missing, invalid_p == 0. */ /* Skip verify of process_record, has predicate. */ /* Skip verify of process_record_signal, has predicate. */ /* Skip verify of gdb_signal_from_target, has predicate. */ @@ -477,16 +477,16 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of get_siginfo_type, has predicate. */ /* Skip verify of record_special_symbol, has predicate. */ /* Skip verify of get_syscall_number, has predicate. */ - /* Skip verify of xml_syscall_file, invalid_p == 0 */ - /* Skip verify of syscalls_info, invalid_p == 0 */ - /* Skip verify of stap_integer_prefixes, invalid_p == 0 */ - /* Skip verify of stap_integer_suffixes, invalid_p == 0 */ - /* Skip verify of stap_register_prefixes, invalid_p == 0 */ - /* Skip verify of stap_register_suffixes, invalid_p == 0 */ - /* Skip verify of stap_register_indirection_prefixes, invalid_p == 0 */ - /* Skip verify of stap_register_indirection_suffixes, invalid_p == 0 */ - /* Skip verify of stap_gdb_register_prefix, invalid_p == 0 */ - /* Skip verify of stap_gdb_register_suffix, invalid_p == 0 */ + /* Skip verify of xml_syscall_file, invalid_p == 0. */ + /* Skip verify of syscalls_info, invalid_p == 0. */ + /* Skip verify of stap_integer_prefixes, invalid_p == 0. */ + /* Skip verify of stap_integer_suffixes, invalid_p == 0. */ + /* Skip verify of stap_register_prefixes, invalid_p == 0. */ + /* Skip verify of stap_register_suffixes, invalid_p == 0. */ + /* Skip verify of stap_register_indirection_prefixes, invalid_p == 0. */ + /* Skip verify of stap_register_indirection_suffixes, invalid_p == 0. */ + /* Skip verify of stap_gdb_register_prefix, invalid_p == 0. */ + /* Skip verify of stap_gdb_register_suffix, invalid_p == 0. */ /* Skip verify of stap_is_single_operand, has predicate. */ /* Skip verify of stap_parse_special_token, has predicate. */ /* Skip verify of stap_adjust_register, has predicate. */ @@ -494,39 +494,39 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of dtrace_probe_is_enabled, has predicate. */ /* Skip verify of dtrace_enable_probe, has predicate. */ /* Skip verify of dtrace_disable_probe, has predicate. */ - /* Skip verify of has_global_solist, invalid_p == 0 */ - /* Skip verify of has_global_breakpoints, invalid_p == 0 */ - /* Skip verify of has_shared_address_space, invalid_p == 0 */ - /* Skip verify of fast_tracepoint_valid_at, invalid_p == 0 */ - /* Skip verify of guess_tracepoint_registers, invalid_p == 0 */ - /* Skip verify of auto_charset, invalid_p == 0 */ - /* Skip verify of auto_wide_charset, invalid_p == 0 */ - /* Skip verify of solib_symbols_extension, invalid_p == 0 */ - /* Skip verify of has_dos_based_file_system, invalid_p == 0 */ - /* Skip verify of gen_return_address, invalid_p == 0 */ + /* Skip verify of has_global_solist, invalid_p == 0. */ + /* Skip verify of has_global_breakpoints, invalid_p == 0. */ + /* Skip verify of has_shared_address_space, invalid_p == 0. */ + /* Skip verify of fast_tracepoint_valid_at, invalid_p == 0. */ + /* Skip verify of guess_tracepoint_registers, invalid_p == 0. */ + /* Skip verify of auto_charset, invalid_p == 0. */ + /* Skip verify of auto_wide_charset, invalid_p == 0. */ + /* Skip verify of solib_symbols_extension, invalid_p == 0. */ + /* Skip verify of has_dos_based_file_system, invalid_p == 0. */ + /* Skip verify of gen_return_address, invalid_p == 0. */ /* Skip verify of info_proc, has predicate. */ /* Skip verify of core_info_proc, has predicate. */ - /* Skip verify of iterate_over_objfiles_in_search_order, invalid_p == 0 */ - /* Skip verify of ravenscar_ops, invalid_p == 0 */ - /* Skip verify of insn_is_call, invalid_p == 0 */ - /* Skip verify of insn_is_ret, invalid_p == 0 */ - /* Skip verify of insn_is_jump, invalid_p == 0 */ - /* Skip verify of program_breakpoint_here_p, invalid_p == 0 */ + /* Skip verify of iterate_over_objfiles_in_search_order, invalid_p == 0. */ + /* Skip verify of ravenscar_ops, invalid_p == 0. */ + /* Skip verify of insn_is_call, invalid_p == 0. */ + /* Skip verify of insn_is_ret, invalid_p == 0. */ + /* Skip verify of insn_is_jump, invalid_p == 0. */ + /* Skip verify of program_breakpoint_here_p, invalid_p == 0. */ /* Skip verify of auxv_parse, has predicate. */ - /* Skip verify of print_auxv_entry, invalid_p == 0 */ - /* Skip verify of vsyscall_range, invalid_p == 0 */ - /* Skip verify of infcall_mmap, invalid_p == 0 */ - /* Skip verify of infcall_munmap, invalid_p == 0 */ - /* Skip verify of gcc_target_options, invalid_p == 0 */ - /* Skip verify of gnu_triplet_regexp, invalid_p == 0 */ - /* Skip verify of addressable_memory_unit_size, invalid_p == 0 */ - /* Skip verify of disassembler_options_implicit, invalid_p == 0 */ - /* Skip verify of disassembler_options, invalid_p == 0 */ - /* Skip verify of valid_disassembler_options, invalid_p == 0 */ - /* Skip verify of type_align, invalid_p == 0 */ - /* Skip verify of get_pc_address_flags, invalid_p == 0 */ - /* Skip verify of read_core_file_mappings, invalid_p == 0 */ - /* Skip verify of use_target_description_from_corefile_notes, invalid_p == 0 */ + /* Skip verify of print_auxv_entry, invalid_p == 0. */ + /* Skip verify of vsyscall_range, invalid_p == 0. */ + /* Skip verify of infcall_mmap, invalid_p == 0. */ + /* Skip verify of infcall_munmap, invalid_p == 0. */ + /* Skip verify of gcc_target_options, invalid_p == 0. */ + /* Skip verify of gnu_triplet_regexp, invalid_p == 0. */ + /* Skip verify of addressable_memory_unit_size, invalid_p == 0. */ + /* Skip verify of disassembler_options_implicit, invalid_p == 0. */ + /* Skip verify of disassembler_options, invalid_p == 0. */ + /* Skip verify of valid_disassembler_options, invalid_p == 0. */ + /* Skip verify of type_align, invalid_p == 0. */ + /* Skip verify of get_pc_address_flags, invalid_p == 0. */ + /* Skip verify of read_core_file_mappings, invalid_p == 0. */ + /* Skip verify of use_target_description_from_corefile_notes, invalid_p == 0. */ if (!log.empty ()) internal_error (_("verify_gdbarch: the following are invalid ...%s"), log.c_str ()); @@ -1440,7 +1440,7 @@ int gdbarch_short_bit (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of short_bit, invalid_p == 0 */ + /* Skip verify of short_bit, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_short_bit called\n"); return gdbarch->short_bit; @@ -1457,7 +1457,7 @@ int gdbarch_int_bit (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of int_bit, invalid_p == 0 */ + /* Skip verify of int_bit, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_int_bit called\n"); return gdbarch->int_bit; @@ -1474,7 +1474,7 @@ int gdbarch_long_bit (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of long_bit, invalid_p == 0 */ + /* Skip verify of long_bit, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_long_bit called\n"); return gdbarch->long_bit; @@ -1491,7 +1491,7 @@ int gdbarch_long_long_bit (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of long_long_bit, invalid_p == 0 */ + /* Skip verify of long_long_bit, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_long_long_bit called\n"); return gdbarch->long_long_bit; @@ -1508,7 +1508,7 @@ int gdbarch_bfloat16_bit (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of bfloat16_bit, invalid_p == 0 */ + /* Skip verify of bfloat16_bit, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_bfloat16_bit called\n"); return gdbarch->bfloat16_bit; @@ -1525,7 +1525,7 @@ const struct floatformat ** gdbarch_bfloat16_format (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of bfloat16_format, invalid_p == 0 */ + /* Skip verify of bfloat16_format, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_bfloat16_format called\n"); return gdbarch->bfloat16_format; @@ -1542,7 +1542,7 @@ int gdbarch_half_bit (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of half_bit, invalid_p == 0 */ + /* Skip verify of half_bit, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_half_bit called\n"); return gdbarch->half_bit; @@ -1559,7 +1559,7 @@ const struct floatformat ** gdbarch_half_format (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of half_format, invalid_p == 0 */ + /* Skip verify of half_format, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_half_format called\n"); return gdbarch->half_format; @@ -1576,7 +1576,7 @@ int gdbarch_float_bit (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of float_bit, invalid_p == 0 */ + /* Skip verify of float_bit, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_float_bit called\n"); return gdbarch->float_bit; @@ -1593,7 +1593,7 @@ const struct floatformat ** gdbarch_float_format (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of float_format, invalid_p == 0 */ + /* Skip verify of float_format, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_float_format called\n"); return gdbarch->float_format; @@ -1610,7 +1610,7 @@ int gdbarch_double_bit (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of double_bit, invalid_p == 0 */ + /* Skip verify of double_bit, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_double_bit called\n"); return gdbarch->double_bit; @@ -1627,7 +1627,7 @@ const struct floatformat ** gdbarch_double_format (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of double_format, invalid_p == 0 */ + /* Skip verify of double_format, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_double_format called\n"); return gdbarch->double_format; @@ -1644,7 +1644,7 @@ int gdbarch_long_double_bit (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of long_double_bit, invalid_p == 0 */ + /* Skip verify of long_double_bit, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_long_double_bit called\n"); return gdbarch->long_double_bit; @@ -1661,7 +1661,7 @@ const struct floatformat ** gdbarch_long_double_format (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of long_double_format, invalid_p == 0 */ + /* Skip verify of long_double_format, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_long_double_format called\n"); return gdbarch->long_double_format; @@ -1678,7 +1678,7 @@ int gdbarch_wchar_bit (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of wchar_bit, invalid_p == 0 */ + /* Skip verify of wchar_bit, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_wchar_bit called\n"); return gdbarch->wchar_bit; @@ -1730,7 +1730,7 @@ int gdbarch_ptr_bit (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of ptr_bit, invalid_p == 0 */ + /* Skip verify of ptr_bit, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_ptr_bit called\n"); return gdbarch->ptr_bit; @@ -1980,7 +1980,7 @@ int gdbarch_num_pseudo_regs (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of num_pseudo_regs, invalid_p == 0 */ + /* Skip verify of num_pseudo_regs, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_num_pseudo_regs called\n"); return gdbarch->num_pseudo_regs; @@ -2069,7 +2069,7 @@ int gdbarch_sp_regnum (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of sp_regnum, invalid_p == 0 */ + /* Skip verify of sp_regnum, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_sp_regnum called\n"); return gdbarch->sp_regnum; @@ -2086,7 +2086,7 @@ int gdbarch_pc_regnum (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of pc_regnum, invalid_p == 0 */ + /* Skip verify of pc_regnum, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_pc_regnum called\n"); return gdbarch->pc_regnum; @@ -2103,7 +2103,7 @@ int gdbarch_ps_regnum (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of ps_regnum, invalid_p == 0 */ + /* Skip verify of ps_regnum, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_ps_regnum called\n"); return gdbarch->ps_regnum; @@ -2120,7 +2120,7 @@ int gdbarch_fp0_regnum (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of fp0_regnum, invalid_p == 0 */ + /* Skip verify of fp0_regnum, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_fp0_regnum called\n"); return gdbarch->fp0_regnum; @@ -2260,7 +2260,7 @@ int gdbarch_deprecated_fp_regnum (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of deprecated_fp_regnum, invalid_p == 0 */ + /* Skip verify of deprecated_fp_regnum, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_deprecated_fp_regnum called\n"); return gdbarch->deprecated_fp_regnum; @@ -2301,7 +2301,7 @@ enum call_dummy_location_type gdbarch_call_dummy_location (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of call_dummy_location, invalid_p == 0 */ + /* Skip verify of call_dummy_location, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_call_dummy_location called\n"); return gdbarch->call_dummy_location; @@ -2492,7 +2492,7 @@ int gdbarch_believe_pcc_promotion (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of believe_pcc_promotion, invalid_p == 0 */ + /* Skip verify of believe_pcc_promotion, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_believe_pcc_promotion called\n"); return gdbarch->believe_pcc_promotion; @@ -2935,7 +2935,7 @@ CORE_ADDR gdbarch_decr_pc_after_break (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of decr_pc_after_break, invalid_p == 0 */ + /* Skip verify of decr_pc_after_break, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_decr_pc_after_break called\n"); return gdbarch->decr_pc_after_break; @@ -2952,7 +2952,7 @@ CORE_ADDR gdbarch_deprecated_function_start_offset (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of deprecated_function_start_offset, invalid_p == 0 */ + /* Skip verify of deprecated_function_start_offset, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_deprecated_function_start_offset called\n"); return gdbarch->deprecated_function_start_offset; @@ -3034,7 +3034,7 @@ CORE_ADDR gdbarch_frame_args_skip (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of frame_args_skip, invalid_p == 0 */ + /* Skip verify of frame_args_skip, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_frame_args_skip called\n"); return gdbarch->frame_args_skip; @@ -3150,7 +3150,7 @@ int gdbarch_frame_red_zone_size (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of frame_red_zone_size, invalid_p == 0 */ + /* Skip verify of frame_red_zone_size, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_frame_red_zone_size called\n"); return gdbarch->frame_red_zone_size; @@ -3303,7 +3303,7 @@ CORE_ADDR gdbarch_memtag_granule_size (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of memtag_granule_size, invalid_p == 0 */ + /* Skip verify of memtag_granule_size, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_memtag_granule_size called\n"); return gdbarch->memtag_granule_size; @@ -3402,7 +3402,7 @@ const solib_ops * gdbarch_so_ops (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of so_ops, invalid_p == 0 */ + /* Skip verify of so_ops, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_so_ops called\n"); return gdbarch->so_ops; @@ -3579,7 +3579,7 @@ int gdbarch_cannot_step_breakpoint (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of cannot_step_breakpoint, invalid_p == 0 */ + /* Skip verify of cannot_step_breakpoint, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_cannot_step_breakpoint called\n"); return gdbarch->cannot_step_breakpoint; @@ -3596,7 +3596,7 @@ int gdbarch_have_nonsteppable_watchpoint (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of have_nonsteppable_watchpoint, invalid_p == 0 */ + /* Skip verify of have_nonsteppable_watchpoint, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_have_nonsteppable_watchpoint called\n"); return gdbarch->have_nonsteppable_watchpoint; @@ -4056,7 +4056,7 @@ int gdbarch_vtable_function_descriptors (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of vtable_function_descriptors, invalid_p == 0 */ + /* Skip verify of vtable_function_descriptors, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_vtable_function_descriptors called\n"); return gdbarch->vtable_function_descriptors; @@ -4073,7 +4073,7 @@ int gdbarch_vbit_in_delta (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of vbit_in_delta, invalid_p == 0 */ + /* Skip verify of vbit_in_delta, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_vbit_in_delta called\n"); return gdbarch->vbit_in_delta; @@ -4363,7 +4363,7 @@ int gdbarch_sofun_address_maybe_missing (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of sofun_address_maybe_missing, invalid_p == 0 */ + /* Skip verify of sofun_address_maybe_missing, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_sofun_address_maybe_missing called\n"); return gdbarch->sofun_address_maybe_missing; @@ -4548,7 +4548,7 @@ const char * gdbarch_xml_syscall_file (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of xml_syscall_file, invalid_p == 0 */ + /* Skip verify of xml_syscall_file, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_xml_syscall_file called\n"); return gdbarch->xml_syscall_file; @@ -4565,7 +4565,7 @@ struct syscalls_info * gdbarch_syscalls_info (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of syscalls_info, invalid_p == 0 */ + /* Skip verify of syscalls_info, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_syscalls_info called\n"); return gdbarch->syscalls_info; @@ -4582,7 +4582,7 @@ const char *const * gdbarch_stap_integer_prefixes (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of stap_integer_prefixes, invalid_p == 0 */ + /* Skip verify of stap_integer_prefixes, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_stap_integer_prefixes called\n"); return gdbarch->stap_integer_prefixes; @@ -4599,7 +4599,7 @@ const char *const * gdbarch_stap_integer_suffixes (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of stap_integer_suffixes, invalid_p == 0 */ + /* Skip verify of stap_integer_suffixes, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_stap_integer_suffixes called\n"); return gdbarch->stap_integer_suffixes; @@ -4616,7 +4616,7 @@ const char *const * gdbarch_stap_register_prefixes (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of stap_register_prefixes, invalid_p == 0 */ + /* Skip verify of stap_register_prefixes, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_stap_register_prefixes called\n"); return gdbarch->stap_register_prefixes; @@ -4633,7 +4633,7 @@ const char *const * gdbarch_stap_register_suffixes (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of stap_register_suffixes, invalid_p == 0 */ + /* Skip verify of stap_register_suffixes, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_stap_register_suffixes called\n"); return gdbarch->stap_register_suffixes; @@ -4650,7 +4650,7 @@ const char *const * gdbarch_stap_register_indirection_prefixes (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of stap_register_indirection_prefixes, invalid_p == 0 */ + /* Skip verify of stap_register_indirection_prefixes, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_stap_register_indirection_prefixes called\n"); return gdbarch->stap_register_indirection_prefixes; @@ -4667,7 +4667,7 @@ const char *const * gdbarch_stap_register_indirection_suffixes (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of stap_register_indirection_suffixes, invalid_p == 0 */ + /* Skip verify of stap_register_indirection_suffixes, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_stap_register_indirection_suffixes called\n"); return gdbarch->stap_register_indirection_suffixes; @@ -4684,7 +4684,7 @@ const char * gdbarch_stap_gdb_register_prefix (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of stap_gdb_register_prefix, invalid_p == 0 */ + /* Skip verify of stap_gdb_register_prefix, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_stap_gdb_register_prefix called\n"); return gdbarch->stap_gdb_register_prefix; @@ -4701,7 +4701,7 @@ const char * gdbarch_stap_gdb_register_suffix (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of stap_gdb_register_suffix, invalid_p == 0 */ + /* Skip verify of stap_gdb_register_suffix, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_stap_gdb_register_suffix called\n"); return gdbarch->stap_gdb_register_suffix; @@ -4886,7 +4886,7 @@ int gdbarch_has_global_solist (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of has_global_solist, invalid_p == 0 */ + /* Skip verify of has_global_solist, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_has_global_solist called\n"); return gdbarch->has_global_solist; @@ -4903,7 +4903,7 @@ int gdbarch_has_global_breakpoints (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of has_global_breakpoints, invalid_p == 0 */ + /* Skip verify of has_global_breakpoints, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_has_global_breakpoints called\n"); return gdbarch->has_global_breakpoints; @@ -5005,7 +5005,7 @@ const char * gdbarch_solib_symbols_extension (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of solib_symbols_extension, invalid_p == 0 */ + /* Skip verify of solib_symbols_extension, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_solib_symbols_extension called\n"); return gdbarch->solib_symbols_extension; @@ -5022,7 +5022,7 @@ int gdbarch_has_dos_based_file_system (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of has_dos_based_file_system, invalid_p == 0 */ + /* Skip verify of has_dos_based_file_system, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_has_dos_based_file_system called\n"); return gdbarch->has_dos_based_file_system; @@ -5121,7 +5121,7 @@ struct ravenscar_arch_ops * gdbarch_ravenscar_ops (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of ravenscar_ops, invalid_p == 0 */ + /* Skip verify of ravenscar_ops, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_ravenscar_ops called\n"); return gdbarch->ravenscar_ops; @@ -5349,7 +5349,7 @@ const char * gdbarch_disassembler_options_implicit (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of disassembler_options_implicit, invalid_p == 0 */ + /* Skip verify of disassembler_options_implicit, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_disassembler_options_implicit called\n"); return gdbarch->disassembler_options_implicit; @@ -5366,7 +5366,7 @@ std::string * gdbarch_disassembler_options (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of disassembler_options, invalid_p == 0 */ + /* Skip verify of disassembler_options, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_disassembler_options called\n"); return gdbarch->disassembler_options; @@ -5383,7 +5383,7 @@ const disasm_options_and_args_t * gdbarch_valid_disassembler_options (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of valid_disassembler_options, invalid_p == 0 */ + /* Skip verify of valid_disassembler_options, invalid_p == 0. */ if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_valid_disassembler_options called\n"); return gdbarch->valid_disassembler_options; diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 5175ef7..60a0f60 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -316,7 +316,7 @@ extern obstack *gdbarch_obstack (gdbarch *arch); extern char *gdbarch_obstack_strdup (struct gdbarch *arch, const char *string); -/* Helper function. Force an update of the current architecture. +/* Helper function. Force an update of INF's architecture. The actual architecture selected is determined by INFO, ``(gdb) set architecture'' et.al., the existing architecture and BFD's default @@ -325,8 +325,7 @@ extern char *gdbarch_obstack_strdup (struct gdbarch *arch, const char *string); Returns non-zero if the update succeeds. */ -extern int gdbarch_update_p (struct gdbarch_info info); - +extern int gdbarch_update_p (inferior *inf, gdbarch_info info); /* Helper function. Find an architecture matching info. diff --git a/gdb/gdbarch.py b/gdb/gdbarch.py index 4b4db66..dd1658d 100755 --- a/gdb/gdbarch.py +++ b/gdb/gdbarch.py @@ -119,7 +119,7 @@ with open("gdbarch-gen.h", "w") as f: file=f, ) -with open("gdbarch.c", "w") as f: +with open("gdbarch-gen.c", "w") as f: print(copyright, file=f) print(file=f) print(file=f) @@ -233,7 +233,7 @@ with open("gdbarch.c", "w") as f: print(f" if (gdbarch->{c.name} == {init_value})", file=f) print(f""" log.puts ("\\n\\t{c.name}");""", file=f) else: - print(f" /* Skip verify of {c.name}, invalid_p == 0 */", file=f) + print(f" /* Skip verify of {c.name}, invalid_p == 0. */", file=f) print(" if (!log.empty ())", file=f) print( """ internal_error (_("verify_gdbarch: the following are invalid ...%s"),""", @@ -361,7 +361,7 @@ with open("gdbarch.c", "w") as f: print(" /* Check variable changed from its initial value. */", file=f) print(f" gdb_assert (gdbarch->{c.name} != {init_value});", file=f) else: - print(f" /* Skip verify of {c.name}, invalid_p == 0 */", file=f) + print(f" /* Skip verify of {c.name}, invalid_p == 0. */", file=f) print(" if (gdbarch_debug >= 2)", file=f) print( f""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""", diff --git a/gdb/glibc-tdep.c b/gdb/glibc-tdep.c index 48e080a..e3bf00c 100644 --- a/gdb/glibc-tdep.c +++ b/gdb/glibc-tdep.c @@ -52,18 +52,20 @@ glibc_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc) of GNU/Linux will provide a portable, efficient interface for debugging programs that use shared libraries. */ - struct bound_minimal_symbol resolver - = lookup_bound_minimal_symbol ("_dl_runtime_resolve"); + bound_minimal_symbol resolver + = lookup_minimal_symbol (current_program_space, "_dl_runtime_resolve"); if (resolver.minsym) { /* The dynamic linker began using this name in early 2005. */ - struct bound_minimal_symbol fixup - = lookup_minimal_symbol ("_dl_fixup", NULL, resolver.objfile); - + bound_minimal_symbol fixup + = lookup_minimal_symbol (current_program_space, "_dl_fixup", + resolver.objfile); + /* This is the name used in older versions. */ if (! fixup.minsym) - fixup = lookup_minimal_symbol ("fixup", NULL, resolver.objfile); + fixup = lookup_minimal_symbol (current_program_space, "fixup", + resolver.objfile); if (fixup.minsym && fixup.value_address () == pc) return frame_unwind_caller_pc (get_current_frame ()); diff --git a/gdb/gnu-v2-abi.c b/gdb/gnu-v2-abi.c index 7b511ea..0a9c09e 100644 --- a/gdb/gnu-v2-abi.c +++ b/gdb/gnu-v2-abi.c @@ -186,7 +186,6 @@ gnuv2_value_rtti_type (struct value *v, int *full, LONGEST *top, int *using_enc) struct type *known_type; struct type *rtti_type; CORE_ADDR vtbl; - struct bound_minimal_symbol minsym; char *p; const char *linkage_name; struct type *btype; @@ -239,7 +238,7 @@ gnuv2_value_rtti_type (struct value *v, int *full, LONGEST *top, int *using_enc) vtbl = value_as_address (value_field (v, known_type_vptr_fieldno)); /* Try to find a symbol that is the vtable. */ - minsym=lookup_minimal_symbol_by_pc(vtbl); + bound_minimal_symbol minsym = lookup_minimal_symbol_by_pc (vtbl); if (minsym.minsym==NULL || (linkage_name=minsym.minsym->linkage_name ())==NULL || !is_vtable_name (linkage_name)) diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c index 1311a99..aefbee5 100644 --- a/gdb/gnu-v3-abi.c +++ b/gdb/gnu-v3-abi.c @@ -1161,7 +1161,7 @@ gnuv3_get_typeid (struct value *value) { std::string sym_name = std::string ("typeinfo for ") + name; bound_minimal_symbol minsym - = lookup_minimal_symbol (sym_name.c_str (), NULL, NULL); + = lookup_minimal_symbol (current_program_space, sym_name.c_str ()); if (minsym.minsym == NULL) error (_("could not find typeinfo symbol for '%s'"), name); @@ -1178,14 +1178,13 @@ static std::string gnuv3_get_typename_from_type_info (struct value *type_info_ptr) { struct gdbarch *gdbarch = type_info_ptr->type ()->arch (); - struct bound_minimal_symbol typeinfo_sym; CORE_ADDR addr; const char *symname; const char *class_name; const char *atsign; addr = value_as_address (type_info_ptr); - typeinfo_sym = lookup_minimal_symbol_by_pc (addr); + bound_minimal_symbol typeinfo_sym = lookup_minimal_symbol_by_pc (addr); if (typeinfo_sym.minsym == NULL) error (_("could not find minimal symbol for typeinfo address %s"), paddress (gdbarch, addr)); @@ -1229,7 +1228,6 @@ gnuv3_skip_trampoline (const frame_info_ptr &frame, CORE_ADDR stop_pc) { CORE_ADDR real_stop_pc, method_stop_pc, func_addr; struct gdbarch *gdbarch = get_frame_arch (frame); - struct bound_minimal_symbol thunk_sym, fn_sym; struct obj_section *section; const char *thunk_name, *fn_name; @@ -1238,7 +1236,7 @@ gnuv3_skip_trampoline (const frame_info_ptr &frame, CORE_ADDR stop_pc) real_stop_pc = stop_pc; /* Find the linker symbol for this potential thunk. */ - thunk_sym = lookup_minimal_symbol_by_pc (real_stop_pc); + bound_minimal_symbol thunk_sym = lookup_minimal_symbol_by_pc (real_stop_pc); section = find_pc_section (real_stop_pc); if (thunk_sym.minsym == NULL || section == NULL) return 0; @@ -1251,7 +1249,8 @@ gnuv3_skip_trampoline (const frame_info_ptr &frame, CORE_ADDR stop_pc) return 0; fn_name = strstr (thunk_name, " thunk to ") + strlen (" thunk to "); - fn_sym = lookup_minimal_symbol (fn_name, NULL, section->objfile); + bound_minimal_symbol fn_sym + = lookup_minimal_symbol (current_program_space, fn_name, section->objfile); if (fn_sym.minsym == NULL) return 0; diff --git a/gdb/go-exp.y b/gdb/go-exp.y index 1a6ebbe..8fd6737 100644 --- a/gdb/go-exp.y +++ b/gdb/go-exp.y @@ -569,16 +569,15 @@ variable: name_not_typename } else { - struct bound_minimal_symbol msymbol; std::string arg = copy_name ($1.stoken); - msymbol = - lookup_bound_minimal_symbol (arg.c_str ()); + bound_minimal_symbol msymbol = + lookup_minimal_symbol (current_program_space, arg.c_str ()); if (msymbol.minsym != NULL) pstate->push_new<var_msym_value_operation> (msymbol); - else if (!have_full_symbols () - && !have_partial_symbols ()) + else if (!have_full_symbols (current_program_space) + && !have_partial_symbols (current_program_space)) error (_("No symbol table is loaded. " "Use the \"file\" command.")); else diff --git a/gdb/go-lang.c b/gdb/go-lang.c index 8b4250b..18d3fc1 100644 --- a/gdb/go-lang.c +++ b/gdb/go-lang.c @@ -54,9 +54,8 @@ static const char GO_MAIN_MAIN[] = "main.main"; const char * go_main_name (void) { - struct bound_minimal_symbol msym; - - msym = lookup_minimal_symbol (GO_MAIN_MAIN, NULL, NULL); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, GO_MAIN_MAIN); if (msym.minsym != NULL) return GO_MAIN_MAIN; diff --git a/gdb/guile/guile-internal.h b/gdb/guile/guile-internal.h index be16fee..dea7884 100644 --- a/gdb/guile/guile-internal.h +++ b/gdb/guile/guile-internal.h @@ -326,32 +326,32 @@ extern SCM gdbscm_make_type_error (const char *subr, int arg_pos, extern SCM gdbscm_make_invalid_object_error (const char *subr, int arg_pos, SCM bad_value, const char *error); -extern void gdbscm_invalid_object_error (const char *subr, int arg_pos, - SCM bad_value, const char *error) - ATTRIBUTE_NORETURN; +[[noreturn]] extern void gdbscm_invalid_object_error (const char *subr, + int arg_pos, + SCM bad_value, + const char *error); extern SCM gdbscm_make_out_of_range_error (const char *subr, int arg_pos, SCM bad_value, const char *error); -extern void gdbscm_out_of_range_error (const char *subr, int arg_pos, - SCM bad_value, const char *error) - ATTRIBUTE_NORETURN; +[[noreturn]] extern void gdbscm_out_of_range_error (const char *subr, + int arg_pos, SCM bad_value, + const char *error); extern SCM gdbscm_make_misc_error (const char *subr, int arg_pos, SCM bad_value, const char *error); -extern void gdbscm_misc_error (const char *subr, int arg_pos, - SCM bad_value, const char *error) - ATTRIBUTE_NORETURN; +[[noreturn]] extern void gdbscm_misc_error (const char *subr, int arg_pos, + SCM bad_value, const char *error); -extern void gdbscm_throw (SCM exception) ATTRIBUTE_NORETURN; +[[noreturn]] extern void gdbscm_throw (SCM exception); struct gdbscm_gdb_exception; extern SCM gdbscm_scm_from_gdb_exception (const gdbscm_gdb_exception &exception); -extern void gdbscm_throw_gdb_exception (gdbscm_gdb_exception exception) - ATTRIBUTE_NORETURN; +[[noreturn]] extern void gdbscm_throw_gdb_exception + (gdbscm_gdb_exception exception); extern void gdbscm_print_exception_with_stack (SCM port, SCM stack, SCM key, SCM args); @@ -368,8 +368,8 @@ extern excp_matcher_func gdbscm_user_error_p; extern SCM gdbscm_make_memory_error (const char *subr, const char *msg, SCM args); -extern void gdbscm_memory_error (const char *subr, const char *msg, SCM args) - ATTRIBUTE_NORETURN; +[[noreturn]] extern void gdbscm_memory_error (const char *subr, + const char *msg, SCM args); /* scm-safe-call.c */ diff --git a/gdb/guile/guile.c b/gdb/guile/guile.c index dbbb96e..432093b 100644 --- a/gdb/guile/guile.c +++ b/gdb/guile/guile.c @@ -124,6 +124,7 @@ static const struct extension_language_ops guile_extension_ops = gdbscm_apply_val_pretty_printer, NULL, /* gdbscm_apply_frame_filter, */ + NULL, /* gdbscm_load_ptwrite_filter, */ gdbscm_preserve_values, diff --git a/gdb/guile/scm-objfile.c b/gdb/guile/scm-objfile.c index bccf6ba..d6c0559 100644 --- a/gdb/guile/scm-objfile.c +++ b/gdb/guile/scm-objfile.c @@ -250,7 +250,7 @@ gdbscm_objfile_progspace (SCM self) objfile_smob *o_smob = ofscm_get_valid_objfile_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); - return psscm_scm_from_pspace (o_smob->objfile->pspace); + return psscm_scm_from_pspace (o_smob->objfile->pspace ()); } /* (objfile-pretty-printers <gdb:objfile>) -> list diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c index c15a9fc..ad93c2b 100644 --- a/gdb/hppa-tdep.c +++ b/gdb/hppa-tdep.c @@ -194,9 +194,8 @@ hppa_extract_17 (unsigned word) CORE_ADDR hppa_symbol_address(const char *sym) { - struct bound_minimal_symbol minsym; - - minsym = lookup_minimal_symbol (sym, NULL, NULL); + bound_minimal_symbol minsym + = lookup_minimal_symbol (current_program_space, sym); if (minsym.minsym) return minsym.value_address (); else diff --git a/gdb/i386-darwin-nat.c b/gdb/i386-darwin-nat.c index 5965599..55c6123 100644 --- a/gdb/i386-darwin-nat.c +++ b/gdb/i386-darwin-nat.c @@ -499,7 +499,7 @@ darwin_check_osabi (darwin_inferior *inf, thread_t thread) else info.bfd_arch_info = bfd_lookup_arch (bfd_arch_i386, bfd_mach_i386_i386); - gdbarch_update_p (info); + gdbarch_update_p (current_inferior (), info); } } diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c index bfe3fb8..0e360b1 100644 --- a/gdb/i386-linux-nat.c +++ b/gdb/i386-linux-nat.c @@ -315,19 +315,19 @@ fetch_xstateregs (struct regcache *regcache, int tid) { struct gdbarch *gdbarch = regcache->arch (); const i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch); - char xstateregs[tdep->xsave_layout.sizeof_xsave]; + gdb::byte_vector xstateregs (tdep->xsave_layout.sizeof_xsave); struct iovec iov; if (have_ptrace_getregset != TRIBOOL_TRUE) return 0; - iov.iov_base = xstateregs; - iov.iov_len = sizeof(xstateregs); + iov.iov_base = xstateregs.data (); + iov.iov_len = xstateregs.size (); if (ptrace (PTRACE_GETREGSET, tid, (unsigned int) NT_X86_XSTATE, &iov) < 0) perror_with_name (_("Couldn't read extended state status")); - i387_supply_xsave (regcache, -1, xstateregs); + i387_supply_xsave (regcache, -1, xstateregs.data ()); return 1; } @@ -340,19 +340,19 @@ store_xstateregs (const struct regcache *regcache, int tid, int regno) { struct gdbarch *gdbarch = regcache->arch (); const i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch); - char xstateregs[tdep->xsave_layout.sizeof_xsave]; + gdb::byte_vector xstateregs (tdep->xsave_layout.sizeof_xsave); struct iovec iov; if (have_ptrace_getregset != TRIBOOL_TRUE) return 0; - - iov.iov_base = xstateregs; - iov.iov_len = sizeof(xstateregs); + + iov.iov_base = xstateregs.data (); + iov.iov_len = xstateregs.size (); if (ptrace (PTRACE_GETREGSET, tid, (unsigned int) NT_X86_XSTATE, &iov) < 0) perror_with_name (_("Couldn't read extended state status")); - i387_collect_xsave (regcache, regno, xstateregs, 0); + i387_collect_xsave (regcache, regno, xstateregs.data (), 0); if (ptrace (PTRACE_SETREGSET, tid, (unsigned int) NT_X86_XSTATE, (int) &iov) < 0) diff --git a/gdb/i386-nto-tdep.c b/gdb/i386-nto-tdep.c deleted file mode 100644 index 6f34415..0000000 --- a/gdb/i386-nto-tdep.c +++ /dev/null @@ -1,379 +0,0 @@ -/* Target-dependent code for QNX Neutrino x86. - - Copyright (C) 2003-2024 Free Software Foundation, Inc. - - Contributed by QNX Software Systems Ltd. - - 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 "extract-store-integer.h" -#include "frame.h" -#include "osabi.h" -#include "regcache.h" -#include "target.h" - -#include "i386-tdep.h" -#include "i387-tdep.h" -#include "nto-tdep.h" -#include "solib.h" -#include "solib-svr4.h" - -#ifndef X86_CPU_FXSR -#define X86_CPU_FXSR (1L << 12) -#endif - -/* Why 13? Look in our /usr/include/x86/context.h header at the - x86_cpu_registers structure and you'll see an 'exx' junk register - that is just filler. Don't ask me, ask the kernel guys. */ -#define NUM_GPREGS 13 - -/* Mapping between the general-purpose registers in `struct xxx' - format and GDB's register cache layout. */ - -/* From <x86/context.h>. */ -static int i386nto_gregset_reg_offset[] = -{ - 7 * 4, /* %eax */ - 6 * 4, /* %ecx */ - 5 * 4, /* %edx */ - 4 * 4, /* %ebx */ - 11 * 4, /* %esp */ - 2 * 4, /* %epb */ - 1 * 4, /* %esi */ - 0 * 4, /* %edi */ - 8 * 4, /* %eip */ - 10 * 4, /* %eflags */ - 9 * 4, /* %cs */ - 12 * 4, /* %ss */ - -1 /* filler */ -}; - -/* Given a GDB register number REGNUM, return the offset into - Neutrino's register structure or -1 if the register is unknown. */ - -static int -nto_reg_offset (int regnum) -{ - if (regnum >= 0 && regnum < ARRAY_SIZE (i386nto_gregset_reg_offset)) - return i386nto_gregset_reg_offset[regnum]; - - return -1; -} - -static void -i386nto_supply_gregset (struct regcache *regcache, char *gpregs) -{ - struct gdbarch *gdbarch = regcache->arch (); - i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch); - - gdb_assert (tdep->gregset_reg_offset == i386nto_gregset_reg_offset); - i386_gregset.supply_regset (&i386_gregset, regcache, -1, - gpregs, NUM_GPREGS * 4); -} - -static void -i386nto_supply_fpregset (struct regcache *regcache, char *fpregs) -{ - if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR) - i387_supply_fxsave (regcache, -1, fpregs); - else - i387_supply_fsave (regcache, -1, fpregs); -} - -static void -i386nto_supply_regset (struct regcache *regcache, int regset, char *data) -{ - switch (regset) - { - case NTO_REG_GENERAL: - i386nto_supply_gregset (regcache, data); - break; - case NTO_REG_FLOAT: - i386nto_supply_fpregset (regcache, data); - break; - } -} - -static int -i386nto_regset_id (int regno) -{ - if (regno == -1) - return NTO_REG_END; - else if (regno < I386_NUM_GREGS) - return NTO_REG_GENERAL; - else if (regno < I386_NUM_GREGS + I387_NUM_REGS) - return NTO_REG_FLOAT; - else if (regno < I386_SSE_NUM_REGS) - return NTO_REG_FLOAT; /* We store xmm registers in fxsave_area. */ - - return -1; /* Error. */ -} - -static int -i386nto_register_area (struct gdbarch *gdbarch, - int regno, int regset, unsigned *off) -{ - i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch); - - *off = 0; - if (regset == NTO_REG_GENERAL) - { - if (regno == -1) - return NUM_GPREGS * 4; - - *off = nto_reg_offset (regno); - if (*off == -1) - return 0; - return 4; - } - else if (regset == NTO_REG_FLOAT) - { - unsigned off_adjust, regsize, regset_size, regno_base; - /* The following are flags indicating number in our fxsave_area. */ - int first_four = (regno >= I387_FCTRL_REGNUM (tdep) - && regno <= I387_FISEG_REGNUM (tdep)); - int second_four = (regno > I387_FISEG_REGNUM (tdep) - && regno <= I387_FOP_REGNUM (tdep)); - int st_reg = (regno >= I387_ST0_REGNUM (tdep) - && regno < I387_ST0_REGNUM (tdep) + 8); - int xmm_reg = (regno >= I387_XMM0_REGNUM (tdep) - && regno < I387_MXCSR_REGNUM (tdep)); - - if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR) - { - off_adjust = 32; - regsize = 16; - regset_size = 512; - /* fxsave_area structure. */ - if (first_four) - { - /* fpu_control_word, fpu_status_word, fpu_tag_word, fpu_operand - registers. */ - regsize = 2; /* Two bytes each. */ - off_adjust = 0; - regno_base = I387_FCTRL_REGNUM (tdep); - } - else if (second_four) - { - /* fpu_ip, fpu_cs, fpu_op, fpu_ds registers. */ - regsize = 4; - off_adjust = 8; - regno_base = I387_FISEG_REGNUM (tdep) + 1; - } - else if (st_reg) - { - /* ST registers. */ - regsize = 16; - off_adjust = 32; - regno_base = I387_ST0_REGNUM (tdep); - } - else if (xmm_reg) - { - /* XMM registers. */ - regsize = 16; - off_adjust = 160; - regno_base = I387_XMM0_REGNUM (tdep); - } - else if (regno == I387_MXCSR_REGNUM (tdep)) - { - regsize = 4; - off_adjust = 24; - regno_base = I387_MXCSR_REGNUM (tdep); - } - else - { - /* Whole regset. */ - gdb_assert (regno == -1); - off_adjust = 0; - regno_base = 0; - regsize = regset_size; - } - } - else - { - regset_size = 108; - /* fsave_area structure. */ - if (first_four || second_four) - { - /* fpu_control_word, ... , fpu_ds registers. */ - regsize = 4; - off_adjust = 0; - regno_base = I387_FCTRL_REGNUM (tdep); - } - else if (st_reg) - { - /* One of ST registers. */ - regsize = 10; - off_adjust = 7 * 4; - regno_base = I387_ST0_REGNUM (tdep); - } - else - { - /* Whole regset. */ - gdb_assert (regno == -1); - off_adjust = 0; - regno_base = 0; - regsize = regset_size; - } - } - - if (regno != -1) - *off = off_adjust + (regno - regno_base) * regsize; - else - *off = 0; - return regsize; - } - return -1; -} - -static int -i386nto_regset_fill (const struct regcache *regcache, int regset, char *data) -{ - if (regset == NTO_REG_GENERAL) - { - int regno; - - for (regno = 0; regno < NUM_GPREGS; regno++) - { - int offset = nto_reg_offset (regno); - if (offset != -1) - regcache->raw_collect (regno, data + offset); - } - } - else if (regset == NTO_REG_FLOAT) - { - if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR) - i387_collect_fxsave (regcache, -1, data); - else - i387_collect_fsave (regcache, -1, data); - } - else - return -1; - - return 0; -} - -/* Return whether THIS_FRAME corresponds to a QNX Neutrino sigtramp - routine. */ - -static int -i386nto_sigtramp_p (const frame_info_ptr &this_frame) -{ - CORE_ADDR pc = get_frame_pc (this_frame); - const char *name; - - find_pc_partial_function (pc, &name, NULL, NULL); - return name && strcmp ("__signalstub", name) == 0; -} - -/* Assuming THIS_FRAME is a QNX Neutrino sigtramp routine, return the - address of the associated sigcontext structure. */ - -static CORE_ADDR -i386nto_sigcontext_addr (const frame_info_ptr &this_frame) -{ - struct gdbarch *gdbarch = get_frame_arch (this_frame); - enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - gdb_byte buf[4]; - CORE_ADDR ptrctx; - - /* We store __ucontext_t addr in EDI register. */ - get_frame_register (this_frame, I386_EDI_REGNUM, buf); - ptrctx = extract_unsigned_integer (buf, 4, byte_order); - ptrctx += 24 /* Context pointer is at this offset. */; - - return ptrctx; -} - -static void -init_i386nto_ops (void) -{ - nto_regset_id = i386nto_regset_id; - nto_supply_gregset = i386nto_supply_gregset; - nto_supply_fpregset = i386nto_supply_fpregset; - nto_supply_altregset = nto_dummy_supply_regset; - nto_supply_regset = i386nto_supply_regset; - nto_register_area = i386nto_register_area; - nto_regset_fill = i386nto_regset_fill; - nto_fetch_link_map_offsets = - svr4_ilp32_fetch_link_map_offsets; -} - -static void -i386nto_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) -{ - i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch); - static solib_ops nto_svr4_so_ops; - - /* Deal with our strange signals. */ - nto_initialize_signals (); - - /* NTO uses ELF. */ - i386_elf_init_abi (info, gdbarch); - - /* Neutrino rewinds to look more normal. Need to override the i386 - default which is [unfortunately] to decrement the PC. */ - set_gdbarch_decr_pc_after_break (gdbarch, 0); - - tdep->gregset_reg_offset = i386nto_gregset_reg_offset; - tdep->gregset_num_regs = ARRAY_SIZE (i386nto_gregset_reg_offset); - tdep->sizeof_gregset = NUM_GPREGS * 4; - - tdep->sigtramp_p = i386nto_sigtramp_p; - tdep->sigcontext_addr = i386nto_sigcontext_addr; - tdep->sc_reg_offset = i386nto_gregset_reg_offset; - tdep->sc_num_regs = ARRAY_SIZE (i386nto_gregset_reg_offset); - - /* Setjmp()'s return PC saved in EDX (5). */ - tdep->jb_pc_offset = 20; /* 5x32 bit ints in. */ - - set_solib_svr4_fetch_link_map_offsets - (gdbarch, svr4_ilp32_fetch_link_map_offsets); - - /* Initialize this lazily, to avoid an initialization order - dependency on solib-svr4.c's _initialize routine. */ - if (nto_svr4_so_ops.in_dynsym_resolve_code == NULL) - { - nto_svr4_so_ops = svr4_so_ops; - - /* Our loader handles solib relocations differently than svr4. */ - nto_svr4_so_ops.relocate_section_addresses - = nto_relocate_section_addresses; - - /* Supply a nice function to find our solibs. */ - nto_svr4_so_ops.find_and_open_solib - = nto_find_and_open_solib; - - /* Our linker code is in libc. */ - nto_svr4_so_ops.in_dynsym_resolve_code - = nto_in_dynsym_resolve_code; - } - set_gdbarch_so_ops (gdbarch, &nto_svr4_so_ops); - - set_gdbarch_wchar_bit (gdbarch, 32); - set_gdbarch_wchar_signed (gdbarch, 0); -} - -void _initialize_i386nto_tdep (); -void -_initialize_i386nto_tdep () -{ - init_i386nto_ops (); - gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_QNXNTO, - i386nto_init_abi); - gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour, - nto_elf_osabi_sniffer); -} diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index f1f909e..625ffe5 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -1946,12 +1946,11 @@ i386_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) { /* Make sure address is computed correctly as a 32bit integer even if CORE_ADDR is 64 bit wide. */ - struct bound_minimal_symbol s; CORE_ADDR call_dest; call_dest = pc + 5 + extract_signed_integer (buf, 4, byte_order); call_dest = call_dest & 0xffffffffU; - s = lookup_minimal_symbol_by_pc (call_dest); + bound_minimal_symbol s = lookup_minimal_symbol_by_pc (call_dest); if (s.minsym != NULL && s.minsym->linkage_name () != NULL && strcmp (s.minsym->linkage_name (), "__main") == 0) diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c index 6376cf8..2739304 100644 --- a/gdb/ia64-tdep.c +++ b/gdb/ia64-tdep.c @@ -3615,9 +3615,7 @@ ia64_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr, /* There are also descriptors embedded in vtables. */ if (s) { - struct bound_minimal_symbol minsym; - - minsym = lookup_minimal_symbol_by_pc (addr); + bound_minimal_symbol minsym = lookup_minimal_symbol_by_pc (addr); if (minsym.minsym && is_vtable_name (minsym.minsym->linkage_name ())) diff --git a/gdb/inf-child.c b/gdb/inf-child.c index 1318d6b..df993b6 100644 --- a/gdb/inf-child.c +++ b/gdb/inf-child.c @@ -320,6 +320,21 @@ inf_child_target::fileio_fstat (int fd, struct stat *sb, fileio_error *target_er return ret; } +/* Implementation of to_fileio_stat. */ + +int +inf_child_target::fileio_stat (struct inferior *inf, const char *filename, + struct stat *sb, fileio_error *target_errno) +{ + int ret; + + ret = lstat (filename, sb); + if (ret == -1) + *target_errno = host_to_fileio_error (errno); + + return ret; +} + /* Implementation of to_fileio_close. */ int diff --git a/gdb/inf-child.h b/gdb/inf-child.h index 91955a6..65d42e1 100644 --- a/gdb/inf-child.h +++ b/gdb/inf-child.h @@ -81,6 +81,8 @@ public: int fileio_pread (int fd, gdb_byte *read_buf, int len, ULONGEST offset, fileio_error *target_errno) override; int fileio_fstat (int fd, struct stat *sb, fileio_error *target_errno) override; + int fileio_stat (struct inferior *inf, const char *filename, + struct stat *sb, fileio_error *target_errno) override; int fileio_close (int fd, fileio_error *target_errno) override; int fileio_unlink (struct inferior *inf, const char *filename, diff --git a/gdb/infcall.c b/gdb/infcall.c index edac9a7..02e3b38 100644 --- a/gdb/infcall.c +++ b/gdb/infcall.c @@ -488,7 +488,7 @@ get_function_name (CORE_ADDR funaddr, char *buf, int buf_size) { /* Try the minimal symbols. */ - struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (funaddr); + bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (funaddr); if (msymbol.minsym) return msymbol.minsym->print_name (); @@ -1271,7 +1271,7 @@ call_function_by_hand_dummy (struct value *function, CORE_ADDR dummy_addr; real_pc = funaddr; - dummy_addr = entry_point_address (); + dummy_addr = entry_point_address (current_program_space); /* A call dummy always consists of just a single breakpoint, so its address is the same as the address of the dummy. diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 71514d5..347684a 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -383,7 +383,7 @@ run_command_1 (const char *args, int from_tty, enum run_how run_how) /* Clean up any leftovers from other runs. Some other things from this function should probably be moved into target_pre_inferior. */ - target_pre_inferior (from_tty); + target_pre_inferior (); /* The comment here used to read, "The exec file is re-read every time we do a generic_mourn_inferior, so we just have to worry @@ -519,7 +519,7 @@ start_command (const char *args, int from_tty) /* Some languages such as Ada need to search inside the program minimal symbols for the location where to put the temporary breakpoint before starting. */ - if (!have_minimal_symbols ()) + if (!have_minimal_symbols (current_program_space)) error (_("No symbol table loaded. Use the \"file\" command.")); /* Run the program until reaching the main procedure... */ @@ -1078,7 +1078,8 @@ jump_command (const char *arg, int from_tty) { /* If multiple sal-objects were found, try dropping those that aren't from the current symtab. */ - struct symtab_and_line cursal = get_current_source_symtab_and_line (); + symtab_and_line cursal + = get_current_source_symtab_and_line (current_program_space); sals.erase (std::remove_if (sals.begin (), sals.end (), [&] (const symtab_and_line &sal) { @@ -1359,7 +1360,7 @@ until_next_command (int from_tty) if (!func) { - struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc); + bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc); if (msymbol.minsym == nullptr) error (_("Execution is not within a known function.")); @@ -2628,7 +2629,7 @@ attach_command (const char *args, int from_tty) /* Clean up any leftovers from other runs. Some other things from this function should probably be moved into target_pre_inferior. */ - target_pre_inferior (from_tty); + target_pre_inferior (); gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (args, &async_exec); args = stripped.get (); @@ -2827,7 +2828,7 @@ detach_command (const char *args, int from_tty) /* If the solist is global across inferiors, don't clear it when we detach from a single inferior. */ if (!gdbarch_has_global_solist (inf->arch ())) - no_shared_libraries (nullptr, from_tty); + no_shared_libraries (inf->pspace); if (deprecated_detach_hook) deprecated_detach_hook (); @@ -2853,7 +2854,7 @@ disconnect_command (const char *args, int from_tty) query_if_trace_running (from_tty); disconnect_tracing (); target_disconnect (args, from_tty); - no_shared_libraries (nullptr, from_tty); + no_shared_libraries (current_program_space); init_thread_list (); update_previous_thread (); if (deprecated_detach_hook) diff --git a/gdb/inferior.c b/gdb/inferior.c index 6a19767..bc9e5ee 100644 --- a/gdb/inferior.c +++ b/gdb/inferior.c @@ -790,6 +790,10 @@ inferior_command (const char *args, int from_tty) notify_user_selected_context_changed (USER_SELECTED_INFERIOR); } + + /* Switching current inferior may have made one of the inferiors + prunable, so prune it. */ + prune_inferiors (); } } diff --git a/gdb/infrun.c b/gdb/infrun.c index 1f32a63..f2d28ca 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -1317,7 +1317,7 @@ follow_exec (ptid_t ptid, const char *exec_file_target) /* Also, loading a symbol file below may trigger symbol lookups, and we don't want those to be satisfied by the libraries of the previous incarnation of this process. */ - no_shared_libraries (nullptr, 0); + no_shared_libraries (current_program_space); inferior *execing_inferior = current_inferior (); inferior *following_inferior; @@ -8245,7 +8245,8 @@ process_event_stop_test (struct execution_control_state *ecs) "it's not the start of a statement"); } } - else if (execution_direction == EXEC_REVERSE + + if (execution_direction == EXEC_REVERSE && *curr_frame_id != original_frame_id && original_frame_id.code_addr_p && curr_frame_id->code_addr_p && original_frame_id.code_addr == curr_frame_id->code_addr) @@ -9296,12 +9297,24 @@ print_stop_location (const target_waitstatus &ws) && (tp->control.step_start_function == find_pc_function (tp->stop_pc ()))) { - /* Finished step, just print source line. */ - source_flag = SRC_LINE; + symtab_and_line sal = find_frame_sal (get_selected_frame (nullptr)); + if (sal.symtab != tp->current_symtab) + { + /* Finished step in same frame but into different file, print + location and source line. */ + source_flag = SRC_AND_LOC; + } + else + { + /* Finished step in same frame and same file, just print source + line. */ + source_flag = SRC_LINE; + } } else { - /* Print location and source line. */ + /* Finished step into different frame, print location and source + line. */ source_flag = SRC_AND_LOC; } break; diff --git a/gdb/inline-frame.c b/gdb/inline-frame.c index f65f39b..bed99dc 100644 --- a/gdb/inline-frame.c +++ b/gdb/inline-frame.c @@ -35,9 +35,9 @@ keep our own list. */ struct inline_state { - inline_state (thread_info *thread_, int skipped_frames_, CORE_ADDR saved_pc_, + inline_state (thread_info *thread_, CORE_ADDR saved_pc_, std::vector<symbol *> &&skipped_symbols_) - : thread (thread_), skipped_frames (skipped_frames_), saved_pc (saved_pc_), + : thread (thread_), saved_pc (saved_pc_), skipped_symbols (std::move (skipped_symbols_)) {} @@ -45,19 +45,14 @@ struct inline_state stopped thread. */ thread_info *thread; - /* The number of inlined functions we are skipping. Each of these - functions can be stepped in to. */ - int skipped_frames; - - /* Only valid if SKIPPED_FRAMES is non-zero. This is the PC used - when calculating SKIPPED_FRAMES; used to check whether we have + /* Only valid if SKIPPED_SYMBOLS is not empty. This is the PC used + when calculating SKIPPED_SYMBOLS; used to check whether we have moved to a new location by user request. If so, we invalidate any skipped frames. */ CORE_ADDR saved_pc; - /* Only valid if SKIPPED_FRAMES is non-zero. This is the list of all - function symbols that have been skipped, from inner most to outer - most. It is used to find the call site of the current frame. */ + /* The list of all function symbols that have been skipped, from inner most + to outer most. It is used to find the call site of the current frame. */ std::vector<struct symbol *> skipped_symbols; }; @@ -247,10 +242,12 @@ inline_frame_sniffer (const struct frame_unwind *self, /* If this is the topmost frame, or all frames above us are inlined, then check whether we were requested to skip some frames (so they can be stepped into later). */ - if (state != NULL && state->skipped_frames > 0 && next_frame == NULL) + if (state != nullptr + && !state->skipped_symbols.empty () + && next_frame == nullptr) { - gdb_assert (depth >= state->skipped_frames); - depth -= state->skipped_frames; + gdb_assert (depth >= state->skipped_symbols.size ()); + depth -= state->skipped_symbols.size (); } /* If all the inlined functions here already have frames, then pass @@ -343,7 +340,6 @@ skip_inline_frames (thread_info *thread, bpstat *stop_chain) { const struct block *frame_block, *cur_block; std::vector<struct symbol *> skipped_syms; - int skip_count = 0; /* This function is called right after reinitializing the frame cache. We try not to do more unwinding than absolutely @@ -369,7 +365,6 @@ skip_inline_frames (thread_info *thread, bpstat *stop_chain) if (stopped_by_user_bp_inline_frame (cur_block, stop_chain)) break; - skip_count++; skipped_syms.push_back (cur_block->function ()); } else @@ -383,11 +378,11 @@ skip_inline_frames (thread_info *thread, bpstat *stop_chain) } gdb_assert (find_inline_frame_state (thread) == NULL); - inline_states.emplace_back (thread, skip_count, this_pc, - std::move (skipped_syms)); - if (skip_count != 0) + if (!skipped_syms.empty ()) reinit_frame_cache (); + + inline_states.emplace_back (thread, this_pc, std::move (skipped_syms)); } /* Step into an inlined function by unhiding it. */ @@ -397,8 +392,10 @@ step_into_inline_frame (thread_info *thread) { inline_state *state = find_inline_frame_state (thread); - gdb_assert (state != NULL && state->skipped_frames > 0); - state->skipped_frames--; + gdb_assert (state != nullptr); + gdb_assert (!state->skipped_symbols.empty ()); + + state->skipped_symbols.pop_back (); reinit_frame_cache (); } @@ -413,7 +410,7 @@ inline_skipped_frames (thread_info *thread) if (state == NULL) return 0; else - return state->skipped_frames; + return state->skipped_symbols.size (); } /* If one or more inlined functions are hidden, return the symbol for @@ -426,13 +423,9 @@ inline_skipped_symbol (thread_info *thread) gdb_assert (state != NULL); /* This should only be called when we are skipping at least one frame, - hence SKIPPED_FRAMES will be greater than zero when we get here. - We initialise SKIPPED_FRAMES at the same time as we build - SKIPPED_SYMBOLS, hence it should be true that SKIPPED_FRAMES never - indexes outside of the SKIPPED_SYMBOLS vector. */ - gdb_assert (state->skipped_frames > 0); - gdb_assert (state->skipped_frames <= state->skipped_symbols.size ()); - return state->skipped_symbols[state->skipped_frames - 1]; + hence SKIPPED_SYMBOLS will have at least one item when we get here. */ + gdb_assert (!state->skipped_symbols.empty ()); + return state->skipped_symbols.back (); } /* Return the number of functions inlined into THIS_FRAME. Some of @@ -660,8 +660,8 @@ jit_object_close_impl (struct gdb_symbol_callbacks *cb, paddress (priv_data->gdbarch, priv_data->entry.symfile_addr)); - objfile *objfile = objfile::make (nullptr, objfile_name.c_str (), - OBJF_NOT_FILENAME); + objfile *objfile = objfile::make (nullptr, current_program_space, + objfile_name.c_str (), OBJF_NOT_FILENAME); objfile->per_bfd->gdbarch = priv_data->gdbarch; for (gdb_symtab &symtab : obj->symtabs) @@ -880,7 +880,7 @@ jit_breakpoint_re_set_internal (struct gdbarch *gdbarch, program_space *pspace) /* Lookup the registration symbol. If it is missing, then we assume we are not attached to a JIT. */ bound_minimal_symbol reg_symbol - = lookup_minimal_symbol_text (jit_break_name, the_objfile); + = lookup_minimal_symbol_text (pspace, jit_break_name, the_objfile); if (reg_symbol.minsym == NULL || reg_symbol.value_address () == 0) { diff --git a/gdb/language.c b/gdb/language.c index be6a1e8..d697331 100644 --- a/gdb/language.c +++ b/gdb/language.c @@ -110,6 +110,13 @@ scoped_restore_current_language::scoped_restore_current_language () { } +scoped_restore_current_language::scoped_restore_current_language + (enum language lang) + : scoped_restore_current_language () +{ + set_language (lang); +} + scoped_restore_current_language::~scoped_restore_current_language () { /* If both are NULL, then that means dont_restore was called. */ diff --git a/gdb/language.h b/gdb/language.h index a2ce169..985e622 100644 --- a/gdb/language.h +++ b/gdb/language.h @@ -860,6 +860,10 @@ class scoped_restore_current_language public: scoped_restore_current_language (); + + /* Set the current language as well. */ + explicit scoped_restore_current_language (enum language lang); + ~scoped_restore_current_language (); scoped_restore_current_language (scoped_restore_current_language &&other) diff --git a/gdb/linespec.c b/gdb/linespec.c index 7a1fbc2..ee418e3 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -1156,7 +1156,7 @@ iterate_over_all_matching_symtabs set_current_program_space (pspace); - for (objfile *objfile : current_program_space->objfiles ()) + for (objfile *objfile : pspace->objfiles ()) { objfile->expand_symtabs_matching (NULL, &lookup_name, NULL, NULL, (SEARCH_GLOBAL_BLOCK @@ -1544,15 +1544,15 @@ decode_line_2 (struct linespec_state *self, /* Throw an appropriate error when SYMBOL is not found (optionally in FILENAME). */ -static void ATTRIBUTE_NORETURN +[[noreturn]] static void symbol_not_found_error (const char *symbol, const char *filename) { if (symbol == NULL) symbol = ""; - if (!have_full_symbols () - && !have_partial_symbols () - && !have_minimal_symbols ()) + if (!have_full_symbols (current_program_space) + && !have_partial_symbols (current_program_space) + && !have_minimal_symbols (current_program_space)) throw_error (NOT_FOUND_ERROR, _("No symbol table is loaded. Use the \"file\" command.")); @@ -1586,7 +1586,7 @@ symbol_not_found_error (const char *symbol, const char *filename) /* Throw an appropriate error when an unexpected token is encountered in the input. */ -static void ATTRIBUTE_NORETURN +[[noreturn]] static void unexpected_linespec_error (linespec_parser *parser) { linespec_token token; @@ -1613,7 +1613,7 @@ unexpected_linespec_error (linespec_parser *parser) /* Throw an undefined label error. */ -static void ATTRIBUTE_NORETURN +[[noreturn]] static void undefined_label_error (const char *function, const char *label) { if (function != NULL) @@ -1628,7 +1628,7 @@ undefined_label_error (const char *function, const char *label) /* Throw a source file not found error. */ -static void ATTRIBUTE_NORETURN +[[noreturn]] static void source_file_not_found_error (const char *name) { throw_error (NOT_FOUND_ERROR, _("No source file named %s."), name); @@ -2172,7 +2172,7 @@ convert_linespec_to_sals (struct linespec_state *state, linespec *ls) for (const auto &sym : ls->labels.label_symbols) { struct program_space *pspace - = sym.symbol->symtab ()->compunit ()->objfile ()->pspace; + = sym.symbol->symtab ()->compunit ()->objfile ()->pspace (); if (symbol_to_sal (&sal, state->funfirstline, sym.symbol) && maybe_add_address (state->addr_set, pspace, sal.pc)) @@ -2194,7 +2194,7 @@ convert_linespec_to_sals (struct linespec_state *state, linespec *ls) for (const auto &sym : ls->function_symbols) { program_space *pspace - = sym.symbol->symtab ()->compunit ()->objfile ()->pspace; + = sym.symbol->symtab ()->compunit ()->objfile ()->pspace (); set_current_program_space (pspace); /* Don't skip to the first line of the function if we @@ -2256,7 +2256,7 @@ convert_linespec_to_sals (struct linespec_state *state, linespec *ls) for (const auto &elem : ls->minimal_symbols) { - program_space *pspace = elem.objfile->pspace; + program_space *pspace = elem.objfile->pspace (); set_current_program_space (pspace); minsym_found (state, elem.objfile, elem.minsym, &sals); } @@ -3205,7 +3205,8 @@ decode_line_with_current_source (const char *string, int flags) /* We use whatever is set as the current source line. We do not try and get a default source symtab+line or it will recursively call us! */ - symtab_and_line cursal = get_current_source_symtab_and_line (); + symtab_and_line cursal + = get_current_source_symtab_and_line (current_program_space); location_spec_up locspec = string_to_location_spec (&string, current_language); @@ -3255,9 +3256,9 @@ initialize_defaults (struct symtab **default_symtab, int *default_line) /* Use whatever we have for the default source line. We don't use get_current_or_default_symtab_and_line as it can recurse and call us back! */ - struct symtab_and_line cursal = - get_current_source_symtab_and_line (); - + symtab_and_line cursal + = get_current_source_symtab_and_line (current_program_space); + *default_symtab = cursal.symtab; *default_line = cursal.line; } @@ -3437,7 +3438,7 @@ lookup_prefix_sym (struct linespec_state *state, { /* Program spaces that are executing startup should have been filtered out earlier. */ - program_space *pspace = elt->compunit ()->objfile ()->pspace; + program_space *pspace = elt->compunit ()->objfile ()->pspace (); gdb_assert (!pspace->executing_startup); set_current_program_space (pspace); @@ -3459,8 +3460,8 @@ compare_symbols (const block_symbol &a, const block_symbol &b) { uintptr_t uia, uib; - uia = (uintptr_t) a.symbol->symtab ()->compunit ()->objfile ()->pspace; - uib = (uintptr_t) b.symbol->symtab ()->compunit ()->objfile ()->pspace; + uia = (uintptr_t) a.symbol->symtab ()->compunit ()->objfile ()->pspace (); + uib = (uintptr_t) b.symbol->symtab ()->compunit ()->objfile ()->pspace (); if (uia < uib) return true; @@ -3483,8 +3484,8 @@ compare_msymbols (const bound_minimal_symbol &a, const bound_minimal_symbol &b) { uintptr_t uia, uib; - uia = (uintptr_t) a.objfile->pspace; - uib = (uintptr_t) a.objfile->pspace; + uia = (uintptr_t) a.objfile->pspace (); + uib = (uintptr_t) a.objfile->pspace (); if (uia < uib) return true; @@ -3584,7 +3585,7 @@ find_method (struct linespec_state *self, /* Program spaces that are executing startup should have been filtered out earlier. */ - pspace = sym->symtab ()->compunit ()->objfile ()->pspace; + pspace = sym->symtab ()->compunit ()->objfile ()->pspace (); gdb_assert (!pspace->executing_startup); set_current_program_space (pspace); t = check_typedef (sym->type ()); @@ -3596,7 +3597,7 @@ find_method (struct linespec_state *self, if (ix == sym_classes->size () - 1 || (pspace != (sym_classes->at (ix + 1).symbol->symtab () - ->compunit ()->objfile ()->pspace))) + ->compunit ()->objfile ()->pspace ()))) { /* If we did not find a direct implementation anywhere in this program space, consider superclasses. */ @@ -3716,7 +3717,8 @@ symtabs_from_filename (const char *filename, if (result.empty ()) { - if (!have_full_symbols () && !have_partial_symbols ()) + if (!have_full_symbols (current_program_space) + && !have_partial_symbols (current_program_space)) throw_error (NOT_FOUND_ERROR, _("No symbol table is loaded. " "Use the \"file\" command.")); @@ -3963,7 +3965,7 @@ find_label_symbols (struct linespec_state *self, { fn_sym = elt.symbol; set_current_program_space - (fn_sym->symtab ()->compunit ()->objfile ()->pspace); + (fn_sym->symtab ()->compunit ()->objfile ()->pspace ()); block = fn_sym->value_block (); find_label_symbols_in_block (block, name, fn_sym, completion_mode, @@ -3992,7 +3994,7 @@ decode_digits_list_mode (struct linespec_state *self, /* The logic above should ensure this. */ gdb_assert (elt != NULL); - program_space *pspace = elt->compunit ()->objfile ()->pspace; + program_space *pspace = elt->compunit ()->objfile ()->pspace (); set_current_program_space (pspace); /* Simplistic search just for the list command. */ @@ -4027,7 +4029,7 @@ decode_digits_ordinary (struct linespec_state *self, /* The logic above should ensure this. */ gdb_assert (elt != NULL); - program_space *pspace = elt->compunit ()->objfile ()->pspace; + program_space *pspace = elt->compunit ()->objfile ()->pspace (); set_current_program_space (pspace); pcs = find_pcs_for_symtab_line (elt, line, best_entry); @@ -4153,7 +4155,7 @@ minsym_found (struct linespec_state *self, struct objfile *objfile, sal.section = msymbol->obj_section (objfile); - if (maybe_add_address (self->addr_set, objfile->pspace, sal.pc)) + if (maybe_add_address (self->addr_set, objfile->pspace (), sal.pc)) add_sal_to_sals (self, result, &sal, msymbol->natural_name (), 0); } @@ -4163,7 +4165,7 @@ minsym_found (struct linespec_state *self, struct objfile *objfile, static void add_minsym (struct minimal_symbol *minsym, struct objfile *objfile, struct symtab *symtab, int list_mode, - std::vector<struct bound_minimal_symbol> *msyms) + std::vector<bound_minimal_symbol> *msyms) { if (symtab != NULL) { @@ -4200,7 +4202,7 @@ search_minsyms_for_name (struct collect_info *info, struct program_space *search_pspace, struct symtab *symtab) { - std::vector<struct bound_minimal_symbol> minsyms; + std::vector<bound_minimal_symbol> minsyms; if (symtab == NULL) { @@ -4213,7 +4215,7 @@ search_minsyms_for_name (struct collect_info *info, set_current_program_space (pspace); - for (objfile *objfile : current_program_space->objfiles ()) + for (objfile *objfile : pspace->objfiles ()) { iterate_over_minimal_symbols (objfile, name, [&] (struct minimal_symbol *msym) @@ -4228,7 +4230,7 @@ search_minsyms_for_name (struct collect_info *info, } else { - program_space *pspace = symtab->compunit ()->objfile ()->pspace; + program_space *pspace = symtab->compunit ()->objfile ()->pspace (); if (search_pspace == NULL || pspace == search_pspace) { @@ -4322,13 +4324,13 @@ add_matching_symbols_to_info (const char *name, { return info->add_symbol (bsym); }); search_minsyms_for_name (info, lookup_name, pspace, NULL); } - else if (pspace == NULL || pspace == elt->compunit ()->objfile ()->pspace) + else if (pspace == NULL || pspace == elt->compunit ()->objfile ()->pspace ()) { int prev_len = info->result.symbols->size (); /* Program spaces that are executing startup should have been filtered out earlier. */ - program_space *elt_pspace = elt->compunit ()->objfile ()->pspace; + program_space *elt_pspace = elt->compunit ()->objfile ()->pspace (); gdb_assert (!elt_pspace->executing_startup); set_current_program_space (elt_pspace); iterate_over_file_blocks (elt, lookup_name, SEARCH_VFT, @@ -4369,7 +4371,7 @@ symbol_to_sal (struct symtab_and_line *result, result->symbol = sym; result->line = sym->line (); result->pc = sym->value_address (); - result->pspace = result->symtab->compunit ()->objfile ()->pspace; + result->pspace = result->symtab->compunit ()->objfile ()->pspace (); result->explicit_pc = 1; return 1; } @@ -4385,7 +4387,7 @@ symbol_to_sal (struct symtab_and_line *result, result->symbol = sym; result->line = sym->line (); result->pc = sym->value_address (); - result->pspace = result->symtab->compunit ()->objfile ()->pspace; + result->pspace = result->symtab->compunit ()->objfile ()->pspace (); return 1; } } diff --git a/gdb/linux-fork.c b/gdb/linux-fork.c index 319a13f..c457a90 100644 --- a/gdb/linux-fork.c +++ b/gdb/linux-fork.c @@ -484,10 +484,12 @@ inferior_call_waitpid (ptid_t pptid, int pid) scoped_switch_fork_info switch_fork_info (pptid); /* Get the waitpid_fn. */ - if (lookup_minimal_symbol ("waitpid", NULL, NULL).minsym != NULL) + if (lookup_minimal_symbol (current_program_space, "waitpid").minsym + != nullptr) waitpid_fn = find_function_in_inferior ("waitpid", &waitpid_objf); if (!waitpid_fn - && lookup_minimal_symbol ("_waitpid", NULL, NULL).minsym != NULL) + && (lookup_minimal_symbol (current_program_space, "_waitpid").minsym + != nullptr)) waitpid_fn = find_function_in_inferior ("_waitpid", &waitpid_objf); if (waitpid_fn != nullptr) { @@ -638,9 +640,7 @@ info_checkpoints_command (const char *arg, int from_tty) gdb_printf (_(", line %d"), sal.line); if (!sal.symtab && !sal.line) { - struct bound_minimal_symbol msym; - - msym = lookup_minimal_symbol_by_pc (pc); + bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (pc); if (msym.minsym) gdb_printf (", <%s>", msym.minsym->linkage_name ()); } @@ -703,10 +703,11 @@ checkpoint_command (const char *args, int from_tty) /* Make the inferior fork, record its (and gdb's) state. */ - if (lookup_minimal_symbol ("fork", NULL, NULL).minsym != NULL) + if (lookup_minimal_symbol (current_program_space, "fork").minsym != nullptr) fork_fn = find_function_in_inferior ("fork", &fork_objf); if (!fork_fn) - if (lookup_minimal_symbol ("_fork", NULL, NULL).minsym != NULL) + if (lookup_minimal_symbol (current_program_space, "_fork").minsym + != nullptr) fork_fn = find_function_in_inferior ("fork", &fork_objf); if (!fork_fn) error (_("checkpoint: can't find fork function in inferior.")); diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c index 018bd68..9d84187 100644 --- a/gdb/linux-thread-db.c +++ b/gdb/linux-thread-db.c @@ -467,11 +467,11 @@ verbose_dlsym (void *handle, const char *name) static int inferior_has_bug (const char *ver_symbol, int ver_major_min, int ver_minor_min) { - struct bound_minimal_symbol version_msym; CORE_ADDR version_addr; int got, retval = 0; - version_msym = lookup_minimal_symbol (ver_symbol, NULL, NULL); + bound_minimal_symbol version_msym + = lookup_minimal_symbol (current_program_space, ver_symbol); if (version_msym.minsym == NULL) return 0; @@ -810,9 +810,8 @@ static bool libpthread_objfile_p (objfile *obj) { return (libpthread_name_p (objfile_name (obj)) - && lookup_minimal_symbol ("pthread_create", - NULL, - obj).minsym != NULL); + && lookup_minimal_symbol (current_program_space, + "pthread_create", obj).minsym != nullptr); } /* Attempt to initialize dlopen()ed libthread_db, described by INFO. diff --git a/gdb/loongarch-linux-nat.c b/gdb/loongarch-linux-nat.c index 8736287..bc9927d 100644 --- a/gdb/loongarch-linux-nat.c +++ b/gdb/loongarch-linux-nat.c @@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "cli/cli-cmds.h" #include "elf/common.h" #include "gregset.h" #include "inferior.h" @@ -765,4 +766,19 @@ _initialize_loongarch_linux_nat () { linux_target = &the_loongarch_linux_nat_target; add_inf_child_target (&the_loongarch_linux_nat_target); + + /* Add a maintenance command to enable printing the LoongArch internal + debug registers mirror variables. */ + add_setshow_boolean_cmd ("show-debug-regs", class_maintenance, + &show_debug_regs, _("\ +Set whether to show the LoongArch debug registers state."), _("\ +Show whether to show the LoongArch debug registers state."), _("\ +Use \"on\" to enable, \"off\" to disable.\n\ +If enabled, the debug registers values are shown when GDB inserts\n\ +or removes a hardware breakpoint or watchpoint, and when the inferior\n\ +triggers a breakpoint or watchpoint."), + NULL, + NULL, + &maintenance_set_cmdlist, + &maintenance_show_cmdlist); } diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c index 757f4ac..c50dd7f 100644 --- a/gdb/loongarch-tdep.c +++ b/gdb/loongarch-tdep.c @@ -36,14 +36,14 @@ static insn_t loongarch_fetch_instruction (CORE_ADDR pc) { size_t insn_len = loongarch_insn_length (0); - gdb_byte buf[insn_len]; + gdb::byte_vector buf (insn_len); int err; - err = target_read_memory (pc, buf, insn_len); + err = target_read_memory (pc, buf.data (), insn_len); if (err) memory_error (TARGET_XFER_E_IO, pc); - return extract_unsigned_integer (buf, insn_len, BFD_ENDIAN_LITTLE); + return extract_unsigned_integer (buf.data (), insn_len, BFD_ENDIAN_LITTLE); } /* Return TRUE if INSN is a unconditional branch instruction, otherwise return FALSE. */ @@ -1306,18 +1306,24 @@ loongarch_return_value (struct gdbarch *gdbarch, struct value *function, and the signed integer scalars are sign-extended. */ if (writebuf) { - gdb_byte buf[regsize]; + gdb::byte_vector buf (regsize); if (type->is_unsigned ()) { - ULONGEST data = extract_unsigned_integer (writebuf, len, BFD_ENDIAN_LITTLE); - store_unsigned_integer (buf, regsize, BFD_ENDIAN_LITTLE, data); + ULONGEST data = extract_unsigned_integer (writebuf, len, + BFD_ENDIAN_LITTLE); + store_unsigned_integer (buf.data (), regsize, + BFD_ENDIAN_LITTLE, data); } else { - LONGEST data = extract_signed_integer (writebuf, len, BFD_ENDIAN_LITTLE); - store_signed_integer (buf, regsize, BFD_ENDIAN_LITTLE, data); + LONGEST data + = extract_signed_integer (writebuf, len, BFD_ENDIAN_LITTLE); + store_signed_integer (buf.data (), regsize, BFD_ENDIAN_LITTLE, + data); } - loongarch_xfer_reg (regcache, a0, regsize, nullptr, buf, 0); + + loongarch_xfer_reg (regcache, a0, regsize, nullptr, buf.data (), + 0); } else loongarch_xfer_reg (regcache, a0, len, readbuf, nullptr, 0); diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c index d9890d0..28dfb2f 100644 --- a/gdb/m32c-tdep.c +++ b/gdb/m32c-tdep.c @@ -2212,8 +2212,8 @@ m32c_return_value (struct gdbarch *gdbarch, /* Everything else is passed in mem0, using as many bytes as needed. This is not what the Renesas tools do, but it's what GCC does at the moment. */ - struct bound_minimal_symbol mem0 - = lookup_minimal_symbol ("mem0", NULL, NULL); + bound_minimal_symbol mem0 + = lookup_minimal_symbol (current_program_space, "mem0"); if (! mem0.minsym) error (_("The return value is stored in memory at 'mem0', " @@ -2244,8 +2244,8 @@ m32c_return_value (struct gdbarch *gdbarch, /* Everything else is passed in mem0, using as many bytes as needed. This is not what the Renesas tools do, but it's what GCC does at the moment. */ - struct bound_minimal_symbol mem0 - = lookup_minimal_symbol ("mem0", NULL, NULL); + bound_minimal_symbol mem0 + = lookup_minimal_symbol (current_program_space, "mem0"); if (! mem0.minsym) error (_("The return value is stored in memory at 'mem0', " @@ -2421,11 +2421,9 @@ m32c_m16c_address_to_pointer (struct gdbarch *gdbarch, { const char *func_name; char *tramp_name; - struct bound_minimal_symbol tramp_msym; /* Try to find a linker symbol at this address. */ - struct bound_minimal_symbol func_msym - = lookup_minimal_symbol_by_pc (addr); + bound_minimal_symbol func_msym = lookup_minimal_symbol_by_pc (addr); if (! func_msym.minsym) error (_("Cannot convert code address %s to function pointer:\n" @@ -2438,7 +2436,8 @@ m32c_m16c_address_to_pointer (struct gdbarch *gdbarch, strcat (tramp_name, ".plt"); /* Try to find a linker symbol for the trampoline. */ - tramp_msym = lookup_minimal_symbol (tramp_name, NULL, NULL); + bound_minimal_symbol tramp_msym + = lookup_minimal_symbol (current_program_space, tramp_name); /* We've either got another copy of the name now, or don't need the name any more. */ @@ -2502,7 +2501,7 @@ m32c_m16c_pointer_to_address (struct gdbarch *gdbarch, { /* See if there is a minimal symbol at that address whose name is "NAME.plt". */ - struct bound_minimal_symbol ptr_msym = lookup_minimal_symbol_by_pc (ptr); + bound_minimal_symbol ptr_msym = lookup_minimal_symbol_by_pc (ptr); if (ptr_msym.minsym) { @@ -2512,7 +2511,6 @@ m32c_m16c_pointer_to_address (struct gdbarch *gdbarch, if (len > 4 && strcmp (ptr_msym_name + len - 4, ".plt") == 0) { - struct bound_minimal_symbol func_msym; /* We have a .plt symbol; try to find the symbol for the corresponding function. @@ -2522,8 +2520,8 @@ m32c_m16c_pointer_to_address (struct gdbarch *gdbarch, char *func_name = (char *) xmalloc (len - 4 + 1); memcpy (func_name, ptr_msym_name, len - 4); func_name[len - 4] = '\0'; - func_msym - = lookup_minimal_symbol (func_name, NULL, NULL); + bound_minimal_symbol func_msym + = lookup_minimal_symbol (current_program_space, func_name); /* If we do have such a symbol, return its value as the function's true address. */ diff --git a/gdb/m32r-tdep.c b/gdb/m32r-tdep.c index f2f8602..c6428f6 100644 --- a/gdb/m32r-tdep.c +++ b/gdb/m32r-tdep.c @@ -800,14 +800,14 @@ m32r_frame_this_id (const frame_info_ptr &this_frame, = m32r_frame_unwind_cache (this_frame, this_prologue_cache); CORE_ADDR base; CORE_ADDR func; - struct bound_minimal_symbol msym_stack; struct frame_id id; /* The FUNC is easy. */ func = get_frame_func (this_frame); /* Check if the stack is empty. */ - msym_stack = lookup_minimal_symbol ("_stack", NULL, NULL); + bound_minimal_symbol msym_stack + = lookup_minimal_symbol (current_program_space, "_stack"); if (msym_stack.minsym && info->base == msym_stack.value_address ()) return; diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c index e58e44b..12cd0ef 100644 --- a/gdb/m68hc11-tdep.c +++ b/gdb/m68hc11-tdep.c @@ -210,9 +210,8 @@ static int soft_reg_initialized = 0; static void m68hc11_get_register_info (struct m68hc11_soft_reg *reg, const char *name) { - struct bound_minimal_symbol msymbol; - - msymbol = lookup_minimal_symbol (name, NULL, NULL); + bound_minimal_symbol msymbol + = lookup_minimal_symbol (current_program_space, name); if (msymbol.minsym) { reg->addr = msymbol.value_address (); @@ -591,12 +590,10 @@ m68hc11_analyze_instruction (struct gdbarch *gdbarch, static enum insn_return_kind m68hc11_get_return_insn (CORE_ADDR pc) { - struct bound_minimal_symbol sym; - /* A flag indicating that this is a STO_M68HC12_FAR or STO_M68HC12_INTERRUPT function is stored by elfread.c in the high bit of the info field. Use this to decide which instruction the function uses to return. */ - sym = lookup_minimal_symbol_by_pc (pc); + bound_minimal_symbol sym = lookup_minimal_symbol_by_pc (pc); if (sym.minsym == 0) return RETURN_RTS; diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c index 1b8cc92..375d5e6 100644 --- a/gdb/m68k-tdep.c +++ b/gdb/m68k-tdep.c @@ -1350,11 +1350,19 @@ static enum gdb_osabi m68k_osabi_sniffer (bfd *abfd) { unsigned int elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI]; + enum gdb_osabi osabi = GDB_OSABI_UNKNOWN; if (elfosabi == ELFOSABI_NONE) - return GDB_OSABI_SVR4; + { + /* Check note sections. */ + for (asection *sect : gdb_bfd_sections (abfd)) + generic_elf_osabi_sniff_abi_tag_sections (abfd, sect, &osabi); + + if (osabi == GDB_OSABI_UNKNOWN) + osabi = GDB_OSABI_SVR4; + } - return GDB_OSABI_UNKNOWN; + return osabi; } void _initialize_m68k_tdep (); diff --git a/gdb/machoread.c b/gdb/machoread.c index be68e45..ef6cf66 100644 --- a/gdb/machoread.c +++ b/gdb/machoread.c @@ -390,13 +390,14 @@ static CORE_ADDR macho_resolve_oso_sym_with_minsym (struct objfile *main_objfile, asymbol *sym) { /* For common symbol and global symbols, use the min symtab. */ - struct bound_minimal_symbol msym; const char *name = sym->name; if (*name != '\0' && *name == bfd_get_symbol_leading_char (main_objfile->obfd.get ())) ++name; - msym = lookup_minimal_symbol (name, NULL, main_objfile); + + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, name, main_objfile); if (msym.minsym == NULL) { warning (_("can't find symbol '%s' in minsymtab"), name); diff --git a/gdb/macrocmd.c b/gdb/macrocmd.c index 6cf3a0d..2da5a5b 100644 --- a/gdb/macrocmd.c +++ b/gdb/macrocmd.c @@ -271,18 +271,17 @@ skip_ws (const char **expp) } /* Try to find the bounds of an identifier. If an identifier is - found, returns a newly allocated string; otherwise returns NULL. + found, return it; otherwise return an empty string. + EXPP is a pointer to an input string; it is updated to point to the text following the identifier. If IS_PARAMETER is true, this function will also allow "..." forms as used in varargs macro parameters. */ -static gdb::unique_xmalloc_ptr<char> +static std::string extract_identifier (const char **expp, int is_parameter) { - char *result; const char *p = *expp; - unsigned int len; if (is_parameter && startswith (p, "...")) { @@ -291,67 +290,39 @@ extract_identifier (const char **expp, int is_parameter) else { if (! *p || ! macro_is_identifier_nondigit (*p)) - return NULL; + return {}; + for (++p; *p && (macro_is_identifier_nondigit (*p) || macro_is_digit (*p)); ++p) ; } - if (is_parameter && startswith (p, "...")) + if (is_parameter && startswith (p, "...")) p += 3; - len = p - *expp; - result = (char *) xmalloc (len + 1); - memcpy (result, *expp, len); - result[len] = '\0'; - *expp += len; - return gdb::unique_xmalloc_ptr<char> (result); -} + std::string result (*expp, p); + *expp = p; -struct temporary_macro_definition : public macro_definition -{ - temporary_macro_definition () - { - table = nullptr; - kind = macro_object_like; - argc = 0; - argv = nullptr; - replacement = nullptr; - } - - ~temporary_macro_definition () - { - int i; - - for (i = 0; i < argc; ++i) - xfree ((char *) argv[i]); - xfree ((char *) argv); - /* Note that the 'replacement' field is not allocated. */ - } -}; + return result; +} static void macro_define_command (const char *exp, int from_tty) { - temporary_macro_definition new_macro; - if (!exp) error (_("usage: macro define NAME[(ARGUMENT-LIST)] [REPLACEMENT-LIST]")); skip_ws (&exp); - gdb::unique_xmalloc_ptr<char> name = extract_identifier (&exp, 0); - if (name == NULL) + + std::string name = extract_identifier (&exp, 0); + if (name.empty ()) error (_("Invalid macro name.")); + if (*exp == '(') { /* Function-like macro. */ - int alloced = 5; - char **argv = XNEWVEC (char *, alloced); - - new_macro.kind = macro_function_like; - new_macro.argc = 0; - new_macro.argv = (const char * const *) argv; + std::vector<std::string> argv; /* Skip the '(' and whitespace. */ ++exp; @@ -359,23 +330,13 @@ macro_define_command (const char *exp, int from_tty) while (*exp != ')') { - int i; - - if (new_macro.argc == alloced) - { - alloced *= 2; - argv = (char **) xrealloc (argv, alloced * sizeof (char *)); - /* Must update new_macro as well... */ - new_macro.argv = (const char * const *) argv; - } - argv[new_macro.argc] = extract_identifier (&exp, 1).release (); - if (! argv[new_macro.argc]) + argv.emplace_back (extract_identifier (&exp, 1)); + if (argv.back ().empty ()) error (_("Macro is missing an argument.")); - ++new_macro.argc; - for (i = new_macro.argc - 2; i >= 0; --i) + for (const auto &other_arg : argv) { - if (! strcmp (argv[i], argv[new_macro.argc - 1])) + if (&other_arg != &argv.back () && other_arg == argv.back ()) error (_("Two macro arguments with identical names.")); } @@ -388,18 +349,18 @@ macro_define_command (const char *exp, int from_tty) else if (*exp != ')') error (_("',' or ')' expected at end of macro arguments.")); } + /* Skip the closing paren. */ ++exp; skip_ws (&exp); - macro_define_function (macro_main (macro_user_macros), -1, name.get (), - new_macro.argc, (const char **) new_macro.argv, - exp); + macro_define_function (macro_main (macro_user_macros), -1, name.c_str (), + argv, exp); } else { skip_ws (&exp); - macro_define_object (macro_main (macro_user_macros), -1, name.get (), + macro_define_object (macro_main (macro_user_macros), -1, name.c_str (), exp); } } @@ -412,10 +373,12 @@ macro_undef_command (const char *exp, int from_tty) error (_("usage: macro undef NAME")); skip_ws (&exp); - gdb::unique_xmalloc_ptr<char> name = extract_identifier (&exp, 0); - if (name == nullptr) + + std::string name = extract_identifier (&exp, 0); + if (name.empty ()) error (_("Invalid macro name.")); - macro_undef (macro_main (macro_user_macros), -1, name.get ()); + + macro_undef (macro_main (macro_user_macros), -1, name.c_str ()); } diff --git a/gdb/macroscope.c b/gdb/macroscope.c index 4c1304f..c1b2238 100644 --- a/gdb/macroscope.c +++ b/gdb/macroscope.c @@ -121,9 +121,9 @@ default_macro_scope (void) symbol files loaded, then get_current_or_default would raise an error. But `set width' shouldn't raise an error just because it can't decide which scope to macro-expand its argument in. */ - struct symtab_and_line cursal - = get_current_source_symtab_and_line (); - + symtab_and_line cursal + = get_current_source_symtab_and_line (current_program_space); + sal.symtab = cursal.symtab; sal.line = cursal.line; } diff --git a/gdb/macrotab.c b/gdb/macrotab.c index 3a7f792..37ae0f2 100644 --- a/gdb/macrotab.c +++ b/gdb/macrotab.c @@ -545,10 +545,10 @@ macro_lookup_inclusion (struct macro_source_file *source, const char *name) /* Construct a definition for a macro in table T. Cache all strings, and the macro_definition structure itself, in T's bcache. */ -static struct macro_definition * -new_macro_definition (struct macro_table *t, - enum macro_kind kind, - int argc, const char **argv, +static macro_definition * +new_macro_definition (macro_table *t, macro_kind kind, + macro_special_kind special_kind, + const std::vector<std::string> &argv, const char *replacement) { struct macro_definition *d @@ -558,22 +558,26 @@ new_macro_definition (struct macro_table *t, d->table = t; d->kind = kind; d->replacement = macro_bcache_str (t, replacement); - d->argc = argc; if (kind == macro_function_like) { - int i; - const char **cached_argv; - int cached_argv_size = argc * sizeof (*cached_argv); + d->argc = argv.size (); /* Bcache all the arguments. */ - cached_argv = (const char **) alloca (cached_argv_size); - for (i = 0; i < argc; i++) - cached_argv[i] = macro_bcache_str (t, argv[i]); + if (d->argc > 0) + { + std::vector<const char *> cached_argv; - /* Now bcache the array of argument pointers itself. */ - d->argv = macro_bcache (t, cached_argv, cached_argv_size); + for (const auto &arg : argv) + cached_argv.push_back (macro_bcache_str (t, arg.c_str ())); + + /* Now bcache the array of argument pointers itself. */ + d->argv = macro_bcache (t, cached_argv.data (), + cached_argv.size () * sizeof (const char *)); + } } + else + d->argc = special_kind; /* We don't bcache the entire definition structure because it's got a pointer to the macro table in it; since each compilation unit @@ -677,13 +681,12 @@ find_definition (const char *name, /* If NAME already has a definition in scope at LINE in SOURCE, return the key. If the old definition is different from the definition - given by KIND, ARGC, ARGV, and REPLACEMENT, complain, too. - Otherwise, return zero. (ARGC and ARGV are meaningless unless KIND + given by KIND, ARGV, and REPLACEMENT, complain, too. + Otherwise, return nullptr. (ARGV is meaningless unless KIND is `macro_function_like'.) */ -static struct macro_key * -check_for_redefinition (struct macro_source_file *source, int line, - const char *name, enum macro_kind kind, - int argc, const char **argv, +static macro_key * +check_for_redefinition (macro_source_file *source, int line, const char *name, + macro_kind kind, const std::vector<std::string> &argv, const char *replacement) { splay_tree_node n = find_definition (name, source, line); @@ -708,14 +711,14 @@ check_for_redefinition (struct macro_source_file *source, int line, same = 0; else if (kind == macro_function_like) { - if (argc != found_def->argc) + if (argv.size () != found_def->argc) same = 0; else { - int i; + int i = 0; - for (i = 0; i < argc; i++) - if (strcmp (argv[i], found_def->argv[i])) + for (const auto &arg : argv) + if (arg != found_def->argv[i++]) same = 0; } } @@ -739,15 +742,18 @@ check_for_redefinition (struct macro_source_file *source, int line, } /* A helper function to define a new object-like or function-like macro - according to KIND. When KIND is macro_object_like, - the macro_special_kind must be provided as ARGC, and ARGV must be NULL. - When KIND is macro_function_like, ARGC and ARGV are giving the function - arguments. */ + according to KIND. + + When KIND is macro_object_like, the possible special kind is given by + SPECIAL_KIND, and ARGV is meaningless. + + When KIND is macro_function_like, ARGV gives the macro argument names, and + SPECIAL_KIND is meaningless. */ static void -macro_define_internal (struct macro_source_file *source, int line, - const char *name, enum macro_kind kind, - int argc, const char **argv, +macro_define_internal (macro_source_file *source, int line, const char *name, + macro_kind kind, macro_special_kind special_kind, + const std::vector<std::string> &argv, const char *replacement) { struct macro_table *t = source->table; @@ -755,10 +761,7 @@ macro_define_internal (struct macro_source_file *source, int line, struct macro_definition *d; if (! t->redef_ok) - k = check_for_redefinition (source, line, - name, kind, - argc, argv, - replacement); + k = check_for_redefinition (source, line, name, kind, argv, replacement); /* If we're redefining a symbol, and the existing key would be identical to our new key, then the splay_tree_insert function @@ -774,7 +777,7 @@ macro_define_internal (struct macro_source_file *source, int line, return; k = new_macro_key (t, name, source, line); - d = new_macro_definition (t, kind, argc, argv, replacement); + d = new_macro_definition (t, kind, special_kind, argv, replacement); splay_tree_insert (t->definitions, (splay_tree_key) k, (splay_tree_value) d); } @@ -785,10 +788,8 @@ macro_define_object_internal (struct macro_source_file *source, int line, const char *name, const char *replacement, enum macro_special_kind special_kind) { - macro_define_internal (source, line, - name, macro_object_like, - special_kind, NULL, - replacement); + macro_define_internal (source, line, name, macro_object_like, special_kind, + {}, replacement); } void @@ -811,14 +812,12 @@ macro_define_special (struct macro_table *table) } void -macro_define_function (struct macro_source_file *source, int line, - const char *name, int argc, const char **argv, +macro_define_function (macro_source_file *source, int line, const char *name, + const std::vector<std::string> &argv, const char *replacement) { - macro_define_internal (source, line, - name, macro_function_like, - argc, argv, - replacement); + macro_define_internal (source, line, name, macro_function_like, + macro_ordinary, argv, replacement); } void diff --git a/gdb/macrotab.h b/gdb/macrotab.h index 789beed..d501595 100644 --- a/gdb/macrotab.h +++ b/gdb/macrotab.h @@ -242,26 +242,23 @@ struct macro_source_file *macro_lookup_inclusion Record in SOURCE's macro table that, at line number LINE in SOURCE, we #defined a preprocessor symbol named NAME, whose replacement string is REPLACEMENT. This function makes copies of NAME and - REPLACEMENT; the caller is responsible for freeing them. */ + REPLACEMENT. */ void macro_define_object (struct macro_source_file *source, int line, const char *name, const char *replacement); -/* Record an function-like #definition (i.e., one with a parameter list). +/* Record a function-like #definition (i.e., one with a parameter list). Record in SOURCE's macro table that, at line number LINE in SOURCE, - we #defined a preprocessor symbol named NAME, with ARGC arguments - whose names are given in ARGV, whose replacement string is REPLACEMENT. If - the macro takes a variable number of arguments, then ARGC should be - one greater than the number of named arguments, and ARGV[ARGC-1] - should be the string "...". This function makes its own copies of - NAME, ARGV, and REPLACEMENT; the caller is responsible for freeing - them. */ -void macro_define_function (struct macro_source_file *source, int line, - const char *name, int argc, const char **argv, + we #defined a preprocessor symbol named NAME, with argument names given by + ARGV, whose replacement string is REPLACEMENT. If the macro takes a variable + number of arguments, then the last element of ARGV should be the string + "...". This function makes copies of NAME, ARGV, and REPLACEMENT. */ +void macro_define_function (macro_source_file *source, int line, + const char *name, + const std::vector<std::string> &argv, const char *replacement); - /* Record an #undefinition. Record in SOURCE's macro table that, at line number LINE in SOURCE, we removed the definition for the preprocessor symbol named NAME. */ diff --git a/gdb/maint.c b/gdb/maint.c index d091634..237c9d8 100644 --- a/gdb/maint.c +++ b/gdb/maint.c @@ -546,7 +546,6 @@ maintenance_translate_address (const char *arg, int from_tty) CORE_ADDR address; struct obj_section *sect; const char *p; - struct bound_minimal_symbol sym; if (arg == NULL || *arg == 0) error (_("requires argument (address or section + address)")); @@ -577,6 +576,7 @@ maintenance_translate_address (const char *arg, int from_tty) address = parse_and_eval_address (p); + bound_minimal_symbol sym; if (sect) sym = lookup_minimal_symbol_by_pc_section (address, sect); else diff --git a/gdb/make-target-delegates.py b/gdb/make-target-delegates.py index bfcf7fa..fc69cb3 100755 --- a/gdb/make-target-delegates.py +++ b/gdb/make-target-delegates.py @@ -362,7 +362,7 @@ for current_line in scan_target_h(): delegators.append(name) -with open("target-delegates.c", "w") as f: +with open("target-delegates-gen.c", "w") as f: print( gdbcopyright.copyright( "make-target-delegates.py", "Boilerplate target methods for GDB" diff --git a/gdb/mi/mi-cmd-file.c b/gdb/mi/mi-cmd-file.c index 3e2702e..f2fe435 100644 --- a/gdb/mi/mi-cmd-file.c +++ b/gdb/mi/mi-cmd-file.c @@ -35,7 +35,6 @@ void mi_cmd_file_list_exec_source_file (const char *command, const char *const *argv, int argc) { - struct symtab_and_line st; struct ui_out *uiout = current_uiout; if (!mi_valid_noargs ("-file-list-exec-source-file", argc, argv)) @@ -43,7 +42,8 @@ mi_cmd_file_list_exec_source_file (const char *command, /* Set the default file and line, also get them. */ set_default_source_symtab_and_line (); - st = get_current_source_symtab_and_line (); + symtab_and_line st + = get_current_source_symtab_and_line (current_program_space); /* We should always get a symtab. Apparently, filename does not need to be tested for NULL. The documentation in symtab.h diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index 5bcb5f7..b72cd1b9 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -2130,10 +2130,7 @@ mi_cmd_execute (struct mi_parse *parse) std::optional<scoped_restore_current_language> lang_saver; if (parse->language != language_unknown) - { - lang_saver.emplace (); - set_language (parse->language); - } + lang_saver.emplace (parse->language); current_context = parse; diff --git a/gdb/mi/mi-symbol-cmds.c b/gdb/mi/mi-symbol-cmds.c index 15c032b..e90055f 100644 --- a/gdb/mi/mi-symbol-cmds.c +++ b/gdb/mi/mi-symbol-cmds.c @@ -95,8 +95,7 @@ output_debug_symbol (ui_out *uiout, domain_search_flags kind, and then outputs the fields for this msymbol. */ static void -output_nondebug_symbol (ui_out *uiout, - const struct bound_minimal_symbol &msymbol) +output_nondebug_symbol (ui_out *uiout, const bound_minimal_symbol &msymbol) { struct gdbarch *gdbarch = msymbol.objfile->arch (); ui_out_emit_tuple tuple_emitter (uiout, NULL); diff --git a/gdb/minsyms.c b/gdb/minsyms.c index 38176c4..b5c4b95 100644 --- a/gdb/minsyms.c +++ b/gdb/minsyms.c @@ -358,9 +358,9 @@ lookup_minimal_symbol_demangled (const lookup_name_info &lookup_name, Obviously, there must be distinct mangled names for each of these, but the demangled names are all the same: S::S or S::~S. */ -struct bound_minimal_symbol -lookup_minimal_symbol (const char *name, const char *sfile, - struct objfile *objf) +bound_minimal_symbol +lookup_minimal_symbol (program_space *pspace, const char *name, objfile *objf, + const char *sfile) { found_minimal_symbols found; @@ -376,7 +376,7 @@ lookup_minimal_symbol (const char *name, const char *sfile, lookup_name_info lookup_name (name, symbol_name_match_type::FULL); - for (objfile *objfile : current_program_space->objfiles ()) + for (objfile *objfile : pspace->objfiles ()) { if (found.external_symbol.minsym != NULL) break; @@ -384,7 +384,8 @@ lookup_minimal_symbol (const char *name, const char *sfile, if (objf == NULL || objf == objfile || objf == objfile->separate_debug_objfile_backlink) { - symbol_lookup_debug_printf ("lookup_minimal_symbol (%s, %s, %s)", + symbol_lookup_debug_printf ("lookup_minimal_symbol (%s, %s, %s, %s)", + host_address_to_string (pspace), name, sfile != NULL ? sfile : "NULL", objfile_debug_name (objfile)); @@ -474,23 +475,14 @@ lookup_minimal_symbol (const char *name, const char *sfile, return {}; } -/* See minsyms.h. */ - -struct bound_minimal_symbol -lookup_bound_minimal_symbol (const char *name) -{ - return lookup_minimal_symbol (name, NULL, NULL); -} - /* See gdbsupport/symbol.h. */ int find_minimal_symbol_address (const char *name, CORE_ADDR *addr, struct objfile *objfile) { - struct bound_minimal_symbol sym - = lookup_minimal_symbol (name, NULL, objfile); - + bound_minimal_symbol sym + = lookup_minimal_symbol (current_program_space, name, objfile); if (sym.minsym != NULL) *addr = sym.value_address (); @@ -591,10 +583,11 @@ lookup_minimal_symbol_linkage (const char *name, struct objfile *objf) /* See minsyms.h. */ -struct bound_minimal_symbol -lookup_minimal_symbol_linkage (const char *name, bool only_main) +bound_minimal_symbol +lookup_minimal_symbol_linkage (program_space *pspace, const char *name, + bool only_main) { - for (objfile *objfile : current_program_space->objfiles ()) + for (objfile *objfile : pspace->objfiles ()) { if (objfile->separate_debug_objfile_backlink != nullptr) continue; @@ -613,12 +606,13 @@ lookup_minimal_symbol_linkage (const char *name, bool only_main) /* See minsyms.h. */ -struct bound_minimal_symbol -lookup_minimal_symbol_text (const char *name, struct objfile *objf) +bound_minimal_symbol +lookup_minimal_symbol_text (program_space *pspace, const char *name, + objfile *objf) { struct minimal_symbol *msymbol; - struct bound_minimal_symbol found_symbol; - struct bound_minimal_symbol found_file_symbol; + bound_minimal_symbol found_symbol; + bound_minimal_symbol found_file_symbol; unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE; @@ -650,7 +644,7 @@ lookup_minimal_symbol_text (const char *name, struct objfile *objf) if (objf == nullptr) { - for (objfile *objfile : current_program_space->objfiles ()) + for (objfile *objfile : pspace->objfiles ()) { if (found_symbol.minsym != NULL) break; @@ -765,7 +759,6 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc_in, struct obj_section *sectio struct minimal_symbol *msymbol; struct minimal_symbol *best_symbol = NULL; struct objfile *best_objfile = NULL; - struct bound_minimal_symbol result; if (previous != nullptr) { @@ -997,6 +990,7 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc_in, struct obj_section *sectio } } + bound_minimal_symbol result; result.minsym = best_symbol; result.objfile = best_objfile; return result; @@ -1004,7 +998,7 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc_in, struct obj_section *sectio /* See minsyms.h. */ -struct bound_minimal_symbol +bound_minimal_symbol lookup_minimal_symbol_by_pc (CORE_ADDR pc) { return lookup_minimal_symbol_by_pc_section (pc, NULL); @@ -1074,20 +1068,19 @@ const struct gnu_ifunc_fns *gnu_ifunc_fns_p = &stub_gnu_ifunc_fns; -/* Return leading symbol character for a BFD. If BFD is NULL, - return the leading symbol character from the main objfile. */ +/* Return the leading symbol character for BFD ABFD. If ABFD is nullptr, + return the leading symbol character from the the main objfile of PSPACE.. */ static int -get_symbol_leading_char (bfd *abfd) +get_symbol_leading_char (program_space *pspace, bfd *abfd) { if (abfd != NULL) return bfd_get_symbol_leading_char (abfd); - if (current_program_space->symfile_object_file != NULL) - { - objfile *objf = current_program_space->symfile_object_file; - if (objf->obfd != NULL) - return bfd_get_symbol_leading_char (objf->obfd.get ()); - } + + if (objfile *objf = pspace->symfile_object_file; + objf != nullptr && objf->obfd != nullptr) + return bfd_get_symbol_leading_char (objf->obfd.get ()); + return 0; } @@ -1202,7 +1195,8 @@ minimal_symbol_reader::record_full (std::string_view name, /* It's safe to strip the leading char here once, since the name is also stored stripped in the minimal symbol table. */ - if (name[0] == get_symbol_leading_char (m_objfile->obfd.get ())) + if (name[0] == get_symbol_leading_char (m_objfile->pspace (), + m_objfile->obfd.get ())) name = name.substr (1); if (ms_type == mst_file_text && startswith (name, "__gnu_compiled")) @@ -1598,7 +1592,7 @@ find_solib_trampoline_target (const frame_info_ptr &frame, CORE_ADDR pc) /* See minsyms.h. */ CORE_ADDR -minimal_symbol_upper_bound (struct bound_minimal_symbol minsym) +minimal_symbol_upper_bound (bound_minimal_symbol minsym) { short section; struct obj_section *obj_section; diff --git a/gdb/minsyms.h b/gdb/minsyms.h index d44f281..9659f30 100644 --- a/gdb/minsyms.h +++ b/gdb/minsyms.h @@ -20,6 +20,7 @@ #ifndef MINSYMS_H #define MINSYMS_H +struct program_space; struct type; /* Several lookup functions return both a minimal symbol and the @@ -205,16 +206,12 @@ unsigned int msymbol_hash_iw (const char *); symbols are still preferred). Returns a bound minimal symbol that matches, or an empty bound minimal symbol if no match is found. */ -struct bound_minimal_symbol lookup_minimal_symbol (const char *, - const char *, - struct objfile *); +bound_minimal_symbol lookup_minimal_symbol (program_space *pspace, + const char *name, + objfile *obj = nullptr, + const char *sfile = nullptr); -/* Like lookup_minimal_symbol, but searches all files and - objfiles. */ - -struct bound_minimal_symbol lookup_bound_minimal_symbol (const char *); - -/* Look through all the current minimal symbol tables and find the +/* Look through all the minimal symbol tables in PSPACE and find the first minimal symbol that matches NAME and has text type. If OBJF is non-NULL, limit the search to that objfile. Returns a bound minimal symbol that matches, or an "empty" bound minimal symbol @@ -222,8 +219,9 @@ struct bound_minimal_symbol lookup_bound_minimal_symbol (const char *); This function only searches the mangled (linkage) names. */ -struct bound_minimal_symbol lookup_minimal_symbol_text (const char *, - struct objfile *); +bound_minimal_symbol lookup_minimal_symbol_text (program_space *pspace, + const char *name, + objfile *objf); /* Look through the minimal symbols in OBJF (and its separate debug objfiles) for a global (not file-local) minsym whose linkage name @@ -232,16 +230,16 @@ struct bound_minimal_symbol lookup_minimal_symbol_text (const char *, objfile is not accepted. Returns a bound minimal symbol that matches, or an "empty" bound minimal symbol otherwise. */ -extern struct bound_minimal_symbol lookup_minimal_symbol_linkage - (const char *name, struct objfile *objf) +extern bound_minimal_symbol lookup_minimal_symbol_linkage (const char *name, + struct objfile *objf) ATTRIBUTE_NONNULL (1) ATTRIBUTE_NONNULL (2); /* A variant of lookup_minimal_symbol_linkage that iterates over all - objfiles. If ONLY_MAIN is true, then only an objfile with + objfiles of PSPACE. If ONLY_MAIN is true, then only an objfile with OBJF_MAINLINE will be considered. */ -extern struct bound_minimal_symbol lookup_minimal_symbol_linkage - (const char *name, bool only_main) +extern bound_minimal_symbol lookup_minimal_symbol_linkage + (program_space *pspace, const char *name, bool only_main) ATTRIBUTE_NONNULL (1); /* Look through all the current minimal symbol tables and find the @@ -287,7 +285,7 @@ enum class lookup_msym_prefer then the contents will be set to reference the closest symbol before PC_IN. */ -struct bound_minimal_symbol lookup_minimal_symbol_by_pc_section +bound_minimal_symbol lookup_minimal_symbol_by_pc_section (CORE_ADDR pc_in, struct obj_section *section, lookup_msym_prefer prefer = lookup_msym_prefer::TEXT, @@ -299,7 +297,7 @@ struct bound_minimal_symbol lookup_minimal_symbol_by_pc_section This is a wrapper that calls lookup_minimal_symbol_by_pc_section with a NULL section argument. */ -struct bound_minimal_symbol lookup_minimal_symbol_by_pc (CORE_ADDR); +bound_minimal_symbol lookup_minimal_symbol_by_pc (CORE_ADDR); /* Iterate over all the minimal symbols in the objfile OBJF which match NAME. Both the ordinary and demangled names of each symbol @@ -318,7 +316,7 @@ void iterate_over_minimal_symbols symbol in the same section, or the end of the section, as the end of the function. */ -CORE_ADDR minimal_symbol_upper_bound (struct bound_minimal_symbol minsym); +CORE_ADDR minimal_symbol_upper_bound (bound_minimal_symbol minsym); /* Return the type of MSYMBOL, a minimal symbol of OBJFILE. If ADDRESS_P is not NULL, set it to the MSYMBOL's resolved diff --git a/gdb/mips-fbsd-tdep.c b/gdb/mips-fbsd-tdep.c index 7452057..7736078 100644 --- a/gdb/mips-fbsd-tdep.c +++ b/gdb/mips-fbsd-tdep.c @@ -468,8 +468,8 @@ static const struct tramp_frame mips64_fbsd_sigframe = static CORE_ADDR mips_fbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc) { - struct bound_minimal_symbol msym - = lookup_bound_minimal_symbol ("_mips_rtld_bind"); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, "_mips_rtld_bind"); if (msym.minsym != nullptr && msym.value_address () == pc) return frame_unwind_caller_pc (get_current_frame ()); diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c index 7bd96a8..b076d24 100644 --- a/gdb/mips-linux-tdep.c +++ b/gdb/mips-linux-tdep.c @@ -99,16 +99,17 @@ mips_linux_get_longjmp_target (const frame_info_ptr &frame, CORE_ADDR *pc) CORE_ADDR jb_addr; struct gdbarch *gdbarch = get_frame_arch (frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - gdb_byte buf[gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT]; + gdb::byte_vector buf (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT); jb_addr = get_frame_register_unsigned (frame, MIPS_A0_REGNUM); if (target_read_memory ((jb_addr + MIPS_LINUX_JB_PC * MIPS_LINUX_JB_ELEMENT_SIZE), - buf, gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT)) + buf.data (), + gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT)) return 0; - *pc = extract_unsigned_integer (buf, + *pc = extract_unsigned_integer (buf.data (), gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT, byte_order); @@ -698,9 +699,8 @@ mips_linux_in_dynsym_resolve_code (CORE_ADDR pc) static CORE_ADDR mips_linux_skip_resolver (struct gdbarch *gdbarch, CORE_ADDR pc) { - struct bound_minimal_symbol resolver; - - resolver = lookup_minimal_symbol ("__dl_runtime_resolve", NULL, NULL); + bound_minimal_symbol resolver + = lookup_minimal_symbol (current_program_space, "__dl_runtime_resolve"); if (resolver.minsym && resolver.value_address () == pc) return frame_unwind_caller_pc (get_current_frame ()); diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index ae58d7c..f000d2f 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -490,10 +490,10 @@ mips_make_symbol_special (struct symbol *sym, struct objfile *objfile) /* We are in symbol reading so it is OK to cast away constness. */ struct block *block = (struct block *) sym->value_block (); CORE_ADDR compact_block_start; - struct bound_minimal_symbol msym; compact_block_start = block->start () | 1; - msym = lookup_minimal_symbol_by_pc (compact_block_start); + bound_minimal_symbol msym + = lookup_minimal_symbol_by_pc (compact_block_start); if (msym.minsym && !msymbol_is_mips (msym.minsym)) { block->set_start (compact_block_start); @@ -896,7 +896,7 @@ set_mips64_transfers_32bit_regs (const char *args, int from_tty, /* FIXME: cagney/2003-11-15: Should be setting a field in "info" instead of relying on globals. Doing that would let generic code handle the search for this specific architecture. */ - if (!gdbarch_update_p (info)) + if (!gdbarch_update_p (current_inferior (), info)) { mips64_transfers_32bit_regs_p = 0; error (_("32-bit compatibility mode not supported")); @@ -1212,13 +1212,12 @@ show_mask_address (struct ui_file *file, int from_tty, int mips_pc_is_mips (CORE_ADDR memaddr) { - struct bound_minimal_symbol sym; - /* Flags indicating that this is a MIPS16 or microMIPS function is stored by elfread.c in the high bit of the info field. Use this to decide if the function is standard MIPS. Otherwise if bit 0 of the address is clear, then this is a standard MIPS function. */ - sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr)); + bound_minimal_symbol sym + = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr)); if (sym.minsym) return msymbol_is_mips (sym.minsym); else @@ -1230,13 +1229,12 @@ mips_pc_is_mips (CORE_ADDR memaddr) int mips_pc_is_mips16 (struct gdbarch *gdbarch, CORE_ADDR memaddr) { - struct bound_minimal_symbol sym; - /* A flag indicating that this is a MIPS16 function is stored by elfread.c in the high bit of the info field. Use this to decide if the function is MIPS16. Otherwise if bit 0 of the address is set, then ELF file flags will tell if this is a MIPS16 function. */ - sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr)); + bound_minimal_symbol sym + = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr)); if (sym.minsym) return msymbol_is_mips16 (sym.minsym); else @@ -1248,14 +1246,13 @@ mips_pc_is_mips16 (struct gdbarch *gdbarch, CORE_ADDR memaddr) int mips_pc_is_micromips (struct gdbarch *gdbarch, CORE_ADDR memaddr) { - struct bound_minimal_symbol sym; - /* A flag indicating that this is a microMIPS function is stored by elfread.c in the high bit of the info field. Use this to decide if the function is microMIPS. Otherwise if bit 0 of the address is set, then ELF file flags will tell if this is a microMIPS function. */ - sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr)); + bound_minimal_symbol sym + = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr)); if (sym.minsym) return msymbol_is_micromips (sym.minsym); else @@ -1268,14 +1265,13 @@ mips_pc_is_micromips (struct gdbarch *gdbarch, CORE_ADDR memaddr) static enum mips_isa mips_pc_isa (struct gdbarch *gdbarch, CORE_ADDR memaddr) { - struct bound_minimal_symbol sym; - /* A flag indicating that this is a MIPS16 or a microMIPS function is stored by elfread.c in the high bit of the info field. Use this to decide if the function is MIPS16 or microMIPS or normal MIPS. Otherwise if bit 0 of the address is set, then ELF file flags will tell if this is a MIPS16 or a microMIPS function. */ - sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr)); + bound_minimal_symbol sym + = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr)); if (sym.minsym) { if (msymbol_is_micromips (sym.minsym)) @@ -3841,7 +3837,6 @@ mips_stub_frame_sniffer (const struct frame_unwind *self, { gdb_byte dummy[4]; CORE_ADDR pc = get_frame_address_in_block (this_frame); - struct bound_minimal_symbol msym; /* Use the stub unwinder for unreadable code. */ if (target_read_memory (get_frame_pc (this_frame), dummy, 4) != 0) @@ -3852,7 +3847,7 @@ mips_stub_frame_sniffer (const struct frame_unwind *self, /* Calling a PIC function from a non-PIC function passes through a stub. The stub for foo is named ".pic.foo". */ - msym = lookup_minimal_symbol_by_pc (pc); + bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (pc); if (msym.minsym != NULL && msym.minsym->linkage_name () != NULL && startswith (msym.minsym->linkage_name (), ".pic.")) @@ -6973,7 +6968,7 @@ set_mipsfpu_single_command (const char *args, int from_tty) /* FIXME: cagney/2003-11-15: Should be setting a field in "info" instead of relying on globals. Doing that would let generic code handle the search for this specific architecture. */ - if (!gdbarch_update_p (info)) + if (!gdbarch_update_p (current_inferior (), info)) internal_error (_("set mipsfpu failed")); } @@ -6986,7 +6981,7 @@ set_mipsfpu_double_command (const char *args, int from_tty) /* FIXME: cagney/2003-11-15: Should be setting a field in "info" instead of relying on globals. Doing that would let generic code handle the search for this specific architecture. */ - if (!gdbarch_update_p (info)) + if (!gdbarch_update_p (current_inferior (), info)) internal_error (_("set mipsfpu failed")); } @@ -6999,7 +6994,7 @@ set_mipsfpu_none_command (const char *args, int from_tty) /* FIXME: cagney/2003-11-15: Should be setting a field in "info" instead of relying on globals. Doing that would let generic code handle the search for this specific architecture. */ - if (!gdbarch_update_p (info)) + if (!gdbarch_update_p (current_inferior (), info)) internal_error (_("set mipsfpu failed")); } @@ -7824,7 +7819,6 @@ mips_skip_pic_trampoline_code (const frame_info_ptr &frame, CORE_ADDR pc) { struct gdbarch *gdbarch = get_frame_arch (frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - struct bound_minimal_symbol msym; int i; gdb_byte stub_code[16]; int32_t stub_words[4]; @@ -7832,7 +7826,7 @@ mips_skip_pic_trampoline_code (const frame_info_ptr &frame, CORE_ADDR pc) /* The stub for foo is named ".pic.foo", and is either two instructions inserted before foo or a three instruction sequence which jumps to foo. */ - msym = lookup_minimal_symbol_by_pc (pc); + bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (pc); if (msym.minsym == NULL || msym.value_address () != pc || msym.minsym->linkage_name () == NULL @@ -8846,7 +8840,7 @@ mips_abi_update (const char *ignore_args, /* Force the architecture to update, and (if it's a MIPS architecture) mips_gdbarch_init will take care of the rest. */ - gdbarch_update_p (info); + gdbarch_update_p (current_inferior (), info); } /* Print out which MIPS ABI is in use. */ diff --git a/gdb/msp430-tdep.c b/gdb/msp430-tdep.c index 017ebb4..41a8f99 100644 --- a/gdb/msp430-tdep.c +++ b/gdb/msp430-tdep.c @@ -807,11 +807,10 @@ msp430_in_return_stub (struct gdbarch *gdbarch, CORE_ADDR pc, static CORE_ADDR msp430_skip_trampoline_code (const frame_info_ptr &frame, CORE_ADDR pc) { - struct bound_minimal_symbol bms; const char *stub_name; struct gdbarch *gdbarch = get_frame_arch (frame); - bms = lookup_minimal_symbol_by_pc (pc); + bound_minimal_symbol bms = lookup_minimal_symbol_by_pc (pc); if (!bms.minsym) return pc; diff --git a/gdb/nat/aarch64-mte-linux-ptrace.c b/gdb/nat/aarch64-mte-linux-ptrace.c index ace3e18..f215588 100644 --- a/gdb/nat/aarch64-mte-linux-ptrace.c +++ b/gdb/nat/aarch64-mte-linux-ptrace.c @@ -22,6 +22,7 @@ #include "linux-ptrace.h" #include "arch/aarch64.h" +#include "arch/aarch64-mte.h" #include "arch/aarch64-mte-linux.h" #include "nat/aarch64-linux.h" #include "nat/aarch64-mte-linux-ptrace.h" @@ -31,7 +32,7 @@ /* Helper function to display various possible errors when reading MTE tags. */ -static void ATTRIBUTE_NORETURN +[[noreturn]] static void aarch64_mte_linux_peek_error (int error) { switch (error) @@ -53,7 +54,7 @@ aarch64_mte_linux_peek_error (int error) /* Helper function to display various possible errors when writing MTE tags. */ -static void ATTRIBUTE_NORETURN +[[noreturn]] static void aarch64_mte_linux_poke_error (int error) { switch (error) @@ -118,10 +119,10 @@ aarch64_mte_fetch_memtags (int tid, CORE_ADDR address, size_t len, if (ntags == 0) return true; - gdb_byte tagbuf[ntags]; + gdb::byte_vector tagbuf (ntags); struct iovec iovec; - iovec.iov_base = tagbuf; + iovec.iov_base = tagbuf.data (); iovec.iov_len = ntags; tags.clear (); diff --git a/gdb/nat/aarch64-scalable-linux-ptrace.c b/gdb/nat/aarch64-scalable-linux-ptrace.c index 81bb8ea..0f1bedf 100644 --- a/gdb/nat/aarch64-scalable-linux-ptrace.c +++ b/gdb/nat/aarch64-scalable-linux-ptrace.c @@ -920,8 +920,7 @@ aarch64_za_regs_copy_to_reg_buf (int tid, struct reg_buffer_common *reg_buf, else { size_t za_bytes = header->vl * header->vl; - gdb_byte za_zeroed[za_bytes]; - memset (za_zeroed, 0, za_bytes); + gdb::byte_vector za_zeroed (za_bytes, 0); reg_buf->raw_supply (za_regnum, za_zeroed); } @@ -994,8 +993,7 @@ aarch64_za_regs_copy_from_reg_buf (int tid, bool has_za_state = aarch64_has_za_state (tid); size_t za_bytes = sve_vl_from_vg (old_svg) * sve_vl_from_vg (old_svg); - gdb_byte za_zeroed[za_bytes]; - memset (za_zeroed, 0, za_bytes); + gdb::byte_vector za_zeroed (za_bytes, 0); /* If the streaming vector length changed, zero out the contents of ZA in the register cache. Otherwise, we will need to update the ZA contents @@ -1007,8 +1005,7 @@ aarch64_za_regs_copy_from_reg_buf (int tid, /* When we update svg, we don't automatically initialize the ZA buffer. If we have no ZA state and the ZA register contents in the register cache are zero, just return and leave the ZA register cache contents as zero. */ - if (!has_za_state - && reg_buf->raw_compare (za_regnum, za_zeroed, 0)) + if (!has_za_state && reg_buf->raw_compare (za_regnum, za_zeroed.data (), 0)) { /* No ZA state in the thread or in the register cache. This was likely just an adjustment of the streaming vector length. Let this fall @@ -1020,7 +1017,7 @@ aarch64_za_regs_copy_from_reg_buf (int tid, need to initialize the ZA data through ptrace. First we initialize all the bytes of ZA to zero. */ if (!has_za_state - && !reg_buf->raw_compare (za_regnum, za_zeroed, 0)) + && !reg_buf->raw_compare (za_regnum, za_zeroed.data (), 0)) aarch64_initialize_za_regset (tid); /* From this point onwards, it is assumed we have a ZA payload in diff --git a/gdb/nat/fork-inferior.h b/gdb/nat/fork-inferior.h index f3e2f54..0fd4218 100644 --- a/gdb/nat/fork-inferior.h +++ b/gdb/nat/fork-inferior.h @@ -84,13 +84,12 @@ extern void gdb_flush_out_err (); /* Report an error that happened when starting to trace the inferior (i.e., when the "traceme_fun" callback is called on fork_inferior) and bail out. This function does not return. */ -extern void trace_start_error (const char *fmt, ...) - ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 2); +[[noreturn]] extern void trace_start_error (const char *fmt, ...) + ATTRIBUTE_PRINTF (1, 2); /* Like "trace_start_error", but the error message is constructed by combining STRING with the system error message for errno. This function does not return. */ -extern void trace_start_error_with_name (const char *string) - ATTRIBUTE_NORETURN; +[[noreturn]] extern void trace_start_error_with_name (const char *string); #endif /* NAT_FORK_INFERIOR_H */ diff --git a/gdb/nat/linux-btrace.c b/gdb/nat/linux-btrace.c index 5715168..59e8ae6 100644 --- a/gdb/nat/linux-btrace.c +++ b/gdb/nat/linux-btrace.c @@ -415,6 +415,59 @@ cpu_supports_bts (void) } } +/* Return the Intel PT config bitmask from the linux sysfs for a FEATURE. + The bits can be used in the perf_event configuration when enabling PT. + Callers of this function are expected to check the availability of the + feature first via linux_supports_pt_feature. */ + +static uint64_t +linux_read_pt_config_bitmask (const char *feature) +{ + uint64_t config_bitmask = 0; + std::string filename + = std::string ("/sys/bus/event_source/devices/intel_pt/format/") + + feature; + + gdb_file_up file = gdb_fopen_cloexec (filename.c_str (), "r"); + if (file.get () == nullptr) + error (_("Failed to determine config from %s."), filename.c_str ()); + + uint8_t start, end; + int found = fscanf (file.get (), "config:%hhu-%hhu", &start, &end); + if (found == 1) + end = start; + else if (found != 2) + error (_("Failed to determine config from %s."), filename.c_str ()); + + for (uint8_t i = start; i <= end; ++i) + config_bitmask |= (1ULL << i); + + return config_bitmask; +} + +/* Check whether the linux target supports the Intel PT FEATURE. */ + +static bool +linux_supports_pt_feature (const char *feature) +{ + std::string filename + = std::string ("/sys/bus/event_source/devices/intel_pt/caps/") + feature; + + gdb_file_up file = gdb_fopen_cloexec (filename.c_str (), "r"); + if (file.get () == nullptr) + return false; + + int status, found = fscanf (file.get (), "%d", &status); + if (found != 1) + { + warning (_("Failed to determine %s support from %s."), feature, + filename.c_str ()); + return false; + } + + return (status == 1); +} + /* The perf_event_open syscall failed. Try to print a helpful error message. */ @@ -627,6 +680,12 @@ linux_enable_pt (ptid_t ptid, const struct btrace_config_pt *conf) tinfo->attr.exclude_hv = 1; tinfo->attr.exclude_idle = 1; + if (conf->ptwrite && linux_supports_pt_feature ("ptwrite")) + { + tinfo->attr.config |= linux_read_pt_config_bitmask ("ptw"); + tinfo->conf.pt.ptwrite = true; + } + errno = 0; scoped_fd fd (syscall (SYS_perf_event_open, &tinfo->attr, pid, -1, -1, 0)); if (fd.get () < 0) diff --git a/gdb/nat/linux-namespaces.c b/gdb/nat/linux-namespaces.c index 36a245c..9abd3d6 100644 --- a/gdb/nat/linux-namespaces.c +++ b/gdb/nat/linux-namespaces.c @@ -548,7 +548,7 @@ mnsh_handle_readlink (int sock, const char *filename) /* The helper process. Never returns. Must be async-signal-safe. */ -static void mnsh_main (int sock) ATTRIBUTE_NORETURN; +[[noreturn]] static void mnsh_main (int sock); static void mnsh_main (int sock) diff --git a/gdb/netbsd-tdep.c b/gdb/netbsd-tdep.c index 953b329..415a743 100644 --- a/gdb/netbsd-tdep.c +++ b/gdb/netbsd-tdep.c @@ -348,9 +348,8 @@ nbsd_gdb_signal_to_target (struct gdbarch *gdbarch, static CORE_ADDR nbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc) { - struct bound_minimal_symbol msym; - - msym = lookup_minimal_symbol ("_rtld_bind_start", NULL, NULL); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, "_rtld_bind_start"); if (msym.minsym && msym.value_address () == pc) return frame_unwind_caller_pc (get_current_frame ()); else diff --git a/gdb/nto-procfs.c b/gdb/nto-procfs.c deleted file mode 100644 index c310874..0000000 --- a/gdb/nto-procfs.c +++ /dev/null @@ -1,1583 +0,0 @@ -/* Machine independent support for QNX Neutrino /proc (process file system) - for GDB. Written by Colin Burgess at QNX Software Systems Limited. - - Copyright (C) 2003-2024 Free Software Foundation, Inc. - - Contributed by QNX Software Systems Ltd. - - 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 <fcntl.h> -#include <spawn.h> -#include <sys/debug.h> -#include <sys/procfs.h> -#include <sys/neutrino.h> -#include <sys/syspage.h> -#include <dirent.h> -#include <sys/netmgr.h> -#include <sys/auxv.h> - -#include "gdbcore.h" -#include "inferior.h" -#include "target.h" -#include "objfiles.h" -#include "gdbthread.h" -#include "nto-tdep.h" -#include "command.h" -#include "regcache.h" -#include "solib.h" -#include "inf-child.h" -#include "gdbsupport/filestuff.h" -#include "gdbsupport/scoped_fd.h" - -#define NULL_PID 0 -#define _DEBUG_FLAG_TRACE (_DEBUG_FLAG_TRACE_EXEC|_DEBUG_FLAG_TRACE_RD|\ - _DEBUG_FLAG_TRACE_WR|_DEBUG_FLAG_TRACE_MODIFY) - -int ctl_fd; - -static sighandler_t ofunc; - -static procfs_run run; - -/* Create the "native" and "procfs" targets. */ - -struct nto_procfs_target : public inf_child_target -{ - void open (const char *arg, int from_tty) override; - - void attach (const char *, int) override = 0; - - void post_attach (int); - - void detach (inferior *, int) override; - - void resume (ptid_t, int, enum gdb_signal) override; - - ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override; - - void fetch_registers (struct regcache *, int) override; - void store_registers (struct regcache *, int) override; - - enum target_xfer_status xfer_partial (enum target_object object, - const char *annex, - gdb_byte *readbuf, - const gdb_byte *writebuf, - ULONGEST offset, ULONGEST len, - ULONGEST *xfered_len) override; - - void files_info () override; - - int insert_breakpoint (struct gdbarch *, struct bp_target_info *) override; - - int remove_breakpoint (struct gdbarch *, struct bp_target_info *, - enum remove_bp_reason) override; - - int can_use_hw_breakpoint (enum bptype, int, int) override; - - int insert_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override; - - int remove_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override; - - int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type, - struct expression *) override; - - int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type, - struct expression *) override; - - bool stopped_by_watchpoint () override; - - void kill () override; - - void create_inferior (const char *, const std::string &, - char **, int) override; - - void mourn_inferior () override; - - void pass_signals (gdb::array_view<const unsigned char>) override; - - bool thread_alive (ptid_t ptid) override; - - void update_thread_list () override; - - std::string pid_to_str (ptid_t) override; - - void interrupt () override; - - const char *extra_thread_info (struct thread_info *) override; - - const char *pid_to_exec_file (int pid) override; -}; - -/* For "target native". */ - -static const target_info nto_native_target_info = { - "native", - N_("QNX Neutrino local process"), - N_("QNX Neutrino local process (started by the \"run\" command).") -}; - -class nto_procfs_target_native final : public nto_procfs_target -{ - const target_info &info () const override - { return nto_native_target_info; } -}; - -/* For "target procfs <node>". */ - -static const target_info nto_procfs_target_info = { - "procfs", - N_("QNX Neutrino local or remote process"), - N_("QNX Neutrino process. target procfs NODE") -}; - -struct nto_procfs_target_procfs final : public nto_procfs_target -{ - const target_info &info () const override - { return nto_procfs_target_info; } -}; - -static ptid_t do_attach (ptid_t ptid); - -/* These two globals are only ever set in procfs_open_1, but are - referenced elsewhere. 'nto_procfs_node' is a flag used to say - whether we are local, or we should get the current node descriptor - for the remote QNX node. */ -static char *nodestr; -static unsigned nto_procfs_node = ND_LOCAL_NODE; - -/* Return the current QNX Node, or error out. This is a simple - wrapper for the netmgr_strtond() function. The reason this - is required is because QNX node descriptors are transient so - we have to re-acquire them every time. */ -static unsigned -nto_node (void) -{ - unsigned node; - - if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0 - || nodestr == NULL) - return ND_LOCAL_NODE; - - node = netmgr_strtond (nodestr, 0); - if (node == -1) - error (_("Lost the QNX node. Debug session probably over.")); - - return (node); -} - -static enum gdb_osabi -procfs_is_nto_target (bfd *abfd) -{ - return GDB_OSABI_QNXNTO; -} - -/* This is called when we call 'target native' or 'target procfs - <arg>' from the (gdb) prompt. For QNX6 (nto), the only valid arg - will be a QNX node string, eg: "/net/some_node". If arg is not a - valid QNX node, we will default to local. */ -void -nto_procfs_target::open (const char *arg, int from_tty) -{ - char *endstr; - char buffer[50]; - int total_size; - procfs_sysinfo *sysinfo; - char nto_procfs_path[PATH_MAX]; - - /* Offer to kill previous inferiors before opening this target. */ - target_preopen (from_tty); - - nto_is_nto_target = procfs_is_nto_target; - - /* Set the default node used for spawning to this one, - and only override it if there is a valid arg. */ - - xfree (nodestr); - nodestr = NULL; - - nto_procfs_node = ND_LOCAL_NODE; - nodestr = (arg != NULL) ? xstrdup (arg) : NULL; - - if (nodestr) - { - nto_procfs_node = netmgr_strtond (nodestr, &endstr); - if (nto_procfs_node == -1) - { - if (errno == ENOTSUP) - gdb_printf ("QNX Net Manager not found.\n"); - gdb_printf ("Invalid QNX node %s: error %d (%s).\n", nodestr, - errno, safe_strerror (errno)); - xfree (nodestr); - nodestr = NULL; - nto_procfs_node = ND_LOCAL_NODE; - } - else if (*endstr) - { - if (*(endstr - 1) == '/') - *(endstr - 1) = 0; - else - *endstr = 0; - } - } - snprintf (nto_procfs_path, PATH_MAX - 1, "%s%s", - (nodestr != NULL) ? nodestr : "", "/proc"); - - scoped_fd fd (open (nto_procfs_path, O_RDONLY)); - if (fd.get () == -1) - { - gdb_printf ("Error opening %s : %d (%s)\n", nto_procfs_path, errno, - safe_strerror (errno)); - error (_("Invalid procfs arg")); - } - - sysinfo = (void *) buffer; - if (devctl (fd.get (), DCMD_PROC_SYSINFO, sysinfo, sizeof buffer, 0) != EOK) - { - gdb_printf ("Error getting size: %d (%s)\n", errno, - safe_strerror (errno)); - error (_("Devctl failed.")); - } - else - { - total_size = sysinfo->total_size; - sysinfo = alloca (total_size); - if (sysinfo == NULL) - { - gdb_printf ("Memory error: %d (%s)\n", errno, - safe_strerror (errno)); - error (_("alloca failed.")); - } - else - { - if (devctl (fd.get (), DCMD_PROC_SYSINFO, sysinfo, total_size, 0) - != EOK) - { - gdb_printf ("Error getting sysinfo: %d (%s)\n", errno, - safe_strerror (errno)); - error (_("Devctl failed.")); - } - else - { - if (sysinfo->type != - nto_map_arch_to_cputype - (gdbarch_bfd_arch_info - (current_inferior ()->arch ())->arch_name)) - error (_("Invalid target CPU.")); - } - } - } - - inf_child_target::open (arg, from_tty); - gdb_printf ("Debugging using %s\n", nto_procfs_path); -} - -static void -procfs_set_thread (ptid_t ptid) -{ - pid_t tid; - - tid = ptid.tid (); - devctl (ctl_fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0); -} - -/* Return true if the thread TH is still alive. */ - -bool -nto_procfs_target::thread_alive (ptid_t ptid) -{ - pid_t tid; - pid_t pid; - procfs_status status; - int err; - - tid = ptid.tid (); - pid = ptid.pid (); - - if (kill (pid, 0) == -1) - return false; - - status.tid = tid; - if ((err = devctl (ctl_fd, DCMD_PROC_TIDSTATUS, - &status, sizeof (status), 0)) != EOK) - return false; - - /* Thread is alive or dead but not yet joined, - or dead and there is an alive (or dead unjoined) thread with - higher tid. - - If the tid is not the same as requested, requested tid is dead. */ - return (status.tid == tid) && (status.state != STATE_DEAD); -} - -static void -update_thread_private_data_name (struct thread_info *new_thread, - const char *newname) -{ - nto_thread_info *pti = get_nto_thread_info (new_thread); - - gdb_assert (newname != NULL); - gdb_assert (new_thread != NULL); - - if (pti) - { - pti = new nto_thread_info; - new_thread->priv.reset (pti); - } - - pti->name = newname; -} - -static void -update_thread_private_data (struct thread_info *new_thread, - pthread_t tid, int state, int flags) -{ - procfs_info pidinfo; - struct _thread_name *tn; - procfs_threadctl tctl; - -#if _NTO_VERSION > 630 - gdb_assert (new_thread != NULL); - - if (devctl (ctl_fd, DCMD_PROC_INFO, &pidinfo, - sizeof(pidinfo), 0) != EOK) - return; - - memset (&tctl, 0, sizeof (tctl)); - tctl.cmd = _NTO_TCTL_NAME; - tn = (struct _thread_name *) (&tctl.data); - - /* Fetch name for the given thread. */ - tctl.tid = tid; - tn->name_buf_len = sizeof (tctl.data) - sizeof (*tn); - tn->new_name_len = -1; /* Getting, not setting. */ - if (devctl (ctl_fd, DCMD_PROC_THREADCTL, &tctl, sizeof (tctl), NULL) != EOK) - tn->name_buf[0] = '\0'; - - tn->name_buf[_NTO_THREAD_NAME_MAX] = '\0'; - - update_thread_private_data_name (new_thread, tn->name_buf); - - nto_thread_info *pti = get_nto_thread_info (new_thread); - pti->tid = tid; - pti->state = state; - pti->flags = flags; -#endif /* _NTO_VERSION */ -} - -void -nto_procfs_target::update_thread_list () -{ - procfs_status status; - pid_t pid; - ptid_t ptid; - pthread_t tid; - struct thread_info *new_thread; - - if (ctl_fd == -1) - return; - - prune_threads (); - - pid = current_inferior ()->pid; - - status.tid = 1; - - for (tid = 1;; ++tid) - { - if (status.tid == tid - && (devctl (ctl_fd, DCMD_PROC_TIDSTATUS, &status, sizeof (status), 0) - != EOK)) - break; - if (status.tid != tid) - /* The reason why this would not be equal is that devctl might have - returned different tid, meaning the requested tid no longer exists - (e.g. thread exited). */ - continue; - ptid = ptid_t (pid, 0, tid); - new_thread = this->find_thread (ptid); - if (!new_thread) - new_thread = add_thread (ptid); - update_thread_private_data (new_thread, tid, status.state, 0); - status.tid++; - } - return; -} - -static void -procfs_pidlist (const char *args, int from_tty) -{ - struct dirent *dirp = NULL; - char buf[PATH_MAX]; - procfs_info *pidinfo = NULL; - procfs_debuginfo *info = NULL; - procfs_status *status = NULL; - pid_t num_threads = 0; - pid_t pid; - char name[512]; - char procfs_dir[PATH_MAX]; - - snprintf (procfs_dir, sizeof (procfs_dir), "%s%s", - (nodestr != NULL) ? nodestr : "", "/proc"); - - gdb_dir_up dp (opendir (procfs_dir)); - if (dp == NULL) - { - gdb_printf (gdb_stderr, "failed to opendir \"%s\" - %d (%s)", - procfs_dir, errno, safe_strerror (errno)); - return; - } - - /* Start scan at first pid. */ - rewinddir (dp.get ()); - - do - { - /* Get the right pid and procfs path for the pid. */ - do - { - dirp = readdir (dp.get ()); - if (dirp == NULL) - return; - snprintf (buf, sizeof (buf), "%s%s/%s/as", - (nodestr != NULL) ? nodestr : "", - "/proc", dirp->d_name); - pid = atoi (dirp->d_name); - } - while (pid == 0); - - /* Open the procfs path. */ - scoped_fd fd (open (buf, O_RDONLY)); - if (fd.get () == -1) - { - gdb_printf (gdb_stderr, "failed to open %s - %d (%s)\n", - buf, errno, safe_strerror (errno)); - continue; - } - - pidinfo = (procfs_info *) buf; - if (devctl (fd.get (), DCMD_PROC_INFO, pidinfo, sizeof (buf), 0) != EOK) - { - gdb_printf (gdb_stderr, - "devctl DCMD_PROC_INFO failed - %d (%s)\n", - errno, safe_strerror (errno)); - break; - } - num_threads = pidinfo->num_threads; - - info = (procfs_debuginfo *) buf; - if (devctl (fd.get (), DCMD_PROC_MAPDEBUG_BASE, info, sizeof (buf), 0) - != EOK) - strcpy (name, "unavailable"); - else - strcpy (name, info->path); - - /* Collect state info on all the threads. */ - status = (procfs_status *) buf; - for (status->tid = 1; status->tid <= num_threads; status->tid++) - { - const int err - = devctl (fd.get (), DCMD_PROC_TIDSTATUS, status, sizeof (buf), 0); - gdb_printf ("%s - %d", name, pid); - if (err == EOK && status->tid != 0) - gdb_printf ("/%d\n", status->tid); - else - { - gdb_printf ("\n"); - break; - } - } - } - while (dirp != NULL); -} - -static void -procfs_meminfo (const char *args, int from_tty) -{ - procfs_mapinfo *mapinfos = NULL; - static int num_mapinfos = 0; - procfs_mapinfo *mapinfo_p, *mapinfo_p2; - int flags = ~0, err, num, i, j; - - struct - { - procfs_debuginfo info; - char buff[_POSIX_PATH_MAX]; - } map; - - struct info - { - unsigned addr; - unsigned size; - unsigned flags; - unsigned debug_vaddr; - unsigned long long offset; - }; - - struct printinfo - { - unsigned long long ino; - unsigned dev; - struct info text; - struct info data; - char name[256]; - } printme; - - /* Get the number of map entrys. */ - err = devctl (ctl_fd, DCMD_PROC_MAPINFO, NULL, 0, &num); - if (err != EOK) - { - printf ("failed devctl num mapinfos - %d (%s)\n", err, - safe_strerror (err)); - return; - } - - mapinfos = XNEWVEC (procfs_mapinfo, num); - - num_mapinfos = num; - mapinfo_p = mapinfos; - - /* Fill the map entrys. */ - err = devctl (ctl_fd, DCMD_PROC_MAPINFO, mapinfo_p, num - * sizeof (procfs_mapinfo), &num); - if (err != EOK) - { - printf ("failed devctl mapinfos - %d (%s)\n", err, safe_strerror (err)); - xfree (mapinfos); - return; - } - - num = std::min (num, num_mapinfos); - - /* Run through the list of mapinfos, and store the data and text info - so we can print it at the bottom of the loop. */ - for (mapinfo_p = mapinfos, i = 0; i < num; i++, mapinfo_p++) - { - if (!(mapinfo_p->flags & flags)) - mapinfo_p->ino = 0; - - if (mapinfo_p->ino == 0) /* Already visited. */ - continue; - - map.info.vaddr = mapinfo_p->vaddr; - - err = devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0); - if (err != EOK) - continue; - - memset (&printme, 0, sizeof printme); - printme.dev = mapinfo_p->dev; - printme.ino = mapinfo_p->ino; - printme.text.addr = mapinfo_p->vaddr; - printme.text.size = mapinfo_p->size; - printme.text.flags = mapinfo_p->flags; - printme.text.offset = mapinfo_p->offset; - printme.text.debug_vaddr = map.info.vaddr; - strcpy (printme.name, map.info.path); - - /* Check for matching data. */ - for (mapinfo_p2 = mapinfos, j = 0; j < num; j++, mapinfo_p2++) - { - if (mapinfo_p2->vaddr != mapinfo_p->vaddr - && mapinfo_p2->ino == mapinfo_p->ino - && mapinfo_p2->dev == mapinfo_p->dev) - { - map.info.vaddr = mapinfo_p2->vaddr; - err = - devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0); - if (err != EOK) - continue; - - if (strcmp (map.info.path, printme.name)) - continue; - - /* Lower debug_vaddr is always text, if necessary, swap. */ - if ((int) map.info.vaddr < (int) printme.text.debug_vaddr) - { - memcpy (&(printme.data), &(printme.text), - sizeof (printme.data)); - printme.text.addr = mapinfo_p2->vaddr; - printme.text.size = mapinfo_p2->size; - printme.text.flags = mapinfo_p2->flags; - printme.text.offset = mapinfo_p2->offset; - printme.text.debug_vaddr = map.info.vaddr; - } - else - { - printme.data.addr = mapinfo_p2->vaddr; - printme.data.size = mapinfo_p2->size; - printme.data.flags = mapinfo_p2->flags; - printme.data.offset = mapinfo_p2->offset; - printme.data.debug_vaddr = map.info.vaddr; - } - mapinfo_p2->ino = 0; - } - } - mapinfo_p->ino = 0; - - gdb_printf ("%s\n", printme.name); - gdb_printf ("\ttext=%08x bytes @ 0x%08x\n", printme.text.size, - printme.text.addr); - gdb_printf ("\t\tflags=%08x\n", printme.text.flags); - gdb_printf ("\t\tdebug=%08x\n", printme.text.debug_vaddr); - gdb_printf ("\t\toffset=%s\n", phex (printme.text.offset, 8)); - if (printme.data.size) - { - gdb_printf ("\tdata=%08x bytes @ 0x%08x\n", printme.data.size, - printme.data.addr); - gdb_printf ("\t\tflags=%08x\n", printme.data.flags); - gdb_printf ("\t\tdebug=%08x\n", printme.data.debug_vaddr); - gdb_printf ("\t\toffset=%s\n", phex (printme.data.offset, 8)); - } - gdb_printf ("\tdev=0x%x\n", printme.dev); - gdb_printf ("\tino=0x%x\n", (unsigned int) printme.ino); - } - xfree (mapinfos); - return; -} - -/* Print status information about what we're accessing. */ -void -nto_procfs_target::files_info () -{ - struct inferior *inf = current_inferior (); - - gdb_printf ("\tUsing the running image of %s %s via %s.\n", - inf->attach_flag ? "attached" : "child", - target_pid_to_str (ptid_t (inf->pid)).c_str (), - (nodestr != NULL) ? nodestr : "local node"); -} - -/* Target to_pid_to_exec_file implementation. */ - -const char * -nto_procfs_target::pid_to_exec_file (const int pid) -{ - int proc_fd; - static char proc_path[PATH_MAX]; - ssize_t rd; - - /* Read exe file name. */ - snprintf (proc_path, sizeof (proc_path), "%s/proc/%d/exefile", - (nodestr != NULL) ? nodestr : "", pid); - proc_fd = open (proc_path, O_RDONLY); - if (proc_fd == -1) - return NULL; - - rd = read (proc_fd, proc_path, sizeof (proc_path) - 1); - close (proc_fd); - if (rd <= 0) - { - proc_path[0] = '\0'; - return NULL; - } - proc_path[rd] = '\0'; - return proc_path; -} - -/* Attach to process PID, then initialize for debugging it. */ -void -nto_procfs_target::attach (const char *args, int from_tty) -{ - int pid; - struct inferior *inf; - - pid = parse_pid_to_attach (args); - - if (pid == getpid ()) - error (_("Attaching GDB to itself is not a good idea...")); - - target_announce_attach (from_tty, pid); - - ptid_t ptid = do_attach (ptid_t (pid)); - inf = current_inferior (); - inferior_appeared (inf, pid); - inf->attach_flag = true; - - if (!inf->target_is_pushed (ops)) - inf->push_target (ops); - - update_thread_list (); - - switch_to_thread (this->find_thread (ptid)); -} - -void -nto_procfs_target::post_attach (pid_t pid) -{ - if (current_program_space->exec_bfd ()) - solib_create_inferior_hook (0); -} - -static ptid_t -do_attach (ptid_t ptid) -{ - procfs_status status; - struct sigevent event; - char path[PATH_MAX]; - - snprintf (path, PATH_MAX - 1, "%s%s/%d/as", - (nodestr != NULL) ? nodestr : "", "/proc", ptid.pid ()); - ctl_fd = open (path, O_RDWR); - if (ctl_fd == -1) - error (_("Couldn't open proc file %s, error %d (%s)"), path, errno, - safe_strerror (errno)); - if (devctl (ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0) != EOK) - error (_("Couldn't stop process")); - - /* Define a sigevent for process stopped notification. */ - event.sigev_notify = SIGEV_SIGNAL_THREAD; - event.sigev_signo = SIGUSR1; - event.sigev_code = 0; - event.sigev_value.sival_ptr = NULL; - event.sigev_priority = -1; - devctl (ctl_fd, DCMD_PROC_EVENT, &event, sizeof (event), 0); - - if (devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0) == EOK - && status.flags & _DEBUG_FLAG_STOPPED) - SignalKill (nto_node (), ptid.pid (), 0, SIGCONT, 0, 0); - nto_init_solib_absolute_prefix (); - return ptid_t (ptid.pid (), 0, status.tid); -} - -/* Ask the user what to do when an interrupt is received. */ -static void -interrupt_query (void) -{ - if (query (_("Interrupted while waiting for the program.\n\ -Give up (and stop debugging it)? "))) - { - target_mourn_inferior (inferior_ptid); - quit (); - } -} - -/* The user typed ^C twice. */ -static void -nto_handle_sigint_twice (int signo) -{ - signal (signo, ofunc); - interrupt_query (); - signal (signo, nto_handle_sigint_twice); -} - -static void -nto_handle_sigint (int signo) -{ - /* If this doesn't work, try more severe steps. */ - signal (signo, nto_handle_sigint_twice); - - target_interrupt (); -} - -sptid_t -nto_procfs_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, - target_wait_flags options) -{ - sigset_t set; - siginfo_t info; - procfs_status status; - static int exit_signo = 0; /* To track signals that cause termination. */ - - ourstatus->set_spurious (); - - if (inferior_ptid == null_ptid) - { - ourstatus->set_stopped (GDB_SIGNAL_0); - exit_signo = 0; - return null_ptid; - } - - sigemptyset (&set); - sigaddset (&set, SIGUSR1); - - devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); - while (!(status.flags & _DEBUG_FLAG_ISTOP)) - { - ofunc = signal (SIGINT, nto_handle_sigint); - sigwaitinfo (&set, &info); - signal (SIGINT, ofunc); - devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); - } - - nto_inferior_data (NULL)->stopped_flags = status.flags; - nto_inferior_data (NULL)->stopped_pc = status.ip; - - if (status.flags & _DEBUG_FLAG_SSTEP) - ourstatus->set_stopped (GDB_SIGNAL_TRAP); - /* Was it a breakpoint? */ - else if (status.flags & _DEBUG_FLAG_TRACE) - ourstatus->set_stopped (GDB_SIGNAL_TRAP); - else if (status.flags & _DEBUG_FLAG_ISTOP) - { - switch (status.why) - { - case _DEBUG_WHY_SIGNALLED: - ourstatus->set_stopped (gdb_signal_from_host (status.info.si_signo)); - exit_signo = 0; - break; - case _DEBUG_WHY_FAULTED: - if (status.info.si_signo == SIGTRAP) - { - ourstatus->set_stopped (0); - exit_signo = 0; - } - else - { - ourstatus->set_stopped - (gdb_signal_from_host (status.info.si_signo)); - exit_signo = ourstatus->sig (); - } - break; - - case _DEBUG_WHY_TERMINATED: - { - int waitval = 0; - - waitpid (inferior_ptid.pid (), &waitval, WNOHANG); - if (exit_signo) - { - /* Abnormal death. */ - ourstatus->set_signalled (exit_signo); - } - else - { - /* Normal death. */ - ourstatus->set_exited (WEXITSTATUS (waitval)); - } - exit_signo = 0; - break; - } - - case _DEBUG_WHY_REQUESTED: - /* We are assuming a requested stop is due to a SIGINT. */ - ourstatus->set_stopped (GDB_SIGNAL_INT); - exit_signo = 0; - break; - } - } - - return ptid_t (status.pid, 0, status.tid); -} - -/* Read the current values of the inferior's registers, both the - general register set and floating point registers (if supported) - and update gdb's idea of their current values. */ -void -nto_procfs_target::fetch_registers (struct regcache *regcache, int regno) -{ - union - { - procfs_greg greg; - procfs_fpreg fpreg; - procfs_altreg altreg; - } - reg; - int regsize; - - procfs_set_thread (regcache->ptid ()); - if (devctl (ctl_fd, DCMD_PROC_GETGREG, ®, sizeof (reg), ®size) == EOK) - nto_supply_gregset (regcache, (char *) ®.greg); - if (devctl (ctl_fd, DCMD_PROC_GETFPREG, ®, sizeof (reg), ®size) - == EOK) - nto_supply_fpregset (regcache, (char *) ®.fpreg); - if (devctl (ctl_fd, DCMD_PROC_GETALTREG, ®, sizeof (reg), ®size) - == EOK) - nto_supply_altregset (regcache, (char *) ®.altreg); -} - -/* Helper for procfs_xfer_partial that handles memory transfers. - Arguments are like target_xfer_partial. */ - -static enum target_xfer_status -procfs_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf, - ULONGEST memaddr, ULONGEST len, ULONGEST *xfered_len) -{ - int nbytes; - - if (lseek (ctl_fd, (off_t) memaddr, SEEK_SET) != (off_t) memaddr) - return TARGET_XFER_E_IO; - - if (writebuf != NULL) - nbytes = write (ctl_fd, writebuf, len); - else - nbytes = read (ctl_fd, readbuf, len); - if (nbytes <= 0) - return TARGET_XFER_E_IO; - *xfered_len = nbytes; - return TARGET_XFER_OK; -} - -/* Target to_xfer_partial implementation. */ - -enum target_xfer_status -nto_procfs_target::xfer_partial (enum target_object object, - const char *annex, gdb_byte *readbuf, - const gdb_byte *writebuf, ULONGEST offset, - ULONGEST len, ULONGEST *xfered_len) -{ - switch (object) - { - case TARGET_OBJECT_MEMORY: - return procfs_xfer_memory (readbuf, writebuf, offset, len, xfered_len); - case TARGET_OBJECT_AUXV: - if (readbuf != NULL) - { - int err; - CORE_ADDR initial_stack; - debug_process_t procinfo; - /* For 32-bit architecture, size of auxv_t is 8 bytes. */ - const unsigned int sizeof_auxv_t = sizeof (auxv_t); - const unsigned int sizeof_tempbuf = 20 * sizeof_auxv_t; - int tempread; - gdb_byte *const tempbuf = alloca (sizeof_tempbuf); - - if (tempbuf == NULL) - return TARGET_XFER_E_IO; - - err = devctl (ctl_fd, DCMD_PROC_INFO, &procinfo, - sizeof procinfo, 0); - if (err != EOK) - return TARGET_XFER_E_IO; - - initial_stack = procinfo.initial_stack; - - /* procfs is always 'self-hosted', no byte-order manipulation. */ - tempread = nto_read_auxv_from_initial_stack (initial_stack, tempbuf, - sizeof_tempbuf, - sizeof (auxv_t)); - tempread = std::min (tempread, len) - offset; - memcpy (readbuf, tempbuf + offset, tempread); - *xfered_len = tempread; - return tempread ? TARGET_XFER_OK : TARGET_XFER_EOF; - } - /* Fallthru */ - default: - return this->beneath ()->xfer_partial (object, annex, - readbuf, writebuf, offset, len, - xfered_len); - } -} - -/* Take a program previously attached to and detaches it. - The program resumes execution and will no longer stop - on signals, etc. We'd better not have left any breakpoints - in the program or it'll die when it hits one. */ -void -nto_procfs_target::detach (inferior *inf, int from_tty) -{ - target_announce_detach (); - - if (siggnal) - SignalKill (nto_node (), inf->pid, 0, 0, 0, 0); - - close (ctl_fd); - ctl_fd = -1; - - switch_to_no_thread (); - detach_inferior (inf->pid); - init_thread_list (); - inf_child_maybe_unpush_target (ops); -} - -static int -procfs_breakpoint (CORE_ADDR addr, int type, int size) -{ - procfs_break brk; - - brk.type = type; - brk.addr = addr; - brk.size = size; - errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0); - if (errno != EOK) - return 1; - return 0; -} - -int -nto_procfs_target::insert_breakpoint (struct gdbarch *gdbarch, - struct bp_target_info *bp_tgt) -{ - bp_tgt->placed_address = bp_tgt->reqstd_address; - return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, 0); -} - -int -nto_procfs_target::remove_breakpoint (struct gdbarch *gdbarch, - struct bp_target_info *bp_tgt, - enum remove_bp_reason reason) -{ - return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, -1); -} - -int -nto_procfs_target::insert_hw_breakpoint (struct gdbarch *gdbarch, - struct bp_target_info *bp_tgt) -{ - bp_tgt->placed_address = bp_tgt->reqstd_address; - return procfs_breakpoint (bp_tgt->placed_address, - _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0); -} - -int -nto_procfs_target::remove_hw_breakpoint (struct gdbarch *gdbarch, - struct bp_target_info *bp_tgt) -{ - return procfs_breakpoint (bp_tgt->placed_address, - _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1); -} - -void -nto_procfs_target::resume (ptid_t ptid, int step, enum gdb_signal signo) -{ - int signal_to_pass; - procfs_status status; - sigset_t *run_fault = (sigset_t *) (void *) &run.fault; - - if (inferior_ptid == null_ptid) - return; - - procfs_set_thread (ptid == minus_one_ptid ? inferior_ptid : - ptid); - - run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE; - if (step) - run.flags |= _DEBUG_RUN_STEP; - - sigemptyset (run_fault); - sigaddset (run_fault, FLTBPT); - sigaddset (run_fault, FLTTRACE); - sigaddset (run_fault, FLTILL); - sigaddset (run_fault, FLTPRIV); - sigaddset (run_fault, FLTBOUNDS); - sigaddset (run_fault, FLTIOVF); - sigaddset (run_fault, FLTIZDIV); - sigaddset (run_fault, FLTFPE); - /* Peter V will be changing this at some point. */ - sigaddset (run_fault, FLTPAGE); - - run.flags |= _DEBUG_RUN_ARM; - - signal_to_pass = gdb_signal_to_host (signo); - - if (signal_to_pass) - { - devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); - signal_to_pass = gdb_signal_to_host (signo); - if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED)) - { - if (signal_to_pass != status.info.si_signo) - { - SignalKill (nto_node (), inferior_ptid.pid (), 0, - signal_to_pass, 0, 0); - run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG; - } - else /* Let it kill the program without telling us. */ - sigdelset (&run.trace, signal_to_pass); - } - } - else - run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT; - - errno = devctl (ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0); - if (errno != EOK) - { - perror (_("run error!\n")); - return; - } -} - -void -nto_procfs_target::mourn_inferior () -{ - if (inferior_ptid != null_ptid) - { - SignalKill (nto_node (), inferior_ptid.pid (), 0, SIGKILL, 0, 0); - close (ctl_fd); - } - switch_to_no_thread (); - init_thread_list (); - inf_child_mourn_inferior (ops); -} - -/* This function breaks up an argument string into an argument - vector suitable for passing to execvp(). - E.g., on "run a b c d" this routine would get as input - the string "a b c d", and as output it would fill in argv with - the four arguments "a", "b", "c", "d". The only additional - functionality is simple quoting. The gdb command: - run a "b c d" f - will fill in argv with the three args "a", "b c d", "e". */ -static void -breakup_args (char *scratch, char **argv) -{ - char *pp, *cp = scratch; - char quoting = 0; - - for (;;) - { - /* Scan past leading separators. */ - quoting = 0; - while (*cp == ' ' || *cp == '\t' || *cp == '\n') - cp++; - - /* Break if at end of string. */ - if (*cp == '\0') - break; - - /* Take an arg. */ - if (*cp == '"') - { - cp++; - quoting = strchr (cp, '"') ? 1 : 0; - } - - *argv++ = cp; - - /* Scan for next arg separator. */ - pp = cp; - if (quoting) - cp = strchr (pp, '"'); - if ((cp == NULL) || (!quoting)) - cp = strchr (pp, ' '); - if (cp == NULL) - cp = strchr (pp, '\t'); - if (cp == NULL) - cp = strchr (pp, '\n'); - - /* No separators => end of string => break. */ - if (cp == NULL) - { - pp = cp; - break; - } - - /* Replace the separator with a terminator. */ - *cp++ = '\0'; - } - - /* Execv requires a null-terminated arg vector. */ - *argv = NULL; -} - -void -nto_procfs_target::create_inferior (const char *exec_file, - const std::string &allargs, - char **env, int from_tty) -{ - if (exec_file == nullptr) - no_executable_specified_error (); - - struct inheritance inherit; - pid_t pid; - int flags, errn; - char **argv, *args; - const char *in = "", *out = "", *err = ""; - int fd, fds[3]; - sigset_t set; - struct inferior *inf; - - argv = xmalloc ((allargs.size () / (unsigned) 2 + 2) * - sizeof (*argv)); - argv[0] = exec_file; - args = xstrdup (allargs.c_str ()); - breakup_args (args, &argv[1]); - - argv = nto_parse_redirection (argv, &in, &out, &err); - - fds[0] = STDIN_FILENO; - fds[1] = STDOUT_FILENO; - fds[2] = STDERR_FILENO; - - /* If the user specified I/O via gdb's --tty= arg, use it, but only - if the i/o is not also being specified via redirection. */ - const char *inferior_tty = current_inferior ()->tty (); - if (inferior_tty != nullptr) - { - if (!in[0]) - in = inferior_tty; - if (!out[0]) - out = inferior_tty; - if (!err[0]) - err = inferior_tty; - } - - if (in[0]) - { - fd = open (in, O_RDONLY); - if (fd == -1) - perror (in); - else - fds[0] = fd; - } - if (out[0]) - { - fd = open (out, O_WRONLY); - if (fd == -1) - perror (out); - else - fds[1] = fd; - } - if (err[0]) - { - fd = open (err, O_WRONLY); - if (fd == -1) - perror (err); - else - fds[2] = fd; - } - - /* Clear any pending SIGUSR1's but keep the behavior the same. */ - signal (SIGUSR1, signal (SIGUSR1, SIG_IGN)); - - sigemptyset (&set); - sigaddset (&set, SIGUSR1); - sigprocmask (SIG_UNBLOCK, &set, NULL); - - memset (&inherit, 0, sizeof (inherit)); - - if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) != 0) - { - inherit.nd = nto_node (); - inherit.flags |= SPAWN_SETND; - inherit.flags &= ~SPAWN_EXEC; - } - inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD; - inherit.pgroup = SPAWN_NEWPGROUP; - pid = spawnp (argv[0], 3, fds, &inherit, argv, - ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0 ? env : 0); - xfree (args); - - sigprocmask (SIG_BLOCK, &set, NULL); - - if (pid == -1) - error (_("Error spawning %s: %d (%s)"), argv[0], errno, - safe_strerror (errno)); - - if (fds[0] != STDIN_FILENO) - close (fds[0]); - if (fds[1] != STDOUT_FILENO) - close (fds[1]); - if (fds[2] != STDERR_FILENO) - close (fds[2]); - - ptid_t ptid = do_attach (ptid_t (pid)); - update_thread_list (); - switch_to_thread (this->find_thread (ptid)); - - inf = current_inferior (); - inferior_appeared (inf, pid); - inf->attach_flag = false; - - flags = _DEBUG_FLAG_KLC; /* Kill-on-Last-Close flag. */ - errn = devctl (ctl_fd, DCMD_PROC_SET_FLAG, &flags, sizeof (flags), 0); - if (errn != EOK) - { - /* FIXME: expected warning? */ - /* warning( "Failed to set Kill-on-Last-Close flag: errno = %d(%s)\n", - errn, safe_strerror(errn) ); */ - } - if (!inf->target_is_pushed (ops)) - inf->push_target (ops); - target_terminal::init (); - - if (current_program_space->exec_bfd () != NULL - || (current_program_space->symfile_object_file != NULL - && current_program_space->symfile_object_file->obfd != NULL)) - solib_create_inferior_hook (0); -} - -void -nto_procfs_target::interrupt () -{ - devctl (ctl_fd, DCMD_PROC_STOP, NULL, 0, 0); -} - -void -nto_procfs_target::kill () -{ - target_mourn_inferior (inferior_ptid); -} - -/* Fill buf with regset and return devctl cmd to do the setting. Return - -1 if we fail to get the regset. Store size of regset in regsize. */ -static int -get_regset (int regset, char *buf, int bufsize, int *regsize) -{ - int dev_get, dev_set; - switch (regset) - { - case NTO_REG_GENERAL: - dev_get = DCMD_PROC_GETGREG; - dev_set = DCMD_PROC_SETGREG; - break; - - case NTO_REG_FLOAT: - dev_get = DCMD_PROC_GETFPREG; - dev_set = DCMD_PROC_SETFPREG; - break; - - case NTO_REG_ALT: - dev_get = DCMD_PROC_GETALTREG; - dev_set = DCMD_PROC_SETALTREG; - break; - - case NTO_REG_SYSTEM: - default: - return -1; - } - if (devctl (ctl_fd, dev_get, buf, bufsize, regsize) != EOK) - return -1; - - return dev_set; -} - -void -nto_procfs_target::store_registers (struct regcache *regcache, int regno) -{ - union - { - procfs_greg greg; - procfs_fpreg fpreg; - procfs_altreg altreg; - } - reg; - unsigned off; - int len, regset, regsize, dev_set, err; - char *data; - ptid_t ptid = regcache->ptid (); - - if (ptid == null_ptid) - return; - procfs_set_thread (ptid); - - if (regno == -1) - { - for (regset = NTO_REG_GENERAL; regset < NTO_REG_END; regset++) - { - dev_set = get_regset (regset, (char *) ®, - sizeof (reg), ®size); - if (dev_set == -1) - continue; - - if (nto_regset_fill (regcache, regset, (char *) ®) == -1) - continue; - - err = devctl (ctl_fd, dev_set, ®, regsize, 0); - if (err != EOK) - gdb_printf (gdb_stderr, - "Warning unable to write regset %d: %s\n", - regno, safe_strerror (err)); - } - } - else - { - regset = nto_regset_id (regno); - if (regset == -1) - return; - - dev_set = get_regset (regset, (char *) ®, sizeof (reg), ®size); - if (dev_set == -1) - return; - - len = nto_register_area (regcache->arch (), - regno, regset, &off); - - if (len < 1) - return; - - regcache->raw_collect (regno, (char *) ® + off); - - err = devctl (ctl_fd, dev_set, ®, regsize, 0); - if (err != EOK) - gdb_printf (gdb_stderr, - "Warning unable to write regset %d: %s\n", regno, - safe_strerror (err)); - } -} - -/* Set list of signals to be handled in the target. */ - -void -nto_procfs_target::pass_signals - (gdb::array_view<const unsigned char> pass_signals) -{ - int signo; - - sigfillset (&run.trace); - - for (signo = 1; signo < NSIG; signo++) - { - int target_signo = gdb_signal_from_host (signo); - if (target_signo < pass_signals.size () && pass_signals[target_signo]) - sigdelset (&run.trace, signo); - } -} - -std::string -nto_procfs_target::pid_to_str (ptid_t ptid) -{ - int pid, tid; - struct tidinfo *tip; - - pid = ptid.pid (); - tid = ptid.tid (); - -#if 0 /* NYI */ - tip = procfs_thread_info (pid, tid); - if (tip != NULL) - snprintf (&buf[n], 1023, " (state = 0x%02x)", tip->state); -#endif - - return string_printf ("process %d", pid); -} - -/* to_can_run implementation for "target procfs". Note this really - means "can this target be the default run target", which there can - be only one, and we make it be "target native" like other ports. - "target procfs <node>" wouldn't make sense as default run target, as - it needs <node>. */ - -int -nto_procfs_target::can_run () -{ - return 0; -} - -/* "target procfs". */ -static nto_procfs_target_procfs nto_procfs_ops; - -/* "target native". */ -static nto_procfs_target_native nto_native_ops; - -/* Create the "native" and "procfs" targets. */ - -static void -init_procfs_targets (void) -{ - /* Register "target native". This is the default run target. */ - add_target (nto_native_target_info, inf_child_open_target); - set_native_target (&nto_native_ops); - - /* Register "target procfs <node>". */ - add_target (nto_procfs_target_info, inf_child_open_target); -} - -#define OSTYPE_NTO 1 - -void _initialize_procfs (); -void -_initialize_procfs () -{ - sigset_t set; - - init_procfs_targets (); - - /* We use SIGUSR1 to gain control after we block waiting for a process. - We use sigwaitevent to wait. */ - sigemptyset (&set); - sigaddset (&set, SIGUSR1); - sigprocmask (SIG_BLOCK, &set, NULL); - - /* Initially, make sure all signals are reported. */ - sigfillset (&run.trace); - - /* Stuff some information. */ - nto_cpuinfo_flags = SYSPAGE_ENTRY (cpuinfo)->flags; - nto_cpuinfo_valid = 1; - - add_info ("pidlist", procfs_pidlist, _("pidlist")); - add_info ("meminfo", procfs_meminfo, _("memory information")); - - nto_is_nto_target = procfs_is_nto_target; -} - - -static int -procfs_hw_watchpoint (int addr, int len, enum target_hw_bp_type type) -{ - procfs_break brk; - - switch (type) - { - case hw_read: - brk.type = _DEBUG_BREAK_RD; - break; - case hw_access: - brk.type = _DEBUG_BREAK_RW; - break; - default: /* Modify. */ -/* FIXME: brk.type = _DEBUG_BREAK_RWM gives EINVAL for some reason. */ - brk.type = _DEBUG_BREAK_RW; - } - brk.type |= _DEBUG_BREAK_HW; /* Always ask for HW. */ - brk.addr = addr; - brk.size = len; - - errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0); - if (errno != EOK) - { - perror (_("Failed to set hardware watchpoint")); - return -1; - } - return 0; -} - -bool -nto_procfs_target::can_use_hw_breakpoint (enum bptype type, - int cnt, int othertype) -{ - return 1; -} - -int -nto_procfs_target::remove_hw_watchpoint (CORE_ADDR addr, int len, - enum target_hw_bp_type type, - struct expression *cond) -{ - return procfs_hw_watchpoint (addr, -1, type); -} - -int -nto_procfs_target::insert_hw_watchpoint (CORE_ADDR addr, int len, - enum target_hw_bp_type type, - struct expression *cond) -{ - return procfs_hw_watchpoint (addr, len, type); -} - -bool -nto_procfs_target::stopped_by_watchpoint () -{ - /* NOTE: nto_stopped_by_watchpoint will be called ONLY while we are - stopped due to a SIGTRAP. This assumes gdb works in 'all-stop' mode; - future gdb versions will likely run in 'non-stop' mode in which case - we will have to store/examine statuses per thread in question. - Until then, this will work fine. */ - - struct inferior *inf = current_inferior (); - struct nto_inferior_data *inf_data; - - gdb_assert (inf != NULL); - - inf_data = nto_inferior_data (inf); - - return inf_data->stopped_flags - & (_DEBUG_FLAG_TRACE_RD - | _DEBUG_FLAG_TRACE_WR - | _DEBUG_FLAG_TRACE_MODIFY); -} diff --git a/gdb/nto-tdep.c b/gdb/nto-tdep.c deleted file mode 100644 index eeef52db..0000000 --- a/gdb/nto-tdep.c +++ /dev/null @@ -1,521 +0,0 @@ -/* nto-tdep.c - general QNX Neutrino target functionality. - - Copyright (C) 2003-2024 Free Software Foundation, Inc. - - Contributed by QNX Software Systems Ltd. - - 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 <sys/stat.h> -#include "nto-tdep.h" -#include "extract-store-integer.h" -#include "top.h" -#include "inferior.h" -#include "infrun.h" -#include "gdbarch.h" -#include "bfd.h" -#include "elf-bfd.h" -#include "solib-svr4.h" -#include "gdbcore.h" -#include "objfiles.h" -#include "source.h" -#include "gdbsupport/pathstuff.h" - -#define QNX_NOTE_NAME "QNX" -#define QNX_INFO_SECT_NAME "QNX_info" - -#ifdef __CYGWIN__ -#include <sys/cygwin.h> -#endif - -#ifdef __CYGWIN__ -static char default_nto_target[] = "C:\\QNXsdk\\target\\qnx6"; -#elif defined(__sun__) || defined(linux) -static char default_nto_target[] = "/opt/QNXsdk/target/qnx6"; -#else -static char default_nto_target[] = ""; -#endif - -struct nto_target_ops current_nto_target; - -static const registry<inferior>::key<struct nto_inferior_data> - nto_inferior_data_reg; - -static char * -nto_target (void) -{ - char *p = getenv ("QNX_TARGET"); - -#ifdef __CYGWIN__ - static char buf[PATH_MAX]; - if (p) - cygwin_conv_path (CCP_WIN_A_TO_POSIX, p, buf, PATH_MAX); - else - cygwin_conv_path (CCP_WIN_A_TO_POSIX, default_nto_target, buf, PATH_MAX); - return buf; -#else - return p ? p : default_nto_target; -#endif -} - -/* Take a string such as i386, rs6000, etc. and map it onto CPUTYPE_X86, - CPUTYPE_PPC, etc. as defined in nto-share/dsmsgs.h. */ -int -nto_map_arch_to_cputype (const char *arch) -{ - if (!strcmp (arch, "i386") || !strcmp (arch, "x86")) - return CPUTYPE_X86; - if (!strcmp (arch, "rs6000") || !strcmp (arch, "powerpc")) - return CPUTYPE_PPC; - if (!strcmp (arch, "mips")) - return CPUTYPE_MIPS; - if (!strcmp (arch, "arm")) - return CPUTYPE_ARM; - if (!strcmp (arch, "sh")) - return CPUTYPE_SH; - return CPUTYPE_UNKNOWN; -} - -int -nto_find_and_open_solib (const char *solib, unsigned o_flags, - gdb::unique_xmalloc_ptr<char> *temp_pathname) -{ - char *buf, *arch_path, *nto_root; - const char *endian; - const char *base; - const char *arch; - int arch_len, len, ret; -#define PATH_FMT \ - "%s/lib:%s/usr/lib:%s/usr/photon/lib:%s/usr/photon/dll:%s/lib/dll" - - nto_root = nto_target (); - gdbarch *gdbarch = current_inferior ()->arch (); - if (strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name, "i386") == 0) - { - arch = "x86"; - endian = ""; - } - else if (strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name, - "rs6000") == 0 - || strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name, - "powerpc") == 0) - { - arch = "ppc"; - endian = "be"; - } - else - { - arch = gdbarch_bfd_arch_info (gdbarch)->arch_name; - endian = gdbarch_byte_order (gdbarch) - == BFD_ENDIAN_BIG ? "be" : "le"; - } - - /* In case nto_root is short, add strlen(solib) - so we can reuse arch_path below. */ - - arch_len = (strlen (nto_root) + strlen (arch) + strlen (endian) + 2 - + strlen (solib)); - arch_path = (char *) alloca (arch_len); - xsnprintf (arch_path, arch_len, "%s/%s%s", nto_root, arch, endian); - - len = strlen (PATH_FMT) + strlen (arch_path) * 5 + 1; - buf = (char *) alloca (len); - xsnprintf (buf, len, PATH_FMT, arch_path, arch_path, arch_path, arch_path, - arch_path); - - base = lbasename (solib); - ret = openp (buf, OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, base, o_flags, - temp_pathname); - if (ret < 0 && base != solib) - { - xsnprintf (arch_path, arch_len, "/%s", solib); - ret = open (arch_path, o_flags, 0); - if (temp_pathname) - { - if (ret >= 0) - *temp_pathname = gdb_realpath (arch_path); - else - temp_pathname->reset (NULL); - } - } - return ret; -} - -void -nto_init_solib_absolute_prefix (void) -{ - char buf[PATH_MAX * 2], arch_path[PATH_MAX]; - char *nto_root; - const char *endian; - const char *arch; - - nto_root = nto_target (); - gdbarch *gdbarch = current_inferior ()->arch (); - if (strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name, "i386") == 0) - { - arch = "x86"; - endian = ""; - } - else if (strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name, - "rs6000") == 0 - || strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name, - "powerpc") == 0) - { - arch = "ppc"; - endian = "be"; - } - else - { - arch = gdbarch_bfd_arch_info (gdbarch)->arch_name; - endian = gdbarch_byte_order (gdbarch) - == BFD_ENDIAN_BIG ? "be" : "le"; - } - - xsnprintf (arch_path, sizeof (arch_path), "%s/%s%s", nto_root, arch, endian); - - xsnprintf (buf, sizeof (buf), "set solib-absolute-prefix %s", arch_path); - execute_command (buf, 0); -} - -char ** -nto_parse_redirection (char *pargv[], const char **pin, const char **pout, - const char **perr) -{ - char **argv; - const char *in, *out, *err, *p; - int argc, i, n; - - for (n = 0; pargv[n]; n++); - if (n == 0) - return NULL; - in = ""; - out = ""; - err = ""; - - argv = XCNEWVEC (char *, n + 1); - argc = n; - for (i = 0, n = 0; n < argc; n++) - { - p = pargv[n]; - if (*p == '>') - { - p++; - if (*p) - out = p; - else - out = pargv[++n]; - } - else if (*p == '<') - { - p++; - if (*p) - in = p; - else - in = pargv[++n]; - } - else if (*p++ == '2' && *p++ == '>') - { - if (*p == '&' && *(p + 1) == '1') - err = out; - else if (*p) - err = p; - else - err = pargv[++n]; - } - else - argv[i++] = pargv[n]; - } - *pin = in; - *pout = out; - *perr = err; - return argv; -} - -static CORE_ADDR -lm_addr (const solib &so) -{ - auto *li = gdb::checked_static_cast<const lm_info_svr4 *> (so.lm_info.get ()); - - return li->l_addr; -} - -static CORE_ADDR -nto_truncate_ptr (CORE_ADDR addr) -{ - gdbarch *gdbarch = current_inferior ()->arch (); - if (gdbarch_ptr_bit (gdbarch) == sizeof (CORE_ADDR) * 8) - /* We don't need to truncate anything, and the bit twiddling below - will fail due to overflow problems. */ - return addr; - else - return addr & (((CORE_ADDR) 1 << gdbarch_ptr_bit (gdbarch)) - 1); -} - -static Elf_Internal_Phdr * -find_load_phdr (bfd *abfd) -{ - Elf_Internal_Phdr *phdr; - unsigned int i; - - if (!elf_tdata (abfd)) - return NULL; - - phdr = elf_tdata (abfd)->phdr; - for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++) - { - if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X)) - return phdr; - } - return NULL; -} - -void -nto_relocate_section_addresses (solib &so, target_section *sec) -{ - /* Neutrino treats the l_addr base address field in link.h as different than - the base address in the System V ABI and so the offset needs to be - calculated and applied to relocations. */ - Elf_Internal_Phdr *phdr = find_load_phdr (sec->the_bfd_section->owner); - unsigned vaddr = phdr ? phdr->p_vaddr : 0; - - sec->addr = nto_truncate_ptr (sec->addr + lm_addr (so) - vaddr); - sec->endaddr = nto_truncate_ptr (sec->endaddr + lm_addr (so) - vaddr); -} - -/* This is cheating a bit because our linker code is in libc.so. If we - ever implement lazy linking, this may need to be re-examined. */ -int -nto_in_dynsym_resolve_code (CORE_ADDR pc) -{ - if (in_plt_section (pc)) - return 1; - return 0; -} - -void -nto_dummy_supply_regset (struct regcache *regcache, char *regs) -{ - /* Do nothing. */ -} - -static void -nto_sniff_abi_note_section (bfd *abfd, asection *sect, void *obj) -{ - const char *sectname; - unsigned int sectsize; - /* Buffer holding the section contents. */ - char *note; - unsigned int namelen; - const char *name; - const unsigned sizeof_Elf_Nhdr = 12; - - sectname = bfd_section_name (sect); - sectsize = bfd_section_size (sect); - - if (sectsize > 128) - sectsize = 128; - - if (sectname != NULL && strstr (sectname, QNX_INFO_SECT_NAME) != NULL) - *(enum gdb_osabi *) obj = GDB_OSABI_QNXNTO; - else if (sectname != NULL && strstr (sectname, "note") != NULL - && sectsize > sizeof_Elf_Nhdr) - { - note = XNEWVEC (char, sectsize); - bfd_get_section_contents (abfd, sect, note, 0, sectsize); - namelen = (unsigned int) bfd_h_get_32 (abfd, note); - name = note + sizeof_Elf_Nhdr; - if (sectsize >= namelen + sizeof_Elf_Nhdr - && namelen == sizeof (QNX_NOTE_NAME) - && 0 == strcmp (name, QNX_NOTE_NAME)) - *(enum gdb_osabi *) obj = GDB_OSABI_QNXNTO; - - XDELETEVEC (note); - } -} - -enum gdb_osabi -nto_elf_osabi_sniffer (bfd *abfd) -{ - enum gdb_osabi osabi = GDB_OSABI_UNKNOWN; - - bfd_map_over_sections (abfd, - nto_sniff_abi_note_section, - &osabi); - - return osabi; -} - -static const char * const nto_thread_state_str[] = -{ - "DEAD", /* 0 0x00 */ - "RUNNING", /* 1 0x01 */ - "READY", /* 2 0x02 */ - "STOPPED", /* 3 0x03 */ - "SEND", /* 4 0x04 */ - "RECEIVE", /* 5 0x05 */ - "REPLY", /* 6 0x06 */ - "STACK", /* 7 0x07 */ - "WAITTHREAD", /* 8 0x08 */ - "WAITPAGE", /* 9 0x09 */ - "SIGSUSPEND", /* 10 0x0a */ - "SIGWAITINFO", /* 11 0x0b */ - "NANOSLEEP", /* 12 0x0c */ - "MUTEX", /* 13 0x0d */ - "CONDVAR", /* 14 0x0e */ - "JOIN", /* 15 0x0f */ - "INTR", /* 16 0x10 */ - "SEM", /* 17 0x11 */ - "WAITCTX", /* 18 0x12 */ - "NET_SEND", /* 19 0x13 */ - "NET_REPLY" /* 20 0x14 */ -}; - -const char * -nto_extra_thread_info (struct target_ops *self, struct thread_info *ti) -{ - if (ti != NULL && ti->priv != NULL) - { - nto_thread_info *priv = get_nto_thread_info (ti); - - if (priv->state < ARRAY_SIZE (nto_thread_state_str)) - return nto_thread_state_str [priv->state]; - } - return ""; -} - -void -nto_initialize_signals (void) -{ - /* We use SIG45 for pulses, or something, so nostop, noprint - and pass them. */ - signal_stop_update (gdb_signal_from_name ("SIG45"), 0); - signal_print_update (gdb_signal_from_name ("SIG45"), 0); - signal_pass_update (gdb_signal_from_name ("SIG45"), 1); - - /* By default we don't want to stop on these two, but we do want to pass. */ -#if defined(SIGSELECT) - signal_stop_update (SIGSELECT, 0); - signal_print_update (SIGSELECT, 0); - signal_pass_update (SIGSELECT, 1); -#endif - -#if defined(SIGPHOTON) - signal_stop_update (SIGPHOTON, 0); - signal_print_update (SIGPHOTON, 0); - signal_pass_update (SIGPHOTON, 1); -#endif -} - -/* Read AUXV from initial_stack. */ -LONGEST -nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack, gdb_byte *readbuf, - LONGEST len, size_t sizeof_auxv_t) -{ - gdb_byte targ32[4]; /* For 32 bit target values. */ - gdb_byte targ64[8]; /* For 64 bit target values. */ - CORE_ADDR data_ofs = 0; - ULONGEST anint; - LONGEST len_read = 0; - gdb_byte *buff; - enum bfd_endian byte_order; - int ptr_size; - - if (sizeof_auxv_t == 16) - ptr_size = 8; - else - ptr_size = 4; - - /* Skip over argc, argv and envp... Comment from ldd.c: - - The startup frame is set-up so that we have: - auxv - NULL - ... - envp2 - envp1 <----- void *frame + (argc + 2) * sizeof(char *) - NULL - ... - argv2 - argv1 - argc <------ void * frame - - On entry to ldd, frame gives the address of argc on the stack. */ - /* Read argc. 4 bytes on both 64 and 32 bit arches and luckily little - * endian. So we just read first 4 bytes. */ - if (target_read_memory (initial_stack + data_ofs, targ32, 4) != 0) - return 0; - - byte_order = gdbarch_byte_order (current_inferior ()->arch ()); - - anint = extract_unsigned_integer (targ32, sizeof (targ32), byte_order); - - /* Size of pointer is assumed to be 4 bytes (32 bit arch.) */ - data_ofs += (anint + 2) * ptr_size; /* + 2 comes from argc itself and - NULL terminating pointer in - argv. */ - - /* Now loop over env table: */ - anint = 0; - while (target_read_memory (initial_stack + data_ofs, targ64, ptr_size) - == 0) - { - if (extract_unsigned_integer (targ64, ptr_size, byte_order) == 0) - anint = 1; /* Keep looping until non-null entry is found. */ - else if (anint) - break; - data_ofs += ptr_size; - } - initial_stack += data_ofs; - - memset (readbuf, 0, len); - buff = readbuf; - while (len_read <= len-sizeof_auxv_t) - { - if (target_read_memory (initial_stack + len_read, buff, sizeof_auxv_t) - == 0) - { - /* Both 32 and 64 bit structures have int as the first field. */ - const ULONGEST a_type - = extract_unsigned_integer (buff, sizeof (targ32), byte_order); - - if (a_type == AT_NULL) - break; - buff += sizeof_auxv_t; - len_read += sizeof_auxv_t; - } - else - break; - } - return len_read; -} - -/* Return nto_inferior_data for the given INFERIOR. If not yet created, - construct it. */ - -struct nto_inferior_data * -nto_inferior_data (struct inferior *const inferior) -{ - struct inferior *const inf = inferior ? inferior : current_inferior (); - struct nto_inferior_data *inf_data; - - gdb_assert (inf != NULL); - - inf_data = nto_inferior_data_reg.get (inf); - if (inf_data == NULL) - inf_data = nto_inferior_data_reg.emplace (inf); - - return inf_data; -} diff --git a/gdb/nto-tdep.h b/gdb/nto-tdep.h deleted file mode 100644 index 249a4f6..0000000 --- a/gdb/nto-tdep.h +++ /dev/null @@ -1,194 +0,0 @@ -/* nto-tdep.h - QNX Neutrino target header. - - Copyright (C) 2003-2024 Free Software Foundation, Inc. - - Contributed by QNX Software Systems Ltd. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#ifndef NTO_TDEP_H -#define NTO_TDEP_H - -#include "solist.h" -#include "osabi.h" -#include "regset.h" -#include "gdbthread.h" -#include "gdbsupport/gdb-checked-static-cast.h" - -/* Target operations defined for Neutrino targets (<target>-nto-tdep.c). */ - -struct nto_target_ops -{ -/* The CPUINFO flags from the remote. Currently used by - i386 for fxsave but future proofing other hosts. - This is initialized in procfs_attach or nto_start_remote - depending on our host/target. It would only be invalid - if we were talking to an older pdebug which didn't support - the cpuinfo message. */ - unsigned cpuinfo_flags; - -/* True if successfully retrieved cpuinfo from remote. */ - int cpuinfo_valid; - -/* Given a register, return an id that represents the Neutrino - regset it came from. If reg == -1 update all regsets. */ - int (*regset_id) (int); - - void (*supply_gregset) (struct regcache *, char *); - - void (*supply_fpregset) (struct regcache *, char *); - - void (*supply_altregset) (struct regcache *, char *); - -/* Given a regset, tell gdb about registers stored in data. */ - void (*supply_regset) (struct regcache *, int, char *); - -/* Given a register and regset, calculate the offset into the regset - and stuff it into the last argument. If regno is -1, calculate the - size of the entire regset. Returns length of data, -1 if unknown - regset, 0 if unknown register. */ - int (*register_area) (struct gdbarch *, int, int, unsigned *); - -/* Build the Neutrino register set info into the data buffer. - Return -1 if unknown regset, 0 otherwise. */ - int (*regset_fill) (const struct regcache *, int, char *); - -/* Gives the fetch_link_map_offsets function exposure outside of - solib-svr4.c so that we can override relocate_section_addresses(). */ - struct link_map_offsets *(*fetch_link_map_offsets) (void); - -/* Used by nto_elf_osabi_sniffer to determine if we're connected to an - Neutrino target. */ - enum gdb_osabi (*is_nto_target) (bfd *abfd); -}; - -extern struct nto_target_ops current_nto_target; - -#define nto_cpuinfo_flags (current_nto_target.cpuinfo_flags) - -#define nto_cpuinfo_valid (current_nto_target.cpuinfo_valid) - -#define nto_regset_id (current_nto_target.regset_id) - -#define nto_supply_gregset (current_nto_target.supply_gregset) - -#define nto_supply_fpregset (current_nto_target.supply_fpregset) - -#define nto_supply_altregset (current_nto_target.supply_altregset) - -#define nto_supply_regset (current_nto_target.supply_regset) - -#define nto_register_area (current_nto_target.register_area) - -#define nto_regset_fill (current_nto_target.regset_fill) - -#define nto_fetch_link_map_offsets \ -(current_nto_target.fetch_link_map_offsets) - -#define nto_is_nto_target (current_nto_target.is_nto_target) - -/* Keep this consistant with neutrino syspage.h. */ -enum -{ - CPUTYPE_X86, - CPUTYPE_PPC, - CPUTYPE_MIPS, - CPUTYPE_SPARE, - CPUTYPE_ARM, - CPUTYPE_SH, - CPUTYPE_UNKNOWN -}; - -enum -{ - OSTYPE_QNX4, - OSTYPE_NTO -}; - -/* These correspond to the DSMSG_* versions in dsmsgs.h. */ -enum -{ - NTO_REG_GENERAL, - NTO_REG_FLOAT, - NTO_REG_SYSTEM, - NTO_REG_ALT, - NTO_REG_END -}; - -typedef char qnx_reg64[8]; - -typedef struct _debug_regs -{ - qnx_reg64 padding[1024]; -} nto_regset_t; - -struct nto_thread_info : public private_thread_info -{ - short tid = 0; - unsigned char state = 0; - unsigned char flags = 0; - std::string name; -}; - -static inline nto_thread_info * -get_nto_thread_info (thread_info *thread) -{ - return gdb::checked_static_cast<nto_thread_info *> (thread->priv.get ()); -} - -/* Per-inferior data, common for both procfs and remote. */ -struct nto_inferior_data -{ - /* Last stopped flags result from wait function */ - unsigned int stopped_flags = 0; - - /* Last known stopped PC */ - CORE_ADDR stopped_pc = 0; -}; - -/* Generic functions in nto-tdep.c. */ - -void nto_init_solib_absolute_prefix (void); - -char **nto_parse_redirection (char *start_argv[], const char **in, - const char **out, const char **err); - -void nto_relocate_section_addresses (solib &, target_section *); - -int nto_map_arch_to_cputype (const char *); - -int nto_find_and_open_solib (const char *, unsigned, - gdb::unique_xmalloc_ptr<char> *); - -enum gdb_osabi nto_elf_osabi_sniffer (bfd *abfd); - -void nto_initialize_signals (void); - -/* Dummy function for initializing nto_target_ops on targets which do - not define a particular regset. */ -void nto_dummy_supply_regset (struct regcache *regcache, char *regs); - -int nto_in_dynsym_resolve_code (CORE_ADDR pc); - -const char *nto_extra_thread_info (struct target_ops *self, struct thread_info *); - -LONGEST nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack, - gdb_byte *readbuf, - LONGEST len, size_t sizeof_auxv_t); - -struct nto_inferior_data *nto_inferior_data (struct inferior *inf); - -#endif /* NTO_TDEP_H */ diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c index 3655445..cf78979 100644 --- a/gdb/objc-lang.c +++ b/gdb/objc-lang.c @@ -120,9 +120,11 @@ lookup_objc_class (struct gdbarch *gdbarch, const char *classname) return 0; } - if (lookup_minimal_symbol("objc_lookUpClass", 0, 0).minsym) + if (lookup_minimal_symbol (current_program_space, + "objc_lookUpClass").minsym != nullptr) function = find_function_in_inferior("objc_lookUpClass", NULL); - else if (lookup_minimal_symbol ("objc_lookup_class", 0, 0).minsym) + else if (lookup_minimal_symbol (current_program_space, + "objc_lookup_class").minsym != nullptr) function = find_function_in_inferior("objc_lookup_class", NULL); else { @@ -149,9 +151,11 @@ lookup_child_selector (struct gdbarch *gdbarch, const char *selname) return 0; } - if (lookup_minimal_symbol("sel_getUid", 0, 0).minsym) + if (lookup_minimal_symbol (current_program_space, "sel_getUid").minsym + != nullptr) function = find_function_in_inferior("sel_getUid", NULL); - else if (lookup_minimal_symbol ("sel_get_any_uid", 0, 0).minsym) + else if (lookup_minimal_symbol (current_program_space, + "sel_get_any_uid").minsym != nullptr) function = find_function_in_inferior("sel_get_any_uid", NULL); else { @@ -180,17 +184,21 @@ value_nsstring (struct gdbarch *gdbarch, const char *ptr, int len) stringValue[2] = value_string(ptr, len, char_type); stringValue[2] = value_coerce_array(stringValue[2]); /* _NSNewStringFromCString replaces "istr" after Lantern2A. */ - if (lookup_minimal_symbol("_NSNewStringFromCString", 0, 0).minsym) + if (lookup_minimal_symbol (current_program_space, + "_NSNewStringFromCString").minsym != nullptr) { function = find_function_in_inferior("_NSNewStringFromCString", NULL); nsstringValue = call_function_by_hand(function, NULL, stringValue[2]); } - else if (lookup_minimal_symbol("istr", 0, 0).minsym) + else if (lookup_minimal_symbol (current_program_space, + "istr").minsym != nullptr) { function = find_function_in_inferior("istr", NULL); nsstringValue = call_function_by_hand(function, NULL, stringValue[2]); } - else if (lookup_minimal_symbol("+[NSString stringWithCString:]", 0, 0).minsym) + else if (lookup_minimal_symbol (current_program_space, + "+[NSString stringWithCString:]").minsym + != nullptr) { function = find_function_in_inferior("+[NSString stringWithCString:]", NULL); @@ -1137,8 +1145,8 @@ find_imps (const char *method, std::vector<const char *> *symbol_names) symbol_names->push_back (sym->natural_name ()); else { - struct bound_minimal_symbol msym - = lookup_minimal_symbol (selector, 0, 0); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, selector); if (msym.minsym != NULL) symbol_names->push_back (msym.minsym->natural_name ()); @@ -1240,13 +1248,13 @@ find_objc_msgsend (void) for (i = 0; i < nmethcalls; i++) { - struct bound_minimal_symbol func; - /* Try both with and without underscore. */ - func = lookup_bound_minimal_symbol (methcalls[i].name); + bound_minimal_symbol func + = lookup_minimal_symbol (current_program_space, methcalls[i].name); if ((func.minsym == NULL) && (methcalls[i].name[0] == '_')) { - func = lookup_bound_minimal_symbol (methcalls[i].name + 1); + func = lookup_minimal_symbol (current_program_space, + methcalls[i].name + 1); } if (func.minsym == NULL) { diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 368e129..0e076fe 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -306,9 +306,10 @@ build_objfile_section_table (struct objfile *objfile) requests for specific operations. Other bits like OBJF_SHARED are simply copied through to the new objfile flags member. */ -objfile::objfile (gdb_bfd_ref_ptr bfd_, const char *name, objfile_flags flags_) +objfile::objfile (gdb_bfd_ref_ptr bfd_, program_space *pspace, + const char *name, objfile_flags flags_) : flags (flags_), - pspace (current_program_space), + m_pspace (pspace), obfd (std::move (bfd_)) { const char *expanded_name; @@ -345,13 +346,12 @@ objfile::objfile (gdb_bfd_ref_ptr bfd_, const char *name, objfile_flags flags_) set_objfile_per_bfd (this); } -/* If there is a valid and known entry point, function fills *ENTRY_P with it - and returns non-zero; otherwise it returns zero. */ +/* See objfiles.h. */ int -entry_point_address_query (CORE_ADDR *entry_p) +entry_point_address_query (program_space *pspace, CORE_ADDR *entry_p) { - objfile *objf = current_program_space->symfile_object_file; + objfile *objf = pspace->symfile_object_file; if (objf == NULL || !objf->per_bfd->ei.entry_point_p) return 0; @@ -361,14 +361,14 @@ entry_point_address_query (CORE_ADDR *entry_p) return 1; } -/* Get current entry point address. Call error if it is not known. */ +/* See objfiles.h. */ CORE_ADDR -entry_point_address (void) +entry_point_address (program_space *pspace) { CORE_ADDR retval; - if (!entry_point_address_query (&retval)) + if (!entry_point_address_query (pspace, &retval)) error (_("Entry point address is not known.")); return retval; @@ -442,10 +442,11 @@ add_separate_debug_objfile (struct objfile *objfile, struct objfile *parent) /* See objfiles.h. */ objfile * -objfile::make (gdb_bfd_ref_ptr bfd_, const char *name_, objfile_flags flags_, - objfile *parent) +objfile::make (gdb_bfd_ref_ptr bfd_, program_space *pspace, const char *name_, + objfile_flags flags_, objfile *parent) { - objfile *result = new objfile (std::move (bfd_), name_, flags_); + objfile *result + = new objfile (std::move (bfd_), current_program_space, name_, flags_); if (parent != nullptr) add_separate_debug_objfile (result, parent); @@ -463,7 +464,7 @@ objfile::make (gdb_bfd_ref_ptr bfd_, const char *name_, objfile_flags flags_, void objfile::unlink () { - current_program_space->remove_objfile (this); + this->pspace ()->remove_objfile (this); } /* Free all separate debug objfile of OBJFILE, but don't free OBJFILE @@ -561,14 +562,15 @@ objfile::~objfile () and if so, call clear_current_source_symtab_and_line. */ { - struct symtab_and_line cursal = get_current_source_symtab_and_line (); + symtab_and_line cursal + = get_current_source_symtab_and_line (this->pspace ()); if (cursal.symtab && cursal.symtab->compunit ()->objfile () == this) - clear_current_source_symtab_and_line (); + clear_current_source_symtab_and_line (this->pspace ()); } /* Rebuild section map next time we need it. */ - get_objfile_pspace_data (pspace)->section_map_dirty = 1; + get_objfile_pspace_data (m_pspace)->section_map_dirty = 1; } @@ -646,7 +648,7 @@ objfile_relocate1 (struct objfile *objfile, objfile->section_offsets[i] = new_offsets[i]; /* Rebuild section map next time we need it. */ - get_objfile_pspace_data (objfile->pspace)->section_map_dirty = 1; + get_objfile_pspace_data (objfile->pspace ())->section_map_dirty = 1; /* Update the table in exec_ops, used to read memory. */ for (obj_section *s : objfile->sections ()) @@ -731,67 +733,58 @@ objfile_rebase (struct objfile *objfile, CORE_ADDR slide) if (changed) breakpoint_re_set (); } - -/* Return non-zero if OBJFILE has full symbols. */ -int -objfile_has_full_symbols (struct objfile *objfile) +/* See objfiles.h. */ + +bool +objfile_has_full_symbols (objfile *objfile) { - return objfile->compunit_symtabs != NULL; + return objfile->compunit_symtabs != nullptr; } -/* Return non-zero if OBJFILE has full or partial symbols, either directly - or through a separate debug file. */ +/* See objfiles.h. */ -int -objfile_has_symbols (struct objfile *objfile) +bool +objfile_has_symbols (objfile *objfile) { for (::objfile *o : objfile->separate_debug_objfiles ()) if (o->has_partial_symbols () || objfile_has_full_symbols (o)) - return 1; - return 0; -} + return true; + return false; +} -/* Many places in gdb want to test just to see if we have any partial - symbols available. This function returns zero if none are currently - available, nonzero otherwise. */ +/* See objfiles.h. */ -int -have_partial_symbols (void) +bool +have_partial_symbols (program_space *pspace) { - for (objfile *ofp : current_program_space->objfiles ()) - { - if (ofp->has_partial_symbols ()) - return 1; - } - return 0; + for (objfile *ofp : pspace->objfiles ()) + if (ofp->has_partial_symbols ()) + return true; + + return false; } -/* Many places in gdb want to test just to see if we have any full - symbols available. This function returns zero if none are currently - available, nonzero otherwise. */ +/* See objfiles.h. */ -int -have_full_symbols (void) +bool +have_full_symbols (program_space *pspace) { - for (objfile *ofp : current_program_space->objfiles ()) - { - if (objfile_has_full_symbols (ofp)) - return 1; - } - return 0; + for (objfile *ofp : pspace->objfiles ()) + if (objfile_has_full_symbols (ofp)) + return true; + + return false; } -/* This operations deletes all objfile entries that represent solibs that - weren't explicitly loaded by the user, via e.g., the add-symbol-file - command. */ +/* See objfiles.h. */ void -objfile_purge_solibs (void) +objfile_purge_solibs (program_space *pspace) { - for (objfile *objf : current_program_space->objfiles_safe ()) + for (objfile *objf : pspace->objfiles_safe ()) { /* We assume that the solib package has been purged already, or will be soon. */ @@ -801,22 +794,16 @@ objfile_purge_solibs (void) } } +/* See objfiles.h. */ -/* Many places in gdb want to test just to see if we have any minimal - symbols available. This function returns zero if none are currently - available, nonzero otherwise. */ - -int -have_minimal_symbols (void) +bool +have_minimal_symbols (program_space *pspace) { - for (objfile *ofp : current_program_space->objfiles ()) - { - if (ofp->per_bfd->minimal_symbol_count > 0) - { - return 1; - } - } - return 0; + for (objfile *ofp : pspace->objfiles ()) + if (ofp->per_bfd->minimal_symbol_count > 0) + return true; + + return false; } /* Qsort comparison function. */ @@ -1177,16 +1164,14 @@ pc_in_section (CORE_ADDR pc, const char *name) && s->the_bfd_section->name != nullptr && strcmp (s->the_bfd_section->name, name) == 0); } - -/* Set section_map_dirty so section map will be rebuilt next time it - is used. Called by reread_symbols. */ +/* See objfiles.h. */ void -objfiles_changed (void) +objfiles_changed (program_space *pspace) { /* Rebuild section map next time we need it. */ - get_objfile_pspace_data (current_program_space)->section_map_dirty = 1; + get_objfile_pspace_data (pspace)->section_map_dirty = 1; } /* See comments in objfiles.h. */ diff --git a/gdb/objfiles.h b/gdb/objfiles.h index 88dfb33..8b1e89c 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -423,7 +423,8 @@ struct objfile private: /* The only way to create an objfile is to call objfile::make. */ - objfile (gdb_bfd_ref_ptr, const char *, objfile_flags); + objfile (gdb_bfd_ref_ptr, program_space *pspace, const char *, + objfile_flags); public: @@ -436,15 +437,19 @@ public: ~objfile (); /* Create an objfile. */ - static objfile *make (gdb_bfd_ref_ptr bfd_, const char *name_, - objfile_flags flags_, objfile *parent = nullptr); + static objfile *make (gdb_bfd_ref_ptr bfd_, program_space *pspace, + const char *name_, objfile_flags flags_, + objfile *parent = nullptr); - /* Remove an objfile from the current program space, and free + /* Remove this objfile from its program space's objfile list, and frees it. */ void unlink (); DISABLE_COPY_AND_ASSIGN (objfile); + /* Return the program space associated with this objfile. */ + program_space *pspace () { return m_pspace; } + /* A range adapter that makes it possible to iterate over all compunits in one objfile. */ @@ -595,11 +600,10 @@ public: domain_search_flags domain); /* See quick_symbol_functions. */ - struct compunit_symtab *find_pc_sect_compunit_symtab - (struct bound_minimal_symbol msymbol, - CORE_ADDR pc, - struct obj_section *section, - int warn_if_readin); + struct compunit_symtab * + find_pc_sect_compunit_symtab (bound_minimal_symbol msymbol, CORE_ADDR pc, + struct obj_section *section, + int warn_if_readin); /* See quick_symbol_functions. */ void map_symbol_filenames (gdb::function_view<symbol_filename_ftype> fun, @@ -716,10 +720,12 @@ public: objfile_flags flags; +private: /* The program space associated with this objfile. */ - struct program_space *pspace; + program_space *m_pspace; +public: /* List of compunits. These are used to do symbol lookups and file/line-number lookups. */ @@ -907,9 +913,15 @@ obj_section::set_offset (CORE_ADDR offset) /* Declarations for functions defined in objfiles.c */ -extern int entry_point_address_query (CORE_ADDR *entry_p); +/* If there is a valid and known entry point in PSPACE, fill *ENTRY_P with it + and return non-zero. */ -extern CORE_ADDR entry_point_address (void); +extern int entry_point_address_query (program_space *pspace, + CORE_ADDR *entry_p); + +/* Get the entry point address in PSPACE. Call error if it is not known. */ + +extern CORE_ADDR entry_point_address (program_space *pspace); extern void build_objfile_section_table (struct objfile *); @@ -918,18 +930,30 @@ extern void free_objfile_separate_debug (struct objfile *); extern void objfile_relocate (struct objfile *, const section_offsets &); extern void objfile_rebase (struct objfile *, CORE_ADDR); -extern int objfile_has_full_symbols (struct objfile *objfile); +/* Return true if OBJFILE has full symbols. */ + +extern bool objfile_has_full_symbols (objfile *objfile); -extern int objfile_has_symbols (struct objfile *objfile); +/* Return true if OBJFILE has full or partial symbols, either directly + or through a separate debug file. */ -extern int have_partial_symbols (void); +extern bool objfile_has_symbols (objfile *objfile); -extern int have_full_symbols (void); +/* Return true if any objfile of PSPACE has partial symbols. */ + +extern bool have_partial_symbols (program_space *pspace); + +/* Return true if any objfile of PSPACE has full symbols. */ + +extern bool have_full_symbols (program_space *pspace); extern void objfile_set_sym_fns (struct objfile *objfile, const struct sym_fns *sf); -extern void objfiles_changed (void); +/* Set section_map_dirty for PSPACE so the section map will be rebuilt next time + it is used. */ + +extern void objfiles_changed (program_space *pspace); /* Return true if ADDR maps into one of the sections of OBJFILE and false otherwise. */ @@ -942,16 +966,18 @@ extern bool is_addr_in_objfile (CORE_ADDR addr, const struct objfile *objfile); extern bool shared_objfile_contains_address_p (struct program_space *pspace, CORE_ADDR address); -/* This operation deletes all objfile entries that represent solibs that - weren't explicitly loaded by the user, via e.g., the add-symbol-file +/* This operation deletes all objfile entries in PSPACE that represent solibs + that weren't explicitly loaded by the user, via e.g., the add-symbol-file command. */ -extern void objfile_purge_solibs (void); +extern void objfile_purge_solibs (program_space *pspace); /* Functions for dealing with the minimal symbol table, really a misc address<->symbol mapping for things we don't have debug symbols for. */ -extern int have_minimal_symbols (void); +/* Return true if any objfile of PSPACE has minimal symbols. */ + +extern bool have_minimal_symbols (program_space *pspace); extern struct obj_section *find_pc_section (CORE_ADDR pc); diff --git a/gdb/obsd-tdep.c b/gdb/obsd-tdep.c index 5142984..00de5c0 100644 --- a/gdb/obsd-tdep.c +++ b/gdb/obsd-tdep.c @@ -27,9 +27,8 @@ CORE_ADDR obsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc) { - struct bound_minimal_symbol msym; - - msym = lookup_minimal_symbol("_dl_bind", NULL, NULL); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, "_dl_bind"); if (msym.minsym && msym.value_address () == pc) return frame_unwind_caller_pc (get_current_frame ()); else diff --git a/gdb/osabi.c b/gdb/osabi.c index d494d89..8a1efce 100644 --- a/gdb/osabi.c +++ b/gdb/osabi.c @@ -25,6 +25,7 @@ #include "gdb_bfd.h" #include "elf-bfd.h" +#include "inferior.h" #ifndef GDB_OSABI_DEFAULT #define GDB_OSABI_DEFAULT GDB_OSABI_UNKNOWN @@ -70,7 +71,6 @@ static const struct osabi_names gdb_osabi_names[] = { "OpenBSD", NULL }, { "WindowsCE", NULL }, { "DJGPP", NULL }, - { "QNX-Neutrino", NULL }, { "Cygwin", NULL }, { "Windows", NULL }, { "AIX", NULL }, @@ -645,7 +645,7 @@ set_osabi (const char *args, int from_tty, struct cmd_list_element *c) /* NOTE: At some point (true multiple architectures) we'll need to be more graceful here. */ gdbarch_info info; - if (! gdbarch_update_p (info)) + if (!gdbarch_update_p (current_inferior (), info)) internal_error (_("Updating OS ABI failed.")); } diff --git a/gdb/osabi.h b/gdb/osabi.h index c1a85d1..d2b1a35 100644 --- a/gdb/osabi.h +++ b/gdb/osabi.h @@ -35,7 +35,6 @@ enum gdb_osabi GDB_OSABI_OPENBSD, GDB_OSABI_WINCE, GDB_OSABI_GO32, - GDB_OSABI_QNXNTO, GDB_OSABI_CYGWIN, GDB_OSABI_WINDOWS, GDB_OSABI_AIX, diff --git a/gdb/p-exp.y b/gdb/p-exp.y index f334db6..ad7cd58 100644 --- a/gdb/p-exp.y +++ b/gdb/p-exp.y @@ -717,16 +717,15 @@ variable: name_not_typename } else { - struct bound_minimal_symbol msymbol; std::string arg = copy_name ($1.stoken); - msymbol = - lookup_bound_minimal_symbol (arg.c_str ()); + bound_minimal_symbol msymbol + = lookup_minimal_symbol (current_program_space, arg.c_str ()); if (msymbol.minsym != NULL) pstate->push_new<var_msym_value_operation> (msymbol); - else if (!have_full_symbols () - && !have_partial_symbols ()) + else if (!have_full_symbols (current_program_space) + && !have_partial_symbols (current_program_space)) error (_("No symbol table is loaded. " "Use the \"file\" command.")); else diff --git a/gdb/p-lang.c b/gdb/p-lang.c index d3d491c..4c5d4dd 100644 --- a/gdb/p-lang.c +++ b/gdb/p-lang.c @@ -59,22 +59,23 @@ static const char GPC_MAIN_PROGRAM_NAME_2[] = "pascal_main_program"; const char * pascal_main_name (void) { - struct bound_minimal_symbol msym; - - msym = lookup_minimal_symbol (GPC_P_INITIALIZE, NULL, NULL); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, GPC_P_INITIALIZE); /* If '_p_initialize' was not found, the main program is likely not written in Pascal. */ if (msym.minsym == NULL) return NULL; - msym = lookup_minimal_symbol (GPC_MAIN_PROGRAM_NAME_1, NULL, NULL); + msym + = lookup_minimal_symbol (current_program_space, GPC_MAIN_PROGRAM_NAME_1); if (msym.minsym != NULL) { return GPC_MAIN_PROGRAM_NAME_1; } - msym = lookup_minimal_symbol (GPC_MAIN_PROGRAM_NAME_2, NULL, NULL); + msym + = lookup_minimal_symbol (current_program_space, GPC_MAIN_PROGRAM_NAME_2); if (msym.minsym != NULL) { return GPC_MAIN_PROGRAM_NAME_2; diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c index bdb9524..aa7f1a9 100644 --- a/gdb/p-valprint.c +++ b/gdb/p-valprint.c @@ -225,8 +225,8 @@ pascal_language::value_print_inner (struct value *val, { /* Print vtbl's nicely. */ CORE_ADDR vt_address = unpack_pointer (type, valaddr); - struct bound_minimal_symbol msymbol = - lookup_minimal_symbol_by_pc (vt_address); + bound_minimal_symbol msymbol + = lookup_minimal_symbol_by_pc (vt_address); /* If 'symbol_print' is set, we did the work above. */ if (!options->symbol_print diff --git a/gdb/parse.c b/gdb/parse.c index 0a2b2a5..e0837de 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -145,10 +145,12 @@ parser_state::push_symbol (const char *name, block_symbol sym) } else { - struct bound_minimal_symbol msymbol = lookup_bound_minimal_symbol (name); + bound_minimal_symbol msymbol + = lookup_minimal_symbol (current_program_space, name); if (msymbol.minsym != NULL) push_new<expr::var_msym_value_operation> (msymbol); - else if (!have_full_symbols () && !have_partial_symbols ()) + else if (!have_full_symbols (current_program_space) + && !have_partial_symbols (current_program_space)) error (_("No symbol table is loaded. Use the \"file\" command.")); else error (_("No symbol \"%s\" in current context."), name); @@ -161,7 +163,6 @@ void parser_state::push_dollar (struct stoken str) { struct block_symbol sym; - struct bound_minimal_symbol msym; struct internalvar *isym = NULL; std::string copy; @@ -231,7 +232,8 @@ parser_state::push_dollar (struct stoken str) push_new<expr::var_value_operation> (sym); return; } - msym = lookup_bound_minimal_symbol (copy.c_str ()); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, copy.c_str ()); if (msym.minsym) { push_new<expr::var_msym_value_operation> (msym); @@ -374,8 +376,8 @@ parse_exp_in_context (const char **stringptr, CORE_ADDR pc, if (!expression_context_block) { - struct symtab_and_line cursal - = get_current_source_symtab_and_line (); + symtab_and_line cursal + = get_current_source_symtab_and_line (current_program_space); if (cursal.symtab) expression_context_block @@ -421,8 +423,7 @@ parse_exp_in_context (const char **stringptr, CORE_ADDR pc, expression_context_pc, flags, *stringptr, completer != nullptr, tracker); - scoped_restore_current_language lang_saver; - set_language (lang->la_language); + scoped_restore_current_language lang_saver (lang->la_language); try { @@ -488,10 +489,7 @@ parse_expression_with_language (const char *string, enum language lang) { std::optional<scoped_restore_current_language> lang_saver; if (current_language->la_language != lang) - { - lang_saver.emplace (); - set_language (lang); - } + lang_saver.emplace (lang); return parse_expression (string); } diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index e100045..3116fc1 100644 --- a/gdb/ppc-linux-tdep.c +++ b/gdb/ppc-linux-tdep.c @@ -313,15 +313,13 @@ static const struct ppc_insn_pattern powerpc32_plt_stub_so_2[] = static int powerpc_linux_in_dynsym_resolve_code (CORE_ADDR pc) { - struct bound_minimal_symbol sym; - /* Check whether PC is in the dynamic linker. This also checks whether it is in the .plt section, used by non-PIC executables. */ if (svr4_in_dynsym_resolve_code (pc)) return 1; /* Check if we are in the resolver. */ - sym = lookup_minimal_symbol_by_pc (pc); + bound_minimal_symbol sym = lookup_minimal_symbol_by_pc (pc); if (sym.minsym != NULL && (strcmp (sym.minsym->linkage_name (), "__glink") == 0 || strcmp (sym.minsym->linkage_name (), "__glink_PLTresolve") == 0)) @@ -1670,10 +1668,9 @@ ppc_elfv2_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym) static CORE_ADDR ppc_elfv2_skip_entrypoint (struct gdbarch *gdbarch, CORE_ADDR pc) { - struct bound_minimal_symbol fun; int local_entry_offset = 0; - fun = lookup_minimal_symbol_by_pc (pc); + bound_minimal_symbol fun = lookup_minimal_symbol_by_pc (pc); if (fun.minsym == NULL) return pc; diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c index 47e6292..f317c94 100644 --- a/gdb/ppc-sysv-tdep.c +++ b/gdb/ppc-sysv-tdep.c @@ -1044,12 +1044,10 @@ static int convert_code_addr_to_desc_addr (CORE_ADDR code_addr, CORE_ADDR *desc_addr) { struct obj_section *dot_fn_section; - struct bound_minimal_symbol dot_fn; - struct bound_minimal_symbol fn; /* Find the minimal symbol that corresponds to CODE_ADDR (should have a name of the form ".FN"). */ - dot_fn = lookup_minimal_symbol_by_pc (code_addr); + bound_minimal_symbol dot_fn = lookup_minimal_symbol_by_pc (code_addr); if (dot_fn.minsym == NULL || dot_fn.minsym->linkage_name ()[0] != '.') return 0; /* Get the section that contains CODE_ADDR. Need this for the @@ -1061,8 +1059,10 @@ convert_code_addr_to_desc_addr (CORE_ADDR code_addr, CORE_ADDR *desc_addr) address. Only look for the minimal symbol in ".FN"'s object file - avoids problems when two object files (i.e., shared libraries) contain a minimal symbol with the same name. */ - fn = lookup_minimal_symbol (dot_fn.minsym->linkage_name () + 1, NULL, - dot_fn_section->objfile); + bound_minimal_symbol fn + = lookup_minimal_symbol (current_program_space, + dot_fn.minsym->linkage_name () + 1, + dot_fn_section->objfile); if (fn.minsym == NULL) return 0; /* Found a descriptor. */ diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 1d6a492..f1aaa64 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -606,7 +606,6 @@ build_address_symbolic (struct gdbarch *gdbarch, int *line, /* OUT */ int *unmapped) /* OUT */ { - struct bound_minimal_symbol msymbol; struct symbol *symbol; CORE_ADDR name_location = 0; struct obj_section *section = NULL; @@ -638,7 +637,8 @@ build_address_symbolic (struct gdbarch *gdbarch, save some memory, but for many debug format--ELF/DWARF or anything/stabs--it would be inconvenient to eliminate those minimal symbols anyway). */ - msymbol = lookup_minimal_symbol_by_pc_section (addr, section); + bound_minimal_symbol msymbol + = lookup_minimal_symbol_by_pc_section (addr, section); symbol = find_pc_sect_function (addr, section); if (symbol) @@ -1575,7 +1575,6 @@ info_address_command (const char *exp, int from_tty) struct gdbarch *gdbarch; int regno; struct symbol *sym; - struct bound_minimal_symbol msymbol; long val; struct obj_section *section; CORE_ADDR load_addr, context_pc = 0; @@ -1601,7 +1600,8 @@ info_address_command (const char *exp, int from_tty) return; } - msymbol = lookup_bound_minimal_symbol (exp); + bound_minimal_symbol msymbol + = lookup_minimal_symbol (current_program_space, exp); if (msymbol.minsym != NULL) { @@ -1753,9 +1753,9 @@ info_address_command (const char *exp, int from_tty) case LOC_UNRESOLVED: { - struct bound_minimal_symbol msym; - - msym = lookup_bound_minimal_symbol (sym->linkage_name ()); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, + sym->linkage_name ()); if (msym.minsym == NULL) gdb_printf ("unresolved"); else @@ -2294,11 +2294,11 @@ disable_display_command (const char *args, int from_tty) static void clear_dangling_display_expressions (struct objfile *objfile) { - program_space *pspace = objfile->pspace; + program_space *pspace = objfile->pspace (); if (objfile->separate_debug_objfile_backlink) { objfile = objfile->separate_debug_objfile_backlink; - gdb_assert (objfile->pspace == pspace); + gdb_assert (objfile->pspace () == pspace); } for (auto &d : all_displays) diff --git a/gdb/proc-service.c b/gdb/proc-service.c index 1889a00..ce2d69a 100644 --- a/gdb/proc-service.c +++ b/gdb/proc-service.c @@ -99,7 +99,8 @@ ps_pglobal_lookup (struct ps_prochandle *ph, const char *obj, set_current_program_space (inf->pspace); /* FIXME: kettenis/2000-09-03: What should we do with OBJ? */ - bound_minimal_symbol ms = lookup_minimal_symbol (name, NULL, NULL); + bound_minimal_symbol ms + = lookup_minimal_symbol (current_program_space, name); if (ms.minsym == NULL) return PS_NOSYM; diff --git a/gdb/progspace.c b/gdb/progspace.c index d5b5ef2..28198c1 100644 --- a/gdb/progspace.c +++ b/gdb/progspace.c @@ -115,7 +115,7 @@ program_space::~program_space () set_current_program_space (this); breakpoint_program_space_exit (this); - no_shared_libraries (NULL, 0); + no_shared_libraries (this); free_all_objfiles (); /* Defer breakpoint re-set because we don't want to create new locations for this pspace which we're tearing down. */ @@ -128,7 +128,7 @@ void program_space::free_all_objfiles () { /* Any objfile reference would become stale. */ - for (const solib &so : current_program_space->solibs ()) + for (const solib &so : this->solibs ()) gdb_assert (so.objfile == NULL); while (!objfiles_list.empty ()) diff --git a/gdb/psymtab.c b/gdb/psymtab.c index 7d6648c..0df3dc8 100644 --- a/gdb/psymtab.c +++ b/gdb/psymtab.c @@ -87,7 +87,7 @@ static struct partial_symtab * find_pc_sect_psymtab_closer (struct objfile *objfile, CORE_ADDR pc, struct obj_section *section, struct partial_symtab *pst, - struct bound_minimal_symbol msymbol) + bound_minimal_symbol msymbol) { struct partial_symtab *tpst; struct partial_symtab *best_pst = pst; @@ -161,7 +161,7 @@ struct partial_symtab * psymbol_functions::find_pc_sect_psymtab (struct objfile *objfile, CORE_ADDR pc, struct obj_section *section, - struct bound_minimal_symbol msymbol) + bound_minimal_symbol msymbol) { for (partial_symtab *pst : partial_symbols (objfile)) if (pc >= pst->text_low (objfile) && pc < pst->text_high (objfile)) @@ -181,12 +181,11 @@ psymbol_functions::find_pc_sect_psymtab (struct objfile *objfile, the definition of quick_symbol_functions in symfile.h. */ struct compunit_symtab * -psymbol_functions::find_pc_sect_compunit_symtab - (struct objfile *objfile, - struct bound_minimal_symbol msymbol, - CORE_ADDR pc, - struct obj_section *section, - int warn_if_readin) +psymbol_functions::find_pc_sect_compunit_symtab (struct objfile *objfile, + bound_minimal_symbol msymbol, + CORE_ADDR pc, + struct obj_section *section, + int warn_if_readin) { struct partial_symtab *ps = find_pc_sect_psymtab (objfile, pc, section, @@ -1281,7 +1280,7 @@ maintenance_print_psymbols (const char *args, int from_tty) if (address_arg != NULL) { - struct bound_minimal_symbol msymbol; + bound_minimal_symbol msymbol; /* We don't assume each pc has a unique objfile (this is for debugging). */ diff --git a/gdb/psymtab.h b/gdb/psymtab.h index f41f241..508e778 100644 --- a/gdb/psymtab.h +++ b/gdb/psymtab.h @@ -636,8 +636,8 @@ struct psymbol_functions : public quick_symbol_functions domain_search_flags kind) override; struct compunit_symtab *find_pc_sect_compunit_symtab - (struct objfile *objfile, struct bound_minimal_symbol msymbol, - CORE_ADDR pc, struct obj_section *section, int warn_if_readin) override; + (struct objfile *objfile, bound_minimal_symbol msymbol, CORE_ADDR pc, + struct obj_section *section, int warn_if_readin) override; struct compunit_symtab *find_compunit_symtab_by_address (struct objfile *objfile, CORE_ADDR address) override @@ -672,11 +672,10 @@ struct psymbol_functions : public quick_symbol_functions exactly matches PC, or, if we cannot find an exact match, the psymtab that contains a symbol whose address is closest to PC. */ - struct partial_symtab *find_pc_sect_psymtab - (struct objfile *objfile, - CORE_ADDR pc, - struct obj_section *section, - struct bound_minimal_symbol msymbol); + struct partial_symtab *find_pc_sect_psymtab (struct objfile *objfile, + CORE_ADDR pc, + struct obj_section *section, + bound_minimal_symbol msymbol); private: diff --git a/gdb/python/lib/gdb/dap/__init__.py b/gdb/python/lib/gdb/dap/__init__.py index 51b9546..145aeb6 100644 --- a/gdb/python/lib/gdb/dap/__init__.py +++ b/gdb/python/lib/gdb/dap/__init__.py @@ -92,5 +92,8 @@ def pre_command_loop(): # session. session_started = True startup.thread_log("starting DAP server") + # These are handy for bug reports. + startup.exec_and_log("show version") + startup.exec_and_log("show configuration") global server startup.start_dap(server.main_loop) diff --git a/gdb/python/lib/gdb/dap/breakpoint.py b/gdb/python/lib/gdb/dap/breakpoint.py index e60265b..db8ac10 100644 --- a/gdb/python/lib/gdb/dap/breakpoint.py +++ b/gdb/python/lib/gdb/dap/breakpoint.py @@ -23,7 +23,14 @@ import gdb from .server import capability, request, send_event from .sources import make_source -from .startup import DAPException, LogLevel, in_gdb_thread, log_stack, parse_and_eval +from .startup import ( + DAPException, + LogLevel, + exec_mi_and_log, + in_gdb_thread, + log_stack, + parse_and_eval, +) from .typecheck import type_check # True when suppressing new breakpoint events. @@ -97,11 +104,16 @@ breakpoint_map = {} @in_gdb_thread def _breakpoint_descriptor(bp): "Return the Breakpoint object descriptor given a gdb Breakpoint." + # If there are no objfiles (that is, before the launch request), + # we consider all breakpoints to be pending. This is done to work + # around the gdb oddity that setting a breakpoint by address will + # always succeed. + pending = bp.pending or len(gdb.objfiles()) == 0 result = { "id": bp.number, - "verified": not bp.pending, + "verified": not pending, } - if bp.pending: + if pending: result["reason"] = "pending" if bp.locations: # Just choose the first location, because DAP doesn't allow @@ -368,10 +380,13 @@ def _catch_exception(filterId, **args): cmd = "-catch-" + filterId else: raise DAPException("Invalid exception filterID: " + str(filterId)) - result = gdb.execute_mi(cmd) + result = exec_mi_and_log(cmd) + # While the Ada catchpoints emit a "bkptno" field here, the C++ + # ones do not. So, instead we look at the "number" field. + num = result["bkpt"]["number"] # A little lame that there's no more direct way. for bp in gdb.breakpoints(): - if bp.number == result["bkptno"]: + if bp.number == num: return bp # Not a DAPException because this is definitely unexpected. raise Exception("Could not find catchpoint after creating") diff --git a/gdb/python/lib/gdb/dap/globalvars.py b/gdb/python/lib/gdb/dap/globalvars.py index 149c9a8..38bdc5c 100644 --- a/gdb/python/lib/gdb/dap/globalvars.py +++ b/gdb/python/lib/gdb/dap/globalvars.py @@ -60,7 +60,8 @@ class _Globals(BaseReference): @in_gdb_thread def fetch_one_child(self, idx): - return self.var_list[idx].value() + sym = self.var_list[idx] + return (sym.name, sym.value()) @in_gdb_thread diff --git a/gdb/python/lib/gdb/dap/locations.py b/gdb/python/lib/gdb/dap/locations.py index 92e68f5..967322f 100644 --- a/gdb/python/lib/gdb/dap/locations.py +++ b/gdb/python/lib/gdb/dap/locations.py @@ -16,10 +16,9 @@ # This is deprecated in 3.9, but required in older versions. from typing import Optional -import gdb - from .server import capability, request from .sources import decode_source +from .startup import exec_mi_and_log # Note that the spec says that the arguments to this are optional. @@ -36,7 +35,7 @@ def breakpoint_locations(*, source, line: int, endLine: Optional[int] = None, ** endLine = line filename = decode_source(source) lines = set() - for entry in gdb.execute_mi("-symbol-list-lines", filename)["lines"]: + for entry in exec_mi_and_log("-symbol-list-lines", filename)["lines"]: this_line = entry["line"] if this_line >= line and this_line <= endLine: lines.add(this_line) diff --git a/gdb/python/lib/gdb/dap/scopes.py b/gdb/python/lib/gdb/dap/scopes.py index d0e9115..fb90f64 100644 --- a/gdb/python/lib/gdb/dap/scopes.py +++ b/gdb/python/lib/gdb/dap/scopes.py @@ -111,20 +111,19 @@ class _ScopeReference(BaseReference): return symbol_value(self.var_list[idx], self.frame) -# A _ScopeReference that prepends the most recent return value. Note -# that this object is only created if such a value actually exists. +# A _ScopeReference that wraps the 'finish' value. Note that this +# object is only created if such a value actually exists. class _FinishScopeReference(_ScopeReference): - def __init__(self, *args): - super().__init__(*args) + def __init__(self, frame): + super().__init__("Return", "returnValue", frame, ()) def child_count(self): - return super().child_count() + 1 + return 1 def fetch_one_child(self, idx): - if idx == 0: - global _last_return_value - return ("(return)", _last_return_value) - return super().fetch_one_child(idx - 1) + assert idx == 0 + global _last_return_value + return ("(return)", _last_return_value) class _RegisterReference(_ScopeReference): @@ -159,11 +158,11 @@ def scopes(*, frameId: int, **extra): # Make sure to handle the None case as well as the empty # iterator case. locs = tuple(frame.frame_locals() or ()) - if has_return_value: - scopes.append(_FinishScopeReference("Locals", "locals", frame, locs)) - elif locs: + if locs: scopes.append(_ScopeReference("Locals", "locals", frame, locs)) scopes.append(_RegisterReference("Registers", frame)) + if has_return_value: + scopes.append(_FinishScopeReference(frame)) frame_to_scope[frameId] = scopes global_scope = get_global_scope(frame) if global_scope is not None: diff --git a/gdb/python/lib/gdb/dap/sources.py b/gdb/python/lib/gdb/dap/sources.py index ad0c913..a9f4ea6 100644 --- a/gdb/python/lib/gdb/dap/sources.py +++ b/gdb/python/lib/gdb/dap/sources.py @@ -15,10 +15,8 @@ import os -import gdb - from .server import capability, request -from .startup import DAPException, in_gdb_thread +from .startup import DAPException, exec_mi_and_log, in_gdb_thread # The next available source reference ID. Must be greater than 0. _next_source = 1 @@ -83,7 +81,7 @@ def decode_source(source): @capability("supportsLoadedSourcesRequest") def loaded_sources(**extra): result = [] - for elt in gdb.execute_mi("-file-list-exec-source-files")["files"]: + for elt in exec_mi_and_log("-file-list-exec-source-files")["files"]: result.append(make_source(elt["fullname"], elt["file"])) return { "sources": result, diff --git a/gdb/python/lib/gdb/dap/startup.py b/gdb/python/lib/gdb/dap/startup.py index 3952447..a3f048b 100644 --- a/gdb/python/lib/gdb/dap/startup.py +++ b/gdb/python/lib/gdb/dap/startup.py @@ -217,3 +217,10 @@ def exec_and_log(cmd, propagate_exception=False): raise DAPException(str(e)) from e else: log_stack() + + +@in_gdb_thread +def exec_mi_and_log(*args): + """Wrap gdb.execute_mi, logging the command.""" + log("+++ " + str(args)) + return gdb.execute_mi(*args) diff --git a/gdb/python/lib/gdb/ptwrite.py b/gdb/python/lib/gdb/ptwrite.py new file mode 100644 index 0000000..3be65fe --- /dev/null +++ b/gdb/python/lib/gdb/ptwrite.py @@ -0,0 +1,77 @@ +# Ptwrite utilities. +# Copyright (C) 2023 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/>. + +"""Utilities for working with ptwrite filters.""" + +import gdb + +# _ptwrite_filter contains the per thread copies of the filter function. +# The keys are tuples of inferior id and thread id. +# The filter functions are created for each thread by calling the +# _ptwrite_filter_factory. +_ptwrite_filter = {} +_ptwrite_filter_factory = None + + +def _ptwrite_exit_handler(event): + """Exit handler to prune _ptwrite_filter on thread exit.""" + _ptwrite_filter.pop(event.inferior_thread.ptid, None) + + +gdb.events.thread_exited.connect(_ptwrite_exit_handler) + + +def _clear_traces(): + """Helper function to clear the trace of all threads.""" + current_thread = gdb.selected_thread() + + for inferior in gdb.inferiors(): + for thread in inferior.threads(): + thread.switch() + recording = gdb.current_recording() + if recording is not None: + recording.clear() + + current_thread.switch() + + +def register_filter_factory(filter_factory_): + """Register the ptwrite filter factory.""" + if filter_factory_ is not None and not callable(filter_factory_): + raise TypeError("The filter factory must be callable or 'None'.") + + # Clear the traces of all threads of all inferiors to force + # re-decoding with the new filter. + _clear_traces() + + _ptwrite_filter.clear() + global _ptwrite_filter_factory + _ptwrite_filter_factory = filter_factory_ + + +def get_filter(): + """Returns the filter of the current thread.""" + thread = gdb.selected_thread() + key = thread.ptid + + # Create a new filter for new threads. + if key not in _ptwrite_filter: + if _ptwrite_filter_factory is not None: + _ptwrite_filter[key] = _ptwrite_filter_factory(thread) + else: + return None + + return _ptwrite_filter[key] diff --git a/gdb/python/py-disasm.c b/gdb/python/py-disasm.c index 87fea26..9b9b509 100644 --- a/gdb/python/py-disasm.c +++ b/gdb/python/py-disasm.c @@ -1306,7 +1306,7 @@ gdbpy_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr, } else { - gdbpy_print_stack (); + gdbpy_print_stack_or_quit (); return std::optional<int> (-1); } diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c index 89695ff..9f9032f 100644 --- a/gdb/python/py-framefilter.c +++ b/gdb/python/py-framefilter.c @@ -923,12 +923,12 @@ py_print_frame (PyObject *filter, frame_filter_flags flags, else if (PyLong_Check (py_func.get ())) { CORE_ADDR addr; - struct bound_minimal_symbol msymbol; if (get_addr_from_python (py_func.get (), &addr) < 0) return EXT_LANG_BT_ERROR; - msymbol = lookup_minimal_symbol_by_pc (addr); + bound_minimal_symbol msymbol + = lookup_minimal_symbol_by_pc (addr); if (msymbol.minsym != NULL) function = msymbol.minsym->print_name (); } diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c index 60a1483..6e8d5b5 100644 --- a/gdb/python/py-objfile.c +++ b/gdb/python/py-objfile.c @@ -183,7 +183,7 @@ objfpy_get_progspace (PyObject *self, void *closure) objfile_object *obj = (objfile_object *) self; if (obj->objfile) - return pspace_to_pspace_object (obj->objfile->pspace).release (); + return pspace_to_pspace_object (obj->objfile->pspace ()).release (); Py_RETURN_NONE; } diff --git a/gdb/python/py-record-btrace.c b/gdb/python/py-record-btrace.c index 36454fc..68b474c 100644 --- a/gdb/python/py-record-btrace.c +++ b/gdb/python/py-record-btrace.c @@ -44,7 +44,8 @@ struct btpy_list_object { /* Stride size. */ Py_ssize_t step; - /* Either &BTPY_CALL_TYPE or &RECPY_INSN_TYPE. */ + /* Either &recpy_func_type, &recpy_insn_type, &recpy_aux_type or + &recpy_gap_type. */ PyTypeObject* element_type; }; @@ -140,15 +141,21 @@ btrace_func_from_recpy_func (const PyObject * const pyobject) } /* Looks at the recorded item with the number NUMBER and create a - gdb.RecordInstruction or gdb.RecordGap object for it accordingly. */ + gdb.RecordInstruction, gdb.RecordGap or gdb.RecordAuxiliary object + for it accordingly. */ static PyObject * -btpy_insn_or_gap_new (thread_info *tinfo, Py_ssize_t number) +btpy_item_new (thread_info *tinfo, Py_ssize_t number) { btrace_insn_iterator iter; int err_code; - btrace_find_insn_by_number (&iter, &tinfo->btrace, number); + if (btrace_find_insn_by_number (&iter, &tinfo->btrace, number) == 0) + { + PyErr_Format (gdbpy_gdb_error, _("No such instruction.")); + return nullptr; + } + err_code = btrace_insn_get_error (&iter); if (err_code != 0) @@ -162,6 +169,12 @@ btpy_insn_or_gap_new (thread_info *tinfo, Py_ssize_t number) return recpy_gap_new (err_code, err_string, number); } + const struct btrace_insn *insn = btrace_insn_get (&iter); + gdb_assert (insn != nullptr); + + if (insn->iclass == BTRACE_INSN_AUX) + return recpy_aux_new (tinfo, RECORD_METHOD_BTRACE, number); + return recpy_insn_new (tinfo, RECORD_METHOD_BTRACE, number); } @@ -423,6 +436,48 @@ recpy_bt_func_next (PyObject *self, void *closure) RECORD_METHOD_BTRACE, func->next); } +/* Implementation of Auxiliary.data [str] for btrace. */ + +PyObject * +recpy_bt_aux_data (PyObject *self, void *closure) +{ + const btrace_insn *insn; + const recpy_element_object *obj; + thread_info *tinfo; + btrace_insn_iterator iter; + + if (Py_TYPE (self) != &recpy_aux_type) + { + PyErr_Format (gdbpy_gdb_error, _("Must be a gdb.Auxiliary.")); + return nullptr; + } + + obj = (const recpy_element_object *) self; + tinfo = obj->thread; + + if (tinfo == nullptr || btrace_is_empty (tinfo)) + { + PyErr_Format (gdbpy_gdb_error, _("No such auxiliary object.")); + return nullptr; + } + + if (btrace_find_insn_by_number (&iter, &tinfo->btrace, obj->number) == 0) + { + PyErr_Format (gdbpy_gdb_error, _("No such auxiliary object.")); + return nullptr; + } + + insn = btrace_insn_get (&iter); + if (insn == nullptr || insn->iclass != BTRACE_INSN_AUX) + { + PyErr_Format (gdbpy_gdb_error, _("Not a valid auxiliary object.")); + return nullptr; + } + + return PyUnicode_FromString + (iter.btinfo->aux_data.at (insn->aux_data_index).c_str ()); +} + /* Implementation of BtraceList.__len__ (self) -> int. */ static Py_ssize_t @@ -439,8 +494,9 @@ btpy_list_length (PyObject *self) } /* Implementation of - BtraceList.__getitem__ (self, key) -> BtraceInstruction and - BtraceList.__getitem__ (self, key) -> BtraceFunctionCall. */ + BtraceList.__getitem__ (self, key) -> BtraceInstruction, + BtraceList.__getitem__ (self, key) -> BtraceFunctionCall, + BtraceList.__getitem__ (self, key) -> BtraceAuxiliary. */ static PyObject * btpy_list_item (PyObject *self, Py_ssize_t index) @@ -454,10 +510,13 @@ btpy_list_item (PyObject *self, Py_ssize_t index) number = obj->first + (obj->step * index); - if (obj->element_type == &recpy_insn_type) - return recpy_insn_new (obj->thread, RECORD_METHOD_BTRACE, number); - else + if (obj->element_type == &recpy_func_type) return recpy_func_new (obj->thread, RECORD_METHOD_BTRACE, number); + else if (obj->element_type == &recpy_insn_type + || obj->element_type == &recpy_aux_type) + return btpy_item_new (obj->thread, number); + else + return PyErr_Format (gdbpy_gdb_error, _("Not a valid BtraceList object.")); } /* Implementation of BtraceList.__getitem__ (self, slice) -> BtraceList. */ @@ -644,8 +703,7 @@ recpy_bt_replay_position (PyObject *self, void *closure) if (tinfo->btrace.replay == NULL) Py_RETURN_NONE; - return btpy_insn_or_gap_new (tinfo, - btrace_insn_number (tinfo->btrace.replay)); + return btpy_item_new (tinfo, btrace_insn_number (tinfo->btrace.replay)); } /* Implementation of @@ -667,7 +725,7 @@ recpy_bt_begin (PyObject *self, void *closure) Py_RETURN_NONE; btrace_insn_begin (&iterator, &tinfo->btrace); - return btpy_insn_or_gap_new (tinfo, btrace_insn_number (&iterator)); + return btpy_item_new (tinfo, btrace_insn_number (&iterator)); } /* Implementation of @@ -689,7 +747,7 @@ recpy_bt_end (PyObject *self, void *closure) Py_RETURN_NONE; btrace_insn_end (&iterator, &tinfo->btrace); - return btpy_insn_or_gap_new (tinfo, btrace_insn_number (&iterator)); + return btpy_item_new (tinfo, btrace_insn_number (&iterator)); } /* Implementation of @@ -750,6 +808,109 @@ recpy_bt_function_call_history (PyObject *self, void *closure) return btpy_list_new (tinfo, first, last, 1, &recpy_func_type); } +/* Helper function that calls PTW_FILTER with PAYLOAD and IP as arguments. + Returns the string that will be printed, if there is a filter to call. */ +static std::optional<std::string> +recpy_call_filter (const uint64_t payload, const uint64_t ip, + const void *ptw_filter) +{ + std::optional<std::string> result; + + gdb_assert (ptw_filter != nullptr); + if ((PyObject *) ptw_filter == Py_None) + return result; + + gdbpy_enter enter_py; + + gdbpy_ref<> py_payload = gdb_py_object_from_ulongest (payload); + + gdbpy_ref<> py_ip; + if (ip == 0) + py_ip = gdbpy_ref<>::new_reference (Py_None); + else + py_ip = gdb_py_object_from_ulongest (ip); + + gdbpy_ref<> py_result (PyObject_CallFunctionObjArgs ((PyObject *) ptw_filter, + py_payload.get (), + py_ip.get (), + nullptr)); + + if (py_result == nullptr) + { + gdbpy_print_stack (); + gdbpy_error (_("Couldn't call the ptwrite filter.")); + } + + /* Py_None is valid and results in no output. */ + if (py_result == Py_None) + { + result = ""; + return result; + } + + gdb::unique_xmalloc_ptr<char> user_string + = gdbpy_obj_to_string (py_result.get ()); + + if (user_string == nullptr) + { + gdbpy_print_stack (); + gdbpy_error (_("The ptwrite filter didn't return a string.")); + } + else + result = user_string.get (); + + return result; +} + +/* Helper function returning the current ptwrite filter. */ + +static PyObject * +get_ptwrite_filter () +{ + gdbpy_ref<> module (PyImport_ImportModule ("gdb.ptwrite")); + + if (PyErr_Occurred ()) + { + gdbpy_print_stack (); + gdbpy_error (_("Couldn't import gdb.ptwrite.")); + } + + /* We need to keep the reference count. */ + gdbpy_ref<> ptw_filter (gdbpy_call_method (module.get (), "get_filter")); + + if (PyErr_Occurred ()) + { + gdbpy_print_stack (); + gdbpy_error (_("Couldn't get the ptwrite filter.")); + } + + return ptw_filter.get(); +} + +/* Used for registering any python ptwrite filter to the current thread. A + pointer to this function is stored in the python extension interface. */ + +void +gdbpy_load_ptwrite_filter (const struct extension_language_defn *extlang, + struct btrace_thread_info *btinfo) +{ + gdb_assert (btinfo != nullptr); + + gdbpy_enter enter_py; + + btinfo->ptw_context = get_ptwrite_filter (); + +#if defined (HAVE_STRUCT_PT_EVENT_VARIANT_PTWRITE) + if (!btinfo->target->conf.pt.ptwrite && btinfo->ptw_context != Py_None) + warning (_("The target doesn't support decoding ptwrite events.")); +#else + if (btinfo->ptw_context != Py_None) + warning (_("Libipt doesn't support decoding ptwrite events.")); +#endif /* defined (HAVE_STRUCT_PT_EVENT_VARIANT_PTWRITE) */ + + btinfo->ptw_callback_fun = &recpy_call_filter; +} + /* Implementation of BtraceRecord.goto (self, BtraceInstruction) -> None. */ PyObject * @@ -789,6 +950,19 @@ recpy_bt_goto (PyObject *self, PyObject *args) Py_RETURN_NONE; } +/* Implementation of BtraceRecord.clear (self) -> None. */ + +PyObject * +recpy_bt_clear (PyObject *self, PyObject *args) +{ + const recpy_record_object * const record = (recpy_record_object *) self; + thread_info *const tinfo = record->thread; + + btrace_clear (tinfo); + + Py_RETURN_NONE; +} + /* BtraceList methods. */ static PyMethodDef btpy_list_methods[] = diff --git a/gdb/python/py-record-btrace.h b/gdb/python/py-record-btrace.h index 8678e77..3be5860 100644 --- a/gdb/python/py-record-btrace.h +++ b/gdb/python/py-record-btrace.h @@ -31,6 +31,9 @@ extern PyObject *recpy_bt_format (PyObject *self, void *closure); /* Implementation of record.goto (instruction) -> None. */ extern PyObject *recpy_bt_goto (PyObject *self, PyObject *value); +/* Implementation of BtraceRecord.clear (self) -> None. */ +extern PyObject *recpy_bt_clear (PyObject *self, PyObject *args); + /* Implementation of record.instruction_history [list]. */ extern PyObject *recpy_bt_instruction_history (PyObject *self, void *closure); @@ -88,4 +91,7 @@ extern PyObject *recpy_bt_func_prev (PyObject *self, void *closure); /* Implementation of RecordFunctionSegment.next [RecordFunctionSegment]. */ extern PyObject *recpy_bt_func_next (PyObject *self, void *closure); +/* Implementation of RecordAuxiliary.decoded [str]. */ +extern PyObject *recpy_bt_aux_data (PyObject *self, void *closure); + #endif /* PYTHON_PY_RECORD_BTRACE_H */ diff --git a/gdb/python/py-record.c b/gdb/python/py-record.c index d489126..2e0834c 100644 --- a/gdb/python/py-record.c +++ b/gdb/python/py-record.c @@ -48,6 +48,12 @@ static PyTypeObject recpy_gap_type = { PyVarObject_HEAD_INIT (NULL, 0) }; +/* Python RecordAuxiliary type. */ + +PyTypeObject recpy_aux_type = { + PyVarObject_HEAD_INIT (nullptr, 0) +}; + /* Python RecordGap object. */ struct recpy_gap_object { @@ -108,6 +114,19 @@ recpy_goto (PyObject *self, PyObject *value) return PyErr_Format (PyExc_NotImplementedError, _("Not implemented.")); } +/* Implementation of record.clear () -> None. */ + +static PyObject * +recpy_clear (PyObject *self, PyObject *value) +{ + const recpy_record_object * const obj = (recpy_record_object *) self; + + if (obj->method == RECORD_METHOD_BTRACE) + return recpy_bt_clear (self, value); + + return PyErr_Format (PyExc_NotImplementedError, _("Not implemented.")); +} + /* Implementation of record.replay_position [instruction] */ static PyObject * @@ -389,8 +408,8 @@ recpy_element_hash (PyObject *self) return obj->number; } -/* Implementation of operator == and != of RecordInstruction and - RecordFunctionSegment. */ +/* Implementation of operator == and != of RecordInstruction, + RecordFunctionSegment and RecordAuxiliary. */ static PyObject * recpy_element_richcompare (PyObject *self, PyObject *other, int op) @@ -478,12 +497,47 @@ recpy_gap_reason_string (PyObject *self, void *closure) return PyUnicode_FromString (obj->reason_string); } +/* Create a new gdb.Auxiliary object. */ + +PyObject * +recpy_aux_new (thread_info *thread, enum record_method method, + Py_ssize_t number) +{ + recpy_element_object * const obj = PyObject_New (recpy_element_object, + &recpy_aux_type); + + if (obj == NULL) + return NULL; + + obj->thread = thread; + obj->method = method; + obj->number = number; + + return (PyObject *) obj; +} + +/* Implementation of Auxiliary.data [buffer]. */ + +static PyObject * +recpy_aux_data (PyObject *self, void *closure) +{ + const recpy_element_object * const obj = (recpy_element_object *) self; + + if (obj->method == RECORD_METHOD_BTRACE) + return recpy_bt_aux_data (self, closure); + + return PyErr_Format (PyExc_NotImplementedError, _("Not implemented.")); +} + /* Record method list. */ static PyMethodDef recpy_record_methods[] = { { "goto", recpy_goto, METH_VARARGS, "goto (instruction|function_call) -> None.\n\ Rewind to given location."}, + { "clear", recpy_clear, METH_VARARGS, + "clear () -> None.\n\ +Clears the trace."}, { NULL } }; @@ -543,6 +597,14 @@ static gdb_PyGetSetDef recpy_gap_getset[] = { { NULL } }; +/* RecordAuxiliary member list. */ + +static gdb_PyGetSetDef recpy_aux_getset[] = { + { "number", recpy_element_number, nullptr, "element number", nullptr}, + { "data", recpy_aux_data, nullptr, "data", nullptr}, + { nullptr } +}; + /* Sets up the record API in the gdb module. */ static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION @@ -582,10 +644,20 @@ gdbpy_initialize_record (void) recpy_gap_type.tp_doc = "GDB recorded gap object"; recpy_gap_type.tp_getset = recpy_gap_getset; + recpy_aux_type.tp_new = PyType_GenericNew; + recpy_aux_type.tp_flags = Py_TPFLAGS_DEFAULT; + recpy_aux_type.tp_basicsize = sizeof (recpy_element_object); + recpy_aux_type.tp_name = "gdb.RecordAuxiliary"; + recpy_aux_type.tp_doc = "GDB recorded auxiliary object"; + recpy_aux_type.tp_getset = recpy_aux_getset; + recpy_aux_type.tp_richcompare = recpy_element_richcompare; + recpy_aux_type.tp_hash = recpy_element_hash; + if (PyType_Ready (&recpy_record_type) < 0 || PyType_Ready (&recpy_insn_type) < 0 || PyType_Ready (&recpy_func_type) < 0 - || PyType_Ready (&recpy_gap_type) < 0) + || PyType_Ready (&recpy_gap_type) < 0 + || PyType_Ready (&recpy_aux_type) < 0) return -1; else return 0; diff --git a/gdb/python/py-record.h b/gdb/python/py-record.h index 7e11610..0988584 100644 --- a/gdb/python/py-record.h +++ b/gdb/python/py-record.h @@ -59,6 +59,9 @@ extern PyTypeObject recpy_insn_type; /* Python RecordFunctionSegment type. */ extern PyTypeObject recpy_func_type; +/* Python RecordAuxiliary type. */ +extern PyTypeObject recpy_aux_type; + /* Create a new gdb.RecordInstruction object. */ extern PyObject *recpy_insn_new (thread_info *thread, enum record_method method, Py_ssize_t number); @@ -71,4 +74,8 @@ extern PyObject *recpy_func_new (thread_info *thread, enum record_method method, extern PyObject *recpy_gap_new (int reason_code, const char *reason_string, Py_ssize_t number); +/* Create a new gdb.RecordGap object. */ +extern PyObject *recpy_aux_new (thread_info *thread, enum record_method method, + Py_ssize_t number); + #endif /* PYTHON_PY_RECORD_H */ diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c index dada8bf..5c62ef6 100644 --- a/gdb/python/py-value.c +++ b/gdb/python/py-value.c @@ -1258,7 +1258,8 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords) if (ftype->code () == TYPE_CODE_INTERNAL_FUNCTION) return_value = call_internal_function (gdbpy_enter::get_gdbarch (), current_language, - function, args_count, vargs); + function, args_count, vargs, + EVAL_NORMAL); else return_value = call_function_by_hand (function, NULL, diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index f25cd3b..bf3ab67 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -464,6 +464,9 @@ extern enum ext_lang_rc gdbpy_apply_val_pretty_printer struct ui_file *stream, int recurse, const struct value_print_options *options, const struct language_defn *language); +extern void gdbpy_load_ptwrite_filter + (const struct extension_language_defn *extlang, + struct btrace_thread_info *btinfo); extern enum ext_lang_bt_status gdbpy_apply_frame_filter (const struct extension_language_defn *, const frame_info_ptr &frame, frame_filter_flags flags, @@ -948,7 +951,7 @@ private: int gdbpy_print_python_errors_p (void); void gdbpy_print_stack (void); void gdbpy_print_stack_or_quit (); -void gdbpy_handle_exception () ATTRIBUTE_NORETURN; +[[noreturn]] void gdbpy_handle_exception (); /* A wrapper around calling 'error'. Prefixes the error message with an 'Error occurred in Python' string. Use this in C++ code if we spot @@ -958,8 +961,7 @@ void gdbpy_handle_exception () ATTRIBUTE_NORETURN; This always calls error, and never returns. */ -void gdbpy_error (const char *fmt, ...) - ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 2); +[[noreturn]] void gdbpy_error (const char *fmt, ...) ATTRIBUTE_PRINTF (1, 2); gdbpy_ref<> python_string_to_unicode (PyObject *obj); gdb::unique_xmalloc_ptr<char> unicode_to_target_string (PyObject *unicode_str); diff --git a/gdb/python/python.c b/gdb/python/python.c index e9092b4..043c221 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -159,6 +159,8 @@ static const struct extension_language_ops python_extension_ops = gdbpy_apply_frame_filter, + gdbpy_load_ptwrite_filter, + gdbpy_preserve_values, gdbpy_breakpoint_has_cond, @@ -963,7 +965,7 @@ gdbpy_decode_line (PyObject *self, PyObject *args) else { set_default_source_symtab_and_line (); - def_sal = get_current_source_symtab_and_line (); + def_sal = get_current_source_symtab_and_line (current_program_space); sals = def_sal; } } diff --git a/gdb/quick-symbol.h b/gdb/quick-symbol.h index 676c3ed..d6de734 100644 --- a/gdb/quick-symbol.h +++ b/gdb/quick-symbol.h @@ -163,8 +163,8 @@ struct quick_symbol_functions compunit that contains a symbol whose address is closest to PC. */ virtual struct compunit_symtab *find_pc_sect_compunit_symtab - (struct objfile *objfile, struct bound_minimal_symbol msymbol, - CORE_ADDR pc, struct obj_section *section, int warn_if_readin) = 0; + (struct objfile *objfile, bound_minimal_symbol msymbol, CORE_ADDR pc, + struct obj_section *section, int warn_if_readin) = 0; /* Return the comp unit from OBJFILE that contains a symbol at ADDRESS. Return NULL if there is no such comp unit. Unlike diff --git a/gdb/ravenscar-thread.c b/gdb/ravenscar-thread.c index 1957f3c..47db72b 100644 --- a/gdb/ravenscar-thread.c +++ b/gdb/ravenscar-thread.c @@ -326,18 +326,17 @@ ravenscar_thread_target::add_active_thread () and return its associated minimal symbol. Return NULL if not found. */ -static struct bound_minimal_symbol +static bound_minimal_symbol get_running_thread_msymbol () { - struct bound_minimal_symbol msym; - - msym = lookup_minimal_symbol (running_thread_name, NULL, NULL); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, running_thread_name); if (!msym.minsym) /* Older versions of the GNAT runtime were using a different (less ideal) name for the symbol where the active thread ID is stored. If we couldn't find the symbol using the latest name, then try the old one. */ - msym = lookup_minimal_symbol ("running_thread", NULL, NULL); + msym = lookup_minimal_symbol (current_program_space, "running_thread"); return msym; } @@ -348,14 +347,14 @@ get_running_thread_msymbol () static bool has_ravenscar_runtime () { - struct bound_minimal_symbol msym_ravenscar_runtime_initializer - = lookup_minimal_symbol (ravenscar_runtime_initializer, NULL, NULL); - struct bound_minimal_symbol msym_known_tasks - = lookup_minimal_symbol (known_tasks_name, NULL, NULL); - struct bound_minimal_symbol msym_first_task - = lookup_minimal_symbol (first_task_name, NULL, NULL); - struct bound_minimal_symbol msym_running_thread - = get_running_thread_msymbol (); + bound_minimal_symbol msym_ravenscar_runtime_initializer + = lookup_minimal_symbol (current_program_space, + ravenscar_runtime_initializer); + bound_minimal_symbol msym_known_tasks + = lookup_minimal_symbol (current_program_space, known_tasks_name); + bound_minimal_symbol msym_first_task + = lookup_minimal_symbol (current_program_space, first_task_name); + bound_minimal_symbol msym_running_thread = get_running_thread_msymbol (); return (msym_ravenscar_runtime_initializer.minsym && (msym_known_tasks.minsym || msym_first_task.minsym) @@ -377,7 +376,7 @@ ravenscar_thread_target::runtime_initialized () static CORE_ADDR get_running_thread_id (int cpu) { - struct bound_minimal_symbol object_msym = get_running_thread_msymbol (); + bound_minimal_symbol object_msym = get_running_thread_msymbol (); int object_size; int buf_size; gdb_byte *buf; @@ -642,7 +641,8 @@ ravenscar_thread_target::get_fpu_state (struct regcache *regcache, return NOTHING_SPECIAL; bound_minimal_symbol fpu_context - = lookup_minimal_symbol ("system__bb__cpu_primitives__current_fpu_context", + = lookup_minimal_symbol (current_program_space, + "system__bb__cpu_primitives__current_fpu_context", nullptr, nullptr); /* If the symbol can't be found, just fall back. */ if (fpu_context.minsym == nullptr) diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index 9fec611..997f442 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -827,6 +827,22 @@ btrace_insn_history (struct ui_out *uiout, btrace_ui_out_decode_error (uiout, btrace_insn_get_error (&it), conf->format); } + else if (insn->iclass == BTRACE_INSN_AUX) + { + if ((flags & DISASSEMBLY_OMIT_AUX_INSN) != 0) + continue; + + uiout->field_fmt ("insn-number", "%u", btrace_insn_number (&it)); + uiout->text ("\t"); + /* Add 3 spaces to match the instructions and 2 to indent the aux + string to make it more visible. */ + uiout->spaces (5); + uiout->text ("["); + uiout->field_fmt ("aux-data", "%s", + it.btinfo->aux_data.at + (insn->aux_data_index).c_str ()); + uiout->text ("]\n"); + } else { struct disasm_insn dinsn; @@ -1145,6 +1161,31 @@ btrace_get_bfun_name (const struct btrace_function *bfun) return "??"; } +static void +btrace_print_aux_insn (struct ui_out *uiout, + const struct btrace_function *bfun, + const struct btrace_thread_info *btinfo, + int level) +{ + for (const btrace_insn &insn : bfun->insn) + { + if (insn.iclass == BTRACE_INSN_AUX) + { + /* Indent to the function level. */ + uiout->text ("\t"); + /* Adjust for RECORD_PRINT_INDENT_CALLS and indent one + additional level. */ + for (int i = 0; i <= level; ++i) + uiout->text (" "); + + uiout->text ("["); + uiout->field_fmt ("aux-data", "%s", + btinfo->aux_data.at (insn.aux_data_index).c_str ()); + uiout->text ("]\n"); + } + } +} + /* Disassemble a section of the recorded function trace. */ static void @@ -1165,6 +1206,7 @@ btrace_call_history (struct ui_out *uiout, const struct btrace_function *bfun; struct minimal_symbol *msym; struct symbol *sym; + int level = 0; bfun = btrace_call_get (&it); sym = bfun->sym; @@ -1191,9 +1233,9 @@ btrace_call_history (struct ui_out *uiout, if ((flags & RECORD_PRINT_INDENT_CALLS) != 0) { - int level = bfun->level + btinfo->level, i; + level = bfun->level + btinfo->level; - for (i = 0; i < level; ++i) + for (int i = 0; i < level; ++i) uiout->text (" "); } @@ -1220,6 +1262,10 @@ btrace_call_history (struct ui_out *uiout, } uiout->text ("\n"); + + if (((flags & RECORD_DONT_PRINT_AUX) == 0) + && ((bfun->flags & BFUN_CONTAINS_AUX) != 0)) + btrace_print_aux_insn (uiout, bfun, btinfo, level); } } @@ -2345,9 +2391,13 @@ record_btrace_single_step_forward (struct thread_info *tp) return btrace_step_stopped (); /* Skip gaps during replay. If we end up at a gap (at the end of the trace), - jump back to the instruction at which we started. */ + jump back to the instruction at which we started. If we're stepping a + BTRACE_INSN_AUX instruction, print the auxiliary data and skip the + instruction. */ + start = *replay; - do + + for (;;) { unsigned int steps; @@ -2359,8 +2409,23 @@ record_btrace_single_step_forward (struct thread_info *tp) *replay = start; return btrace_step_no_history (); } + + const struct btrace_insn *insn = btrace_insn_get (replay); + if (insn == nullptr) + continue; + + /* If we're stepping a BTRACE_INSN_AUX instruction, print the auxiliary + data and skip the instruction. */ + if (insn->iclass == BTRACE_INSN_AUX) + { + gdb_printf ("[%s]\n", + btinfo->aux_data.at (insn->aux_data_index).c_str ()); + continue; + } + + /* We have an instruction, we are done. */ + break; } - while (btrace_insn_get (replay) == NULL); /* Determine the end of the instruction trace. */ btrace_insn_end (&end, btinfo); @@ -2391,9 +2456,12 @@ record_btrace_single_step_backward (struct thread_info *tp) /* If we can't step any further, we reached the end of the history. Skip gaps during replay. If we end up at a gap (at the beginning of - the trace), jump back to the instruction at which we started. */ + the trace), jump back to the instruction at which we started. + If we're stepping a BTRACE_INSN_AUX instruction, print the auxiliary + data and skip the instruction. */ start = *replay; - do + + for (;;) { unsigned int steps; @@ -2403,8 +2471,22 @@ record_btrace_single_step_backward (struct thread_info *tp) *replay = start; return btrace_step_no_history (); } + + const struct btrace_insn *insn = btrace_insn_get (replay); + if (insn == nullptr) + continue; + + /* Check if we're stepping a BTRACE_INSN_AUX instruction and skip it. */ + if (insn->iclass == BTRACE_INSN_AUX) + { + gdb_printf ("[%s]\n", + btinfo->aux_data.at (insn->aux_data_index).c_str ()); + continue; + } + + /* We have an instruction, we are done. */ + break; } - while (btrace_insn_get (replay) == NULL); /* Check if we're stepping a breakpoint. @@ -2826,26 +2908,33 @@ record_btrace_target::goto_record_end () /* The goto_record method of target record-btrace. */ void -record_btrace_target::goto_record (ULONGEST insn) +record_btrace_target::goto_record (ULONGEST insn_number) { struct thread_info *tp; struct btrace_insn_iterator it; unsigned int number; int found; - number = insn; + number = insn_number; /* Check for wrap-arounds. */ - if (number != insn) + if (number != insn_number) error (_("Instruction number out of range.")); tp = require_btrace_thread (); found = btrace_find_insn_by_number (&it, &tp->btrace, number); - /* Check if the instruction could not be found or is a gap. */ - if (found == 0 || btrace_insn_get (&it) == NULL) + /* Check if the instruction could not be found or is a gap or an + auxiliary instruction. */ + if (found == 0) + error (_("No such instruction.")); + + const struct btrace_insn *insn = btrace_insn_get (&it); + if (insn == NULL) error (_("No such instruction.")); + if (insn->iclass == BTRACE_INSN_AUX) + error (_("Can't go to an auxiliary instruction.")); record_btrace_set_replay (tp, &it); } @@ -3217,4 +3306,9 @@ to see the actual buffer size."), NULL, show_record_pt_buffer_size_value, record_btrace_conf.bts.size = 64 * 1024; record_btrace_conf.pt.size = 16 * 1024; +#if (LIBIPT_VERSION >= 0x200) + record_btrace_conf.pt.ptwrite = true; +#else + record_btrace_conf.pt.ptwrite = false; +#endif } diff --git a/gdb/record-full.c b/gdb/record-full.c index eb62d18..ab854e0 100644 --- a/gdb/record-full.c +++ b/gdb/record-full.c @@ -2073,6 +2073,7 @@ record_full_core_target::resume (ptid_t ptid, int step, enum gdb_signal signal) { record_full_resume_step = step; + record_full_resume_ptid = ptid; record_full_resumed = 1; record_full_execution_dir = ::execution_direction; } diff --git a/gdb/record.c b/gdb/record.c index b254457..d84af60 100644 --- a/gdb/record.c +++ b/gdb/record.c @@ -491,6 +491,9 @@ get_insn_history_modifiers (const char **arg) switch (*args) { + case 'a': + modifiers |= DISASSEMBLY_OMIT_AUX_INSN; + break; case 'm': case 's': modifiers |= DISASSEMBLY_SOURCE; @@ -641,6 +644,9 @@ get_call_history_modifiers (const char **arg) case 'c': modifiers |= RECORD_PRINT_INDENT_CALLS; break; + case 'a': + modifiers |= RECORD_DONT_PRINT_AUX; + break; default: error (_("Invalid modifier: %c."), *args); } @@ -859,6 +865,8 @@ With a /m or /s modifier, source lines are included (if available).\n\ With a /r modifier, raw instructions in hex are included.\n\ With a /f modifier, function names are omitted.\n\ With a /p modifier, current position markers are omitted.\n\ +With a /a modifier, omits output of auxiliary data, which is enabled \ +by default.\n\ With no argument, disassembles ten more instructions after the previous \ disassembly.\n\ \"record instruction-history -\" disassembles ten instructions before a \ @@ -881,6 +889,8 @@ Without modifiers, it prints the function name.\n\ With a /l modifier, the source file and line number range is included.\n\ With a /i modifier, the instruction number range is included.\n\ With a /c modifier, the output is indented based on the call stack depth.\n\ +With a /a modifier, omits output of auxiliary data, which is enabled \ +by default.\n\ With no argument, prints ten more lines after the previous ten-line print.\n\ \"record function-call-history -\" prints ten lines before a previous ten-line \ print.\n\ diff --git a/gdb/record.h b/gdb/record.h index f44b395..aea6507 100644 --- a/gdb/record.h +++ b/gdb/record.h @@ -62,7 +62,10 @@ enum record_print_flag RECORD_PRINT_INSN_RANGE = (1 << 1), /* Indent based on call stack depth (if applicable). */ - RECORD_PRINT_INDENT_CALLS = (1 << 2) + RECORD_PRINT_INDENT_CALLS = (1 << 2), + + /* Deactivate printing auxiliary data (if applicable). */ + RECORD_DONT_PRINT_AUX = (1 << 3) }; DEF_ENUM_FLAGS_TYPE (enum record_print_flag, record_print_flags); diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c index f92de61..67d3f4c 100644 --- a/gdb/remote-sim.c +++ b/gdb/remote-sim.c @@ -69,8 +69,7 @@ static void gdb_os_vprintf_filtered (host_callback *, const char *, va_list); static void gdb_os_evprintf_filtered (host_callback *, const char *, va_list); -static void gdb_os_error (host_callback *, const char *, ...) - ATTRIBUTE_NORETURN; +[[noreturn]] static void gdb_os_error (host_callback *, const char *, ...); /* Naming convention: diff --git a/gdb/remote.c b/gdb/remote.c index 90a4bd5..2c3988c 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -248,6 +248,7 @@ enum { PACKET_vFile_unlink, PACKET_vFile_readlink, PACKET_vFile_fstat, + PACKET_vFile_stat, PACKET_qXfer_auxv, PACKET_qXfer_features, PACKET_qXfer_exec_file, @@ -360,6 +361,9 @@ enum { /* Support for the Qbtrace-conf:pt:size packet. */ PACKET_Qbtrace_conf_pt_size, + /* Support for the Qbtrace-conf:pt:ptwrite packet. */ + PACKET_Qbtrace_conf_pt_ptwrite, + /* Support for exec events. */ PACKET_exec_event_feature, @@ -1010,6 +1014,9 @@ public: int fileio_fstat (int fd, struct stat *sb, fileio_error *target_errno) override; + int fileio_stat (struct inferior *inf, const char *filename, + struct stat *sb, fileio_error *target_errno) override; + int fileio_close (int fd, fileio_error *target_errno) override; int fileio_unlink (struct inferior *inf, @@ -1539,7 +1546,7 @@ static void remote_console_output (const char *msg, ui_file *stream); static void remote_btrace_reset (remote_state *rs); -static void remote_unpush_and_throw (remote_target *target); +[[noreturn]] static void remote_unpush_and_throw (remote_target *target); /* For "remote". */ @@ -2528,9 +2535,6 @@ packet_check_result (const char *buf) /* "Enn" - definitely an error. */ return packet_result::make_numeric_error (buf + 1); - /* Not every request accepts an error in a E.msg form. - Some packets accepts only Enn, in this case E. is not - defined and E. is treated as PACKET_OK. */ /* Always treat "E." as an error. This will be used for more verbose error messages, such as E.memtypes. */ if (buf[0] == 'E' && buf[1] == '.') @@ -3377,17 +3381,6 @@ struct gdb_ext_thread_info whatever. */ }; -/* The volume of remote transfers can be limited by submitting - a mask containing bits specifying the desired information. - Use a union of these values as the 'selection' parameter to - get_thread_info. FIXME: Make these TAG names more thread specific. */ - -#define TAG_THREADID 1 -#define TAG_EXISTS 2 -#define TAG_DISPLAY 4 -#define TAG_THREADNAME 8 -#define TAG_MOREDISPLAY 16 - #define BUF_THREAD_ID_SIZE (OPAQUETHREADBYTES * 2) static const char *unpack_nibble (const char *buf, int *val); @@ -5514,13 +5507,12 @@ remote_target::remote_check_symbols () while (startswith (reply.data (), "qSymbol:")) { - struct bound_minimal_symbol sym; - tmp = &reply[8]; end = hex2bin (tmp, reinterpret_cast <gdb_byte *> (msg.data ()), strlen (tmp) / 2); msg[end] = '\0'; - sym = lookup_minimal_symbol (msg.data (), NULL, NULL); + bound_minimal_symbol sym + = lookup_minimal_symbol (current_program_space, msg.data ()); if (sym.minsym == NULL) xsnprintf (msg.data (), get_remote_packet_size (), "qSymbol::%s", &reply[8]); @@ -5821,6 +5813,8 @@ static const struct protocol_feature remote_protocol_features[] = { PACKET_exec_event_feature }, { "Qbtrace-conf:pt:size", PACKET_DISABLE, remote_supported_packet, PACKET_Qbtrace_conf_pt_size }, + { "Qbtrace-conf:pt:ptwrite", PACKET_DISABLE, remote_supported_packet, + PACKET_Qbtrace_conf_pt_ptwrite }, { "vContSupported", PACKET_DISABLE, remote_supported_packet, PACKET_vContSupported }, { "QThreadEvents", PACKET_DISABLE, remote_supported_packet, PACKET_QThreadEvents }, { "QThreadOptions", PACKET_DISABLE, remote_supported_thread_options, @@ -5950,7 +5944,7 @@ remote_target::remote_query_supported () if (m_features.packet_set_cmd_state (PACKET_accept_error_message) != AUTO_BOOLEAN_FALSE) - remote_query_supported_append (&q, "error-message+"); + remote_query_supported_append (&q, "error-message+"); q = "qSupported:" + q; putpkt (q.c_str ()); @@ -6150,7 +6144,7 @@ remote_unpush_target (remote_target *target) fileio_handles_invalidate_target (target); } -static void +[[noreturn]] static void remote_unpush_and_throw (remote_target *target) { remote_unpush_target (target); @@ -6271,7 +6265,7 @@ remote_target::open_1 (const char *name, int from_tty, int extended_p) } /* First delete any symbols previously loaded from shared libraries. */ - no_shared_libraries (NULL, 0); + no_shared_libraries (current_program_space); /* Start the remote connection. If error() or QUIT, discard this target (we'd otherwise be in an inconsistent state) and then @@ -13048,6 +13042,41 @@ remote_target::fileio_readlink (struct inferior *inf, const char *filename, return ret; } +/* Helper function to handle ::fileio_fstat and ::fileio_stat result + processing. When this function is called the remote syscall has been + performed and we know we didn't get an error back. + + ATTACHMENT and ATTACHMENT_LEN are the attachment data extracted from the + remote syscall reply. EXPECTED_LEN is the length returned from the + fstat or stat call, this the length of the returned data (in ATTACHMENT) + once it has been decoded. The fstat/stat result (from the ATTACHMENT + data) is to be placed in ST. */ + +static int +fileio_process_fstat_and_stat_reply (const char *attachment, + int attachment_len, + int expected_len, + struct stat *st) +{ + struct fio_stat fst; + + int read_len + = remote_unescape_input ((gdb_byte *) attachment, attachment_len, + (gdb_byte *) &fst, sizeof (fst)); + + if (read_len != expected_len) + error (_("vFile:fstat returned %d, but %d bytes."), + expected_len, read_len); + + if (read_len != sizeof (fst)) + error (_("vFile:fstat returned %d bytes, but expecting %d."), + read_len, (int) sizeof (fst)); + + remote_fileio_to_host_stat (&fst, st); + + return 0; +} + /* Implementation of to_fileio_fstat. */ int @@ -13058,8 +13087,6 @@ remote_target::fileio_fstat (int fd, struct stat *st, fileio_error *remote_errno int left = get_remote_packet_size (); int attachment_len, ret; const char *attachment; - struct fio_stat fst; - int read_len; remote_buffer_add_string (&p, &left, "vFile:fstat:"); @@ -13091,19 +13118,41 @@ remote_target::fileio_fstat (int fd, struct stat *st, fileio_error *remote_errno return 0; } - read_len = remote_unescape_input ((gdb_byte *) attachment, attachment_len, - (gdb_byte *) &fst, sizeof (fst)); + return fileio_process_fstat_and_stat_reply (attachment, attachment_len, + ret, st); +} - if (read_len != ret) - error (_("vFile:fstat returned %d, but %d bytes."), ret, read_len); +/* Implementation of to_fileio_stat. */ - if (read_len != sizeof (fst)) - error (_("vFile:fstat returned %d bytes, but expecting %d."), - read_len, (int) sizeof (fst)); +int +remote_target::fileio_stat (struct inferior *inf, const char *filename, + struct stat *st, fileio_error *remote_errno) +{ + struct remote_state *rs = get_remote_state (); + char *p = rs->buf.data (); + int left = get_remote_packet_size () - 1; - remote_fileio_to_host_stat (&fst, st); + if (remote_hostio_set_filesystem (inf, remote_errno) != 0) + return {}; - return 0; + remote_buffer_add_string (&p, &left, "vFile:stat:"); + + remote_buffer_add_bytes (&p, &left, (const gdb_byte *) filename, + strlen (filename)); + + int attachment_len; + const char *attachment; + int ret = remote_hostio_send_command (p - rs->buf.data (), PACKET_vFile_stat, + remote_errno, &attachment, + &attachment_len); + + /* Unlike ::fileio_fstat, the stat fileio call was added later on, and + has none of the legacy bfd issues, so we can just return the error. */ + if (ret < 0) + return ret; + + return fileio_process_fstat_and_stat_reply (attachment, attachment_len, + ret, st); } /* Implementation of to_filesystem_is_local. */ @@ -14692,7 +14741,7 @@ parse_xml_btrace_conf_pt (struct gdb_xml_parser *parser, std::vector<gdb_xml_value> &attributes) { struct btrace_config *conf; - struct gdb_xml_value *size; + struct gdb_xml_value *size, *ptwrite; conf = (struct btrace_config *) user_data; conf->format = BTRACE_FORMAT_PT; @@ -14701,10 +14750,16 @@ parse_xml_btrace_conf_pt (struct gdb_xml_parser *parser, size = xml_find_attribute (attributes, "size"); if (size != NULL) conf->pt.size = (unsigned int) *(ULONGEST *) size->value.get (); + + ptwrite = xml_find_attribute (attributes, "ptwrite"); + if (ptwrite != nullptr) + conf->pt.ptwrite = (bool) *(ULONGEST *) ptwrite->value.get (); } static const struct gdb_xml_attribute btrace_conf_pt_attributes[] = { { "size", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL }, + { "ptwrite", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum, + gdb_xml_enums_boolean }, { NULL, GDB_XML_AF_NONE, NULL, NULL } }; @@ -14810,6 +14865,32 @@ remote_target::btrace_sync_conf (const btrace_config *conf) rs->btrace_config.pt.size = conf->pt.size; } + + if ((m_features.packet_support (PACKET_Qbtrace_conf_pt_ptwrite) + == PACKET_ENABLE) + && conf->pt.ptwrite != rs->btrace_config.pt.ptwrite) + { + pos = buf; + const char *ptw = conf->pt.ptwrite ? "yes" : "no"; + const char *name + = packets_descriptions[PACKET_Qbtrace_conf_pt_ptwrite].name; + pos += xsnprintf (pos, endbuf - pos, "%s=\"%s\"", name, ptw); + + putpkt (buf); + getpkt (&rs->buf, 0); + + packet_result result + = m_features.packet_ok (buf, PACKET_Qbtrace_conf_pt_ptwrite); + if (result.status () == PACKET_ERROR) + { + if (buf[0] == 'E' && buf[1] == '.') + error (_("Failed to sync ptwrite config: %s"), buf + 2); + else + error (_("Failed to sync ptwrite config.")); + } + + rs->btrace_config.pt.ptwrite = conf->pt.ptwrite; + } } /* Read TP's btrace configuration from the target and store it into CONF. */ @@ -15444,7 +15525,7 @@ remote_objfile_changed_check_symbols (program_space *pspace) static void remote_new_objfile (struct objfile *objfile) { - remote_objfile_changed_check_symbols (objfile->pspace); + remote_objfile_changed_check_symbols (objfile->pspace ()); } /* Pull all the tracepoints defined on the target and create local @@ -16178,6 +16259,8 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL, add_packet_config_cmd (PACKET_vFile_fstat, "vFile:fstat", "hostio-fstat", 0); + add_packet_config_cmd (PACKET_vFile_stat, "vFile:stat", "hostio-stat", 0); + add_packet_config_cmd (PACKET_vAttach, "vAttach", "attach", 0); add_packet_config_cmd (PACKET_vRun, "vRun", "run", 0); @@ -16262,6 +16345,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL, add_packet_config_cmd (PACKET_Qbtrace_conf_pt_size, "Qbtrace-conf:pt:size", "btrace-conf-pt-size", 0); + add_packet_config_cmd (PACKET_Qbtrace_conf_pt_ptwrite, "Qbtrace-conf:pt:ptwrite", + "btrace-conf-pt-ptwrite", 0); + add_packet_config_cmd (PACKET_vContSupported, "vContSupported", "verbose-resume-supported", 0); diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c index d592d2d..932708c 100644 --- a/gdb/riscv-tdep.c +++ b/gdb/riscv-tdep.c @@ -1015,7 +1015,7 @@ riscv_pseudo_register_write (struct gdbarch *gdbarch, if (regnum == tdep->fflags_regnum || regnum == tdep->frm_regnum) { int fcsr_regnum = RISCV_CSR_FCSR_REGNUM; - gdb_byte raw_buf[register_size (gdbarch, fcsr_regnum)]; + gdb::byte_vector raw_buf (register_size (gdbarch, fcsr_regnum)); regcache->raw_read (fcsr_regnum, raw_buf); diff --git a/gdb/rs6000-aix-nat.c b/gdb/rs6000-aix-nat.c index 908671a..6a20f61 100644 --- a/gdb/rs6000-aix-nat.c +++ b/gdb/rs6000-aix-nat.c @@ -993,7 +993,7 @@ rs6000_nat_target::create_inferior (const char *exec_file, info.bfd_arch_info = bfd_get_arch_info (&abfd); info.abfd = current_program_space->exec_bfd (); - if (!gdbarch_update_p (info)) + if (!gdbarch_update_p (current_inferior (), info)) internal_error (_("rs6000_create_inferior: failed " "to select architecture")); } diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 2edb823..ed6a21b 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -2250,7 +2250,7 @@ rs6000_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) { CORE_ADDR displ = op & BL_DISPLACEMENT_MASK; CORE_ADDR call_dest = pc + 4 + displ; - struct bound_minimal_symbol s = lookup_minimal_symbol_by_pc (call_dest); + bound_minimal_symbol s = lookup_minimal_symbol_by_pc (call_dest); /* We check for ___eabi (three leading underscores) in addition to __eabi in case the GCC option "-fleading-underscore" was @@ -2324,7 +2324,6 @@ rs6000_skip_trampoline_code (const frame_info_ptr &frame, CORE_ADDR pc) unsigned int ii, op; int rel; CORE_ADDR solib_target_pc; - struct bound_minimal_symbol msymbol; static unsigned trampoline_code[] = { @@ -2339,7 +2338,7 @@ rs6000_skip_trampoline_code (const frame_info_ptr &frame, CORE_ADDR pc) }; /* Check for bigtoc fixup code. */ - msymbol = lookup_minimal_symbol_by_pc (pc); + bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc); if (msymbol.minsym && rs6000_in_solib_return_trampoline (gdbarch, pc, msymbol.minsym->linkage_name ())) @@ -8604,7 +8603,7 @@ powerpc_set_soft_float (const char *args, int from_tty, struct gdbarch_info info; /* Update the architecture. */ - if (!gdbarch_update_p (info)) + if (!gdbarch_update_p (current_inferior (), info)) internal_error (_("could not update architecture")); } @@ -8630,7 +8629,7 @@ powerpc_set_vector_abi (const char *args, int from_tty, /* Update the architecture. */ gdbarch_info info; - if (!gdbarch_update_p (info)) + if (!gdbarch_update_p (current_inferior (), info)) internal_error (_("could not update architecture")); } diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c index 77740fe..db86079 100644 --- a/gdb/sol-thread.c +++ b/gdb/sol-thread.c @@ -759,9 +759,8 @@ ps_err_e ps_pglobal_lookup (struct ps_prochandle *ph, const char *ld_object_name, const char *ld_symbol_name, psaddr_t *ld_symbol_addr) { - struct bound_minimal_symbol ms; - - ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL); + bound_minimal_symbol ms + = lookup_minimal_symbol (current_program_space, ld_symbol_name); if (!ms.minsym) return PS_NOSYM; @@ -1068,7 +1067,7 @@ info_cb (const td_thrhandle_t *th, void *s) /* Print thr_create start function. */ if (ti.ti_startfunc != 0) { - const struct bound_minimal_symbol msym + const bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc); gdb_printf (" startfunc=%s", @@ -1081,7 +1080,7 @@ info_cb (const td_thrhandle_t *th, void *s) /* If thread is asleep, print function that went to sleep. */ if (ti.ti_state == TD_THR_SLEEP) { - const struct bound_minimal_symbol msym + const bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (ti.ti_pc); gdb_printf (" sleepfunc=%s", diff --git a/gdb/sol2-tdep.c b/gdb/sol2-tdep.c index 468b132..0beab74 100644 --- a/gdb/sol2-tdep.c +++ b/gdb/sol2-tdep.c @@ -63,9 +63,8 @@ sol2_sigtramp_p (const frame_info_ptr &this_frame) static CORE_ADDR sol2_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc) { - struct bound_minimal_symbol msym; - - msym = lookup_minimal_symbol("elf_bndr", NULL, NULL); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, "elf_bndr"); if (msym.minsym && msym.value_address () == pc) return frame_unwind_caller_pc (get_current_frame ()); diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c index f0828fd..dd4da93 100644 --- a/gdb/solib-darwin.c +++ b/gdb/solib-darwin.c @@ -239,18 +239,18 @@ darwin_current_sos () for (int i = 0; i < info->all_image.count; i++) { CORE_ADDR iinfo = info->all_image.info + i * image_info_size; - gdb_byte buf[image_info_size]; + gdb::byte_vector buf (image_info_size); CORE_ADDR load_addr; CORE_ADDR path_addr; struct mach_o_header_external hdr; unsigned long hdr_val; /* Read image info from inferior. */ - if (target_read_memory (iinfo, buf, image_info_size)) + if (target_read_memory (iinfo, buf.data (), image_info_size)) break; - load_addr = extract_typed_address (buf, ptr_type); - path_addr = extract_typed_address (buf + ptr_len, ptr_type); + load_addr = extract_typed_address (buf.data (), ptr_type); + path_addr = extract_typed_address (buf.data () + ptr_len, ptr_type); /* Read Mach-O header from memory. */ if (target_read_memory (load_addr, (gdb_byte *) &hdr, sizeof (hdr) - 4)) @@ -333,14 +333,14 @@ darwin_read_exec_load_addr_from_dyld (struct darwin_info *info) for (i = 0; i < info->all_image.count; i++) { CORE_ADDR iinfo = info->all_image.info + i * image_info_size; - gdb_byte buf[image_info_size]; + gdb::byte_vector buf (image_info_size); CORE_ADDR load_addr; /* Read image info from inferior. */ - if (target_read_memory (iinfo, buf, image_info_size)) + if (target_read_memory (iinfo, buf.data (), image_info_size)) break; - load_addr = extract_typed_address (buf, ptr_type); + load_addr = extract_typed_address (buf.data (), ptr_type); if (darwin_validate_exec_header (load_addr) == load_addr) return load_addr; } diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c index 908c78a..d611004 100644 --- a/gdb/solib-dsbt.c +++ b/gdb/solib-dsbt.c @@ -434,7 +434,6 @@ static CORE_ADDR lm_base (void) { bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ()); - struct bound_minimal_symbol got_sym; CORE_ADDR addr; gdb_byte buf[TIC6X_PTR_SIZE]; dsbt_info *info = get_dsbt_info (current_program_space); @@ -451,8 +450,9 @@ lm_base (void) if (info->lm_base_cache) return info->lm_base_cache; - got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", NULL, - current_program_space->symfile_object_file); + bound_minimal_symbol got_sym + = lookup_minimal_symbol (current_program_space, "_GLOBAL_OFFSET_TABLE_", + current_program_space->symfile_object_file); if (got_sym.minsym != 0) { diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c index 39508fa..c1a5768 100644 --- a/gdb/solib-frv.c +++ b/gdb/solib-frv.c @@ -264,7 +264,6 @@ static CORE_ADDR lm_base (void) { bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ()); - struct bound_minimal_symbol got_sym; CORE_ADDR addr; gdb_byte buf[FRV_PTR_SIZE]; @@ -280,8 +279,9 @@ lm_base (void) if (lm_base_cache) return lm_base_cache; - got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", NULL, - current_program_space->symfile_object_file); + bound_minimal_symbol got_sym + = lookup_minimal_symbol (current_program_space, "_GLOBAL_OFFSET_TABLE_", + current_program_space->symfile_object_file); if (got_sym.minsym == 0) { solib_debug_printf ("_GLOBAL_OFFSET_TABLE_ not found."); @@ -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), @@ -687,7 +689,7 @@ enable_break (void) return 0; } - if (!entry_point_address_query (&entry_point)) + if (!entry_point_address_query (current_program_space, &entry_point)) { solib_debug_printf ("Symbol file has no entry point."); return 0; @@ -838,10 +840,10 @@ frv_relocate_section_addresses (solib &so, target_section *sec) static CORE_ADDR main_got (void) { - struct bound_minimal_symbol got_sym; - objfile *objf = current_program_space->symfile_object_file; - got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", NULL, objf); + bound_minimal_symbol got_sym + = lookup_minimal_symbol (current_program_space, "_GLOBAL_OFFSET_TABLE_", + objf); if (got_sym.minsym == 0) return 0; diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 5c8557e..1a0e542 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -695,7 +695,6 @@ scan_dyntag_auxv (const int desired_dyntag, CORE_ADDR *ptr, static CORE_ADDR elf_locate_base (void) { - struct bound_minimal_symbol msymbol; CORE_ADDR dyn_ptr, dyn_ptr_addr; if (!svr4_have_link_map_offsets ()) @@ -751,8 +750,9 @@ elf_locate_base (void) /* This may be a static executable. Look for the symbol conventionally named _r_debug, as a last resort. */ - msymbol = lookup_minimal_symbol ("_r_debug", NULL, - current_program_space->symfile_object_file); + bound_minimal_symbol msymbol + = lookup_minimal_symbol (current_program_space, "_r_debug", + current_program_space->symfile_object_file); if (msymbol.minsym != NULL) return msymbol.value_address (); @@ -1496,7 +1496,7 @@ svr4_current_sos () CORE_ADDR svr4_fetch_objfile_link_map (struct objfile *objfile) { - struct svr4_info *info = get_svr4_info (objfile->pspace); + struct svr4_info *info = get_svr4_info (objfile->pspace ()); /* Cause svr4_current_sos() to be run if it hasn't been already. */ if (info->main_lm_addr == 0) @@ -1625,7 +1625,7 @@ probes_table_htab_remove_objfile_probes (void **slot, void *info) struct objfile *objfile = (struct objfile *) info; if (pa->objfile == objfile) - htab_clear_slot (get_svr4_info (objfile->pspace)->probes_table.get (), + htab_clear_slot (get_svr4_info (objfile->pspace ())->probes_table.get (), slot); return 1; @@ -1636,7 +1636,7 @@ probes_table_htab_remove_objfile_probes (void **slot, void *info) static void probes_table_remove_objfile_probes (struct objfile *objfile) { - svr4_info *info = get_svr4_info (objfile->pspace); + svr4_info *info = get_svr4_info (objfile->pspace ()); if (info->probes_table != nullptr) htab_traverse_noresize (info->probes_table.get (), probes_table_htab_remove_objfile_probes, objfile); @@ -2227,7 +2227,6 @@ svr4_create_solib_event_breakpoints (svr4_info *info, struct gdbarch *gdbarch, static int enable_break (struct svr4_info *info, int from_tty) { - struct bound_minimal_symbol msymbol; const char * const *bkpt_namep; asection *interp_sect; CORE_ADDR sym_addr; @@ -2482,7 +2481,8 @@ enable_break (struct svr4_info *info, int from_tty) objfile *objf = current_program_space->symfile_object_file; for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++) { - msymbol = lookup_minimal_symbol (*bkpt_namep, NULL, objf); + bound_minimal_symbol msymbol + = lookup_minimal_symbol (current_program_space, *bkpt_namep, objf); if ((msymbol.minsym != NULL) && (msymbol.value_address () != 0)) { @@ -2501,7 +2501,8 @@ enable_break (struct svr4_info *info, int from_tty) { for (bkpt_namep = bkpt_names; *bkpt_namep != NULL; bkpt_namep++) { - msymbol = lookup_minimal_symbol (*bkpt_namep, NULL, objf); + bound_minimal_symbol msymbol + = lookup_minimal_symbol (current_program_space, *bkpt_namep, objf); if ((msymbol.minsym != NULL) && (msymbol.value_address () != 0)) { @@ -3364,7 +3365,6 @@ const struct solib_ops svr4_so_ops = open_symbol_file_object, svr4_in_dynsym_resolve_code, solib_bfd_open, - nullptr, svr4_same, svr4_keep_data_in_core, svr4_update_solib_event_breakpoints, diff --git a/gdb/solib.c b/gdb/solib.c index 881f0d9..49f6075 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -114,7 +114,6 @@ show_solib_search_path (struct ui_file *file, int from_tty, static gdb::unique_xmalloc_ptr<char> solib_find_1 (const char *in_pathname, int *fd, bool is_solib) { - const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ()); int found_file = -1; gdb::unique_xmalloc_ptr<char> temp_pathname; const char *fskind = effective_target_file_system_kind (); @@ -297,12 +296,6 @@ solib_find_1 (const char *in_pathname, int *fd, bool is_solib) target_lbasename (fskind, in_pathname), O_RDONLY | O_BINARY, &temp_pathname); - /* If not found, and we're looking for a solib, try to use target - supplied solib search method. */ - if (is_solib && found_file < 0 && ops->find_and_open_solib) - found_file = ops->find_and_open_solib (in_pathname, O_RDONLY | O_BINARY, - &temp_pathname); - /* If not found, next search the inferior's $PATH environment variable. */ if (found_file < 0 && sysroot == NULL) found_file = openp (current_inferior ()->environment.get ("PATH"), @@ -710,15 +703,16 @@ solib_read_symbols (solib &so, symfile_add_flags flags) return false; } -/* Return true if KNOWN->objfile is used by any other so_list object - in the list of shared libraries. Return false otherwise. */ +/* Return true if KNOWN->objfile is used by any other solib object + in PSPACE's list of shared libraries. Return false otherwise. */ static bool -solib_used (const solib &known) +solib_used (program_space *pspace, const solib &known) { - for (const solib &pivot : current_program_space->solibs ()) + for (const solib &pivot : pspace->solibs ()) if (&pivot != &known && pivot.objfile == known.objfile) return true; + return false; } @@ -845,7 +839,7 @@ update_solib_list (int from_tty) /* Unless the user loaded it explicitly, free SO's objfile. */ if (gdb_iter->objfile != nullptr && !(gdb_iter->objfile->flags & OBJF_USERLOADED) - && !solib_used (*gdb_iter)) + && !solib_used (current_program_space, *gdb_iter)) gdb_iter->objfile->unlink (); /* Some targets' section tables might be referring to @@ -1234,21 +1228,29 @@ sharedlibrary_command (const char *args, int from_tty) solib_add (args, from_tty, 1); } -/* Implements the command "nosharedlibrary", which discards symbols - that have been auto-loaded from shared libraries. Symbols from - shared libraries that were added by explicit request of the user - are not discarded. Also called from remote.c. */ +/* See solib.h. */ void -no_shared_libraries (const char *ignored, int from_tty) +no_shared_libraries (program_space *pspace) { /* The order of the two routines below is important: clear_solib notifies the solib_unloaded observers, and some of these observers might need access to their associated objfiles. Therefore, we can not purge the solibs' objfiles before clear_solib has been called. */ - clear_solib (current_program_space); - objfile_purge_solibs (); + clear_solib (pspace); + objfile_purge_solibs (pspace); +} + +/* Implements the command "nosharedlibrary", which discards symbols + that have been auto-loaded from shared libraries. Symbols from + shared libraries that were added by explicit request of the user + are not discarded. */ + +static void +no_shared_libraries_command (const char *ignored, int from_tty) +{ + no_shared_libraries (current_program_space); } /* See solib.h. */ @@ -1313,7 +1315,7 @@ reload_shared_libraries_1 (int from_tty) && filename_cmp (found_pathname, so.so_name.c_str ()) != 0)) { if (so.objfile && !(so.objfile->flags & OBJF_USERLOADED) - && !solib_used (so)) + && !solib_used (current_program_space, so)) so.objfile->unlink (); current_program_space->remove_target_sections (&so); so.clear (); @@ -1700,7 +1702,7 @@ remove_user_added_objfile (struct objfile *objfile) { if (objfile->flags & OBJF_USERLOADED) { - for (solib &so : objfile->pspace->solibs ()) + for (solib &so : objfile->pspace ()->solibs ()) if (so.objfile == objfile) so.objfile = nullptr; } @@ -1725,7 +1727,7 @@ _initialize_solib () = add_info ("sharedlibrary", info_sharedlibrary_command, _ ("Status of loaded shared object libraries.")); add_info_alias ("dll", info_sharedlibrary_cmd, 1); - add_com ("nosharedlibrary", class_files, no_shared_libraries, + add_com ("nosharedlibrary", class_files, no_shared_libraries_command, _ ("Unload all shared object library symbols.")); add_setshow_boolean_cmd ("auto-solib-add", class_support, &auto_solib_add, diff --git a/gdb/solib.h b/gdb/solib.h index f7a93c0..25ed77c 100644 --- a/gdb/solib.h +++ b/gdb/solib.h @@ -80,9 +80,9 @@ extern bool solib_keep_data_in_core (CORE_ADDR vaddr, unsigned long size); extern bool in_solib_dynsym_resolve_code (CORE_ADDR); -/* Discard symbols that were auto-loaded from shared libraries. */ +/* Discard symbols that were auto-loaded from shared libraries in PSPACE. */ -extern void no_shared_libraries (const char *ignored, int from_tty); +extern void no_shared_libraries (program_space *pspace); /* Synchronize GDB's shared object list with inferior's. diff --git a/gdb/solist.h b/gdb/solist.h index f0d2208..6b2a97a 100644 --- a/gdb/solist.h +++ b/gdb/solist.h @@ -132,14 +132,6 @@ struct solib_ops /* Find and open shared library binary file. */ gdb_bfd_ref_ptr (*bfd_open) (const char *pathname); - /* Optional extra hook for finding and opening a solib. - If TEMP_PATHNAME is non-NULL: If the file is successfully opened a - pointer to a malloc'd and realpath'd copy of SONAME is stored there, - otherwise NULL is stored there. */ - int (*find_and_open_solib) (const char *soname, - unsigned o_flags, - gdb::unique_xmalloc_ptr<char> *temp_pathname); - /* Given two so_list objects, one from the GDB thread list and another from the list returned by current_sos, return 1 if they represent the same library. diff --git a/gdb/source.c b/gdb/source.c index 9e528d3..0c5c2ba 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -231,16 +231,15 @@ get_source_location (program_space *pspace) return loc; } -/* Return the current source file for listing and next line to list. - NOTE: The returned sal pc and end fields are not valid. */ +/* See source.h. */ -struct symtab_and_line -get_current_source_symtab_and_line (void) +symtab_and_line +get_current_source_symtab_and_line (program_space *pspace) { symtab_and_line cursal; - current_source_location *loc = get_source_location (current_program_space); + current_source_location *loc = get_source_location (pspace); - cursal.pspace = current_program_space; + cursal.pspace = pspace; cursal.symtab = loc->symtab (); cursal.line = loc->line (); cursal.pc = 0; @@ -260,8 +259,9 @@ get_current_source_symtab_and_line (void) void set_default_source_symtab_and_line (void) { - if (!have_full_symbols () && !have_partial_symbols ()) - error (_("No symbol table is loaded. Use the \"file\" command.")); + if (!have_full_symbols (current_program_space) + && !have_partial_symbols (current_program_space)) + error (_ ("No symbol table is loaded. Use the \"file\" command.")); /* Pull in a current source symtab if necessary. */ current_source_location *loc = get_source_location (current_program_space); @@ -298,9 +298,9 @@ set_current_source_symtab_and_line (const symtab_and_line &sal) /* Reset any information stored about a default file and line to print. */ void -clear_current_source_symtab_and_line (void) +clear_current_source_symtab_and_line (program_space *pspace) { - current_source_location *loc = get_source_location (current_program_space); + current_source_location *loc = get_source_location (pspace); loc->set (nullptr, 0); } @@ -319,13 +319,13 @@ select_source_symtab () SEARCH_FUNCTION_DOMAIN, nullptr); if (bsym.symbol != nullptr) { - symtab_and_line sal = find_function_start_sal (bsym.symbol, true); + symtab_and_line sal = find_function_start_sal (bsym.symbol, false); if (sal.symtab == NULL) /* We couldn't find the location of `main', possibly due to missing line number info, fall back to line 1 in the corresponding file. */ loc->set (bsym.symbol->symtab (), 1); else - loc->set (sal.symtab, std::max (sal.line - (lines_to_list - 1), 1)); + loc->set (sal.symtab, sal.line); return; } diff --git a/gdb/source.h b/gdb/source.h index 144ee48..541ee3b 100644 --- a/gdb/source.h +++ b/gdb/source.h @@ -21,7 +21,9 @@ #include "gdbsupport/scoped_fd.h" +struct program_space; struct symtab; +struct symtab_and_line; /* See openp function definition for their description. */ @@ -107,7 +109,8 @@ extern int get_lines_to_list (void); /* Return the current source file for listing and next line to list. NOTE: The returned sal pc and end fields are not valid. */ -extern struct symtab_and_line get_current_source_symtab_and_line (void); +extern symtab_and_line get_current_source_symtab_and_line + (program_space *pspace); /* If the current source file for listing is not set, try and get a default. Usually called before get_current_source_symtab_and_line() is called. @@ -126,7 +129,7 @@ extern symtab_and_line set_current_source_symtab_and_line (const symtab_and_line &sal); /* Reset any information stored about a default file and line to print. */ -extern void clear_current_source_symtab_and_line (void); +extern void clear_current_source_symtab_and_line (program_space *pspace); /* Add a source path substitution rule. */ extern void add_substitute_path_rule (const char *, const char *); diff --git a/gdb/stack.c b/gdb/stack.c index b36193b..b7a102e 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -1299,13 +1299,12 @@ find_frame_funname (const frame_info_ptr &frame, enum language *funlang, } else { - struct bound_minimal_symbol msymbol; CORE_ADDR pc; if (!get_frame_address_in_block_if_available (frame, &pc)) return funname; - msymbol = lookup_minimal_symbol_by_pc (pc); + bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc); if (msymbol.minsym != NULL) { funname.reset (xstrdup (msymbol.minsym->print_name ())); @@ -1529,9 +1528,7 @@ info_frame_command_core (const frame_info_ptr &fi, bool selected_frame_p) } else if (frame_pc_p) { - struct bound_minimal_symbol msymbol; - - msymbol = lookup_minimal_symbol_by_pc (frame_pc); + bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (frame_pc); if (msymbol.minsym != NULL) { funname = msymbol.minsym->print_name (); diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c index 3a223d0..0eccda2 100644 --- a/gdb/symfile-debug.c +++ b/gdb/symfile-debug.c @@ -399,7 +399,7 @@ objfile::expand_symtabs_matching } struct compunit_symtab * -objfile::find_pc_sect_compunit_symtab (struct bound_minimal_symbol msymbol, +objfile::find_pc_sect_compunit_symtab (bound_minimal_symbol msymbol, CORE_ADDR pc, struct obj_section *section, int warn_if_readin) diff --git a/gdb/symfile.c b/gdb/symfile.c index b0510b4..cf7ab0b 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -91,8 +91,6 @@ static void symbol_file_add_main_1 (const char *args, symfile_add_flags add_flag static const struct sym_fns *find_sym_fns (bfd *); -static void overlay_invalidate_all (void); - static void simple_free_overlay_table (void); static void read_target_long_array (CORE_ADDR, unsigned int *, int, int, @@ -1026,7 +1024,6 @@ symbol_file_add_with_addrs (const gdb_bfd_ref_ptr &abfd, const char *name, section_addr_info *addrs, objfile_flags flags, struct objfile *parent) { - struct objfile *objfile; const int from_tty = add_flags & SYMFILE_VERBOSE; const int mainline = add_flags & SYMFILE_MAINLINE; const int always_confirm = add_flags & SYMFILE_ALWAYS_CONFIRM; @@ -1053,14 +1050,17 @@ symbol_file_add_with_addrs (const gdb_bfd_ref_ptr &abfd, const char *name, if (from_tty && (always_confirm - || ((have_full_symbols () || have_partial_symbols ()) + || ((have_full_symbols (current_program_space) + || have_partial_symbols (current_program_space)) && mainline)) - && !query (_("Load new symbol table from \"%s\"? "), name)) + && !query (_ ("Load new symbol table from \"%s\"? "), name)) error (_("Not confirmed.")); if (mainline) flags |= OBJF_MAINLINE; - objfile = objfile::make (abfd, name, flags, parent); + + objfile *objfile + = objfile::make (abfd, current_program_space, name, flags, parent); /* We either created a new mapped symbol table, mapped an existing symbol table file which has not had initial symbol reading @@ -1199,7 +1199,8 @@ symbol_file_add_main_1 (const char *args, symfile_add_flags add_flags, void symbol_file_clear (int from_tty) { - if ((have_full_symbols () || have_partial_symbols ()) + if ((have_full_symbols (current_program_space) + || have_partial_symbols (current_program_space)) && from_tty && (current_program_space->symfile_object_file ? !query (_("Discard symbol table from `%s'? "), @@ -1209,7 +1210,7 @@ symbol_file_clear (int from_tty) /* solib descriptors may have handles to objfiles. Wipe them before their objfiles get stale by free_all_objfiles. */ - no_shared_libraries (NULL, from_tty); + no_shared_libraries (current_program_space); current_program_space->free_all_objfiles (); @@ -1370,17 +1371,13 @@ find_separate_debug_file (const char *dir, objfile_name (objfile)); /* First try in the same directory as the original file. */ - std::string debugfile = dir; - debugfile += debuglink; + std::string debugfile = path_join (dir, debuglink); if (separate_debug_file_exists (debugfile, crc32, objfile, warnings)) return debugfile; /* Then try in the subdirectory named DEBUG_SUBDIRECTORY. */ - debugfile = dir; - debugfile += DEBUG_SUBDIRECTORY; - debugfile += "/"; - debugfile += debuglink; + debugfile = path_join (dir, DEBUG_SUBDIRECTORY, debuglink); if (separate_debug_file_exists (debugfile, crc32, objfile, warnings)) return debugfile; @@ -1393,10 +1390,13 @@ find_separate_debug_file (const char *dir, bool target_prefix = is_target_filename (dir); const char *dir_notarget = target_prefix ? dir + strlen (TARGET_SYSROOT_PREFIX) : dir; + const char *target_prefix_str = target_prefix ? TARGET_SYSROOT_PREFIX : ""; std::vector<gdb::unique_xmalloc_ptr<char>> debugdir_vec = dirnames_to_char_ptr_vec (debug_file_directory.c_str ()); - gdb::unique_xmalloc_ptr<char> canon_sysroot - = gdb_realpath (gdb_sysroot.c_str ()); + const char *sysroot_str = gdb_sysroot.c_str (); + if (is_target_filename (sysroot_str) && target_filesystem_is_local ()) + sysroot_str += strlen (TARGET_SYSROOT_PREFIX); + gdb::unique_xmalloc_ptr<char> canon_sysroot = gdb_realpath (sysroot_str); /* MS-Windows/MS-DOS don't allow colons in file names; we must convert the drive letter into a one-letter directory, so that the @@ -1421,12 +1421,8 @@ find_separate_debug_file (const char *dir, for (const gdb::unique_xmalloc_ptr<char> &debugdir : debugdir_vec) { - debugfile = target_prefix ? TARGET_SYSROOT_PREFIX : ""; - debugfile += debugdir; - debugfile += "/"; - debugfile += drive; - debugfile += dir_notarget; - debugfile += debuglink; + debugfile = path_join (target_prefix_str, debugdir.get (), + drive.c_str (), dir_notarget, debuglink); if (separate_debug_file_exists (debugfile, crc32, objfile, warnings)) return debugfile; @@ -1443,39 +1439,18 @@ find_separate_debug_file (const char *dir, { /* If the file is in the sysroot, try using its base path in the global debugfile directory. */ - debugfile = target_prefix ? TARGET_SYSROOT_PREFIX : ""; - debugfile += debugdir; - debugfile += "/"; - debugfile += base_path; - debugfile += "/"; - debugfile += debuglink; + debugfile = path_join (target_prefix_str, debugdir.get (), + base_path, debuglink); if (separate_debug_file_exists (debugfile, crc32, objfile, warnings)) return debugfile; /* If the file is in the sysroot, try using its base path in - the sysroot's global debugfile directory. GDB_SYSROOT - might refer to a target: path; we strip the "target:" - prefix -- but if that would yield the empty string, we - don't bother at all, because that would just give the - same result as above. */ + the sysroot's global debugfile directory. */ if (gdb_sysroot != TARGET_SYSROOT_PREFIX) { - debugfile = target_prefix ? TARGET_SYSROOT_PREFIX : ""; - if (is_target_filename (gdb_sysroot)) - { - std::string root - = gdb_sysroot.substr (strlen (TARGET_SYSROOT_PREFIX)); - gdb_assert (!root.empty ()); - debugfile += root; - } - else - debugfile += gdb_sysroot; - debugfile += debugdir; - debugfile += "/"; - debugfile += base_path; - debugfile += "/"; - debugfile += debuglink; + debugfile = path_join (gdb_sysroot.c_str (), debugdir.get (), + base_path, debuglink); if (separate_debug_file_exists (debugfile, crc32, objfile, warnings)) @@ -2387,7 +2362,7 @@ remove_symbol_file_command (const char *args, int from_tty) { if ((objfile->flags & OBJF_USERLOADED) != 0 && (objfile->flags & OBJF_SHARED) != 0 - && objfile->pspace == pspace + && objfile->pspace () == pspace && is_addr_in_objfile (addr, objfile)) { objf = objfile; @@ -2408,7 +2383,7 @@ remove_symbol_file_command (const char *args, int from_tty) { if ((objfile->flags & OBJF_USERLOADED) != 0 && (objfile->flags & OBJF_SHARED) != 0 - && objfile->pspace == pspace + && objfile->pspace () == pspace && filename_cmp (filename.get (), objfile_name (objfile)) == 0) { objf = objfile; @@ -2611,7 +2586,7 @@ reread_symbols (int from_tty) making the dangling pointers point to correct data again. */ - objfiles_changed (); + objfiles_changed (current_program_space); /* Recompute section offsets and section indices. */ objfile->sf->sym_offsets (objfile, {}); @@ -2884,7 +2859,7 @@ clear_symtab_users (symfile_add_flags add_flags) /* Clear the "current" symtab first, because it is no longer valid. breakpoint_re_set may try to access the current symtab. */ - clear_current_source_symtab_and_line (); + clear_current_source_symtab_and_line (current_program_space); clear_displays (); clear_last_displayed_sal (); @@ -2969,13 +2944,13 @@ section_is_overlay (struct obj_section *section) return 0; } -/* Function: overlay_invalidate_all (void) - Invalidate the mapped state of all overlay sections (mark it as stale). */ +/* Invalidate the mapped state of all overlay sections (mark it as stale) in + PSPACE. */ static void -overlay_invalidate_all (void) +overlay_invalidate_all (program_space *pspace) { - for (objfile *objfile : current_program_space->objfiles ()) + for (objfile *objfile : pspace->objfiles ()) for (obj_section *sect : objfile->sections ()) if (section_is_overlay (sect)) sect->ovly_mapped = -1; @@ -3011,7 +2986,7 @@ section_is_mapped (struct obj_section *osect) { if (overlay_cache_invalid) { - overlay_invalidate_all (); + overlay_invalidate_all (current_program_space); overlay_cache_invalid = 0; } if (osect->ovly_mapped == -1) @@ -3427,14 +3402,13 @@ read_target_long_array (CORE_ADDR memaddr, unsigned int *myaddr, static int simple_read_overlay_table (void) { - struct bound_minimal_symbol novlys_msym; - struct bound_minimal_symbol ovly_table_msym; struct gdbarch *gdbarch; int word_size; enum bfd_endian byte_order; simple_free_overlay_table (); - novlys_msym = lookup_minimal_symbol ("_novlys", NULL, NULL); + bound_minimal_symbol novlys_msym + = lookup_minimal_symbol (current_program_space, "_novlys"); if (! novlys_msym.minsym) { error (_("Error reading inferior's overlay table: " @@ -3443,7 +3417,8 @@ simple_read_overlay_table (void) return 0; } - ovly_table_msym = lookup_bound_minimal_symbol ("_ovly_table"); + bound_minimal_symbol ovly_table_msym + = lookup_minimal_symbol (current_program_space, "_ovly_table"); if (! ovly_table_msym.minsym) { error (_("Error reading inferior's overlay table: couldn't find " @@ -3522,8 +3497,8 @@ simple_overlay_update (struct obj_section *osect) { /* Does its cached location match what's currently in the symtab? */ - struct bound_minimal_symbol minsym - = lookup_minimal_symbol ("_ovly_table", NULL, NULL); + bound_minimal_symbol minsym + = lookup_minimal_symbol (current_program_space, "_ovly_table"); if (minsym.minsym == NULL) error (_("Error reading inferior's overlay table: couldn't " @@ -3722,7 +3697,7 @@ static void symfile_free_objfile (struct objfile *objfile) { /* Remove the target sections owned by this objfile. */ - objfile->pspace->remove_target_sections (objfile); + objfile->pspace ()->remove_target_sections (objfile); } /* Wrapper around the quick_symbol_functions expand_symtabs_matching "method". diff --git a/gdb/symmisc.c b/gdb/symmisc.c index b4e0360..7f81415 100644 --- a/gdb/symmisc.c +++ b/gdb/symmisc.c @@ -366,8 +366,7 @@ dump_symtab (struct symtab *symtab, struct ui_file *outfile) But use only real languages, not placeholders. */ if (symtab->language () != language_unknown) { - scoped_restore_current_language save_lang; - set_language (symtab->language ()); + scoped_restore_current_language save_lang (symtab->language ()); dump_symtab_1 (symtab, outfile); } else diff --git a/gdb/symtab.c b/gdb/symtab.c index 41d71be..9b3562e 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -1755,7 +1755,7 @@ maintenance_print_symbol_cache_statistics (const char *args, int from_tty) static void symtab_new_objfile_observer (struct objfile *objfile) { - symbol_cache_flush (objfile->pspace); + symbol_cache_flush (objfile->pspace ()); } /* This module's 'all_objfiles_removed' observer. */ @@ -1774,7 +1774,7 @@ symtab_all_objfiles_removed (program_space *pspace) static void symtab_free_objfile_observer (struct objfile *objfile) { - symbol_cache_flush (objfile->pspace); + symbol_cache_flush (objfile->pspace ()); } /* See symtab.h. */ @@ -2439,7 +2439,7 @@ lookup_symbol_in_objfile_from_linkage_name (struct objfile *objfile, /* A helper function that throws an exception when a symbol was found in a psymtab but not in a symtab. */ -static void ATTRIBUTE_NORETURN +[[noreturn]] static void error_in_psymtab_expansion (enum block_enum block_index, const char *name, struct compunit_symtab *cust) { @@ -2892,14 +2892,14 @@ find_pc_sect_compunit_symtab (CORE_ADDR pc, struct obj_section *section) { struct compunit_symtab *best_cust = NULL; CORE_ADDR best_cust_range = 0; - struct bound_minimal_symbol msymbol; /* If we know that this is not a text address, return failure. This is necessary because we loop based on the block's high and low code addresses, which do not include the data ranges, and because we call find_pc_sect_psymtab which has a similar restriction based on the partial_symtab's texthigh and textlow. */ - msymbol = lookup_minimal_symbol_by_pc_section (pc, section); + bound_minimal_symbol msymbol + = lookup_minimal_symbol_by_pc_section (pc, section); if (msymbol.minsym && msymbol.minsym->data_p ()) return NULL; @@ -3091,7 +3091,6 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) int len; const linetable_entry *item; const struct blockvector *bv; - struct bound_minimal_symbol msymbol; /* Info on best line seen so far, and where it starts, and its file. */ @@ -3170,13 +3169,14 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) * check for the address being the same, to avoid an * infinite recursion. */ - msymbol = lookup_minimal_symbol_by_pc (pc); + bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc); if (msymbol.minsym != NULL) if (msymbol.minsym->type () == mst_solib_trampoline) { - struct bound_minimal_symbol mfunsym - = lookup_minimal_symbol_text (msymbol.minsym->linkage_name (), - NULL); + bound_minimal_symbol mfunsym + = lookup_minimal_symbol_text (section->objfile->pspace (), + msymbol.minsym->linkage_name (), + nullptr); if (mfunsym.minsym == NULL) /* I eliminated this warning since it is coming out @@ -3919,7 +3919,7 @@ skip_prologue_sal (struct symtab_and_line *sal) } else { - struct bound_minimal_symbol msymbol + bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc_section (sal->pc, sal->section); if (msymbol.minsym == NULL) @@ -4764,8 +4764,9 @@ info_sources_worker (struct ui_out *uiout, static void info_sources_command (const char *args, int from_tty) { - if (!have_full_symbols () && !have_partial_symbols ()) - error (_("No symbol table is loaded. Use the \"file\" command.")); + if (!have_full_symbols (current_program_space) + && !have_partial_symbols (current_program_space)) + error (_ ("No symbol table is loaded. Use the \"file\" command.")); filename_partial_match_opts match_opts; auto group = make_info_sources_options_def_group (&match_opts); @@ -5289,7 +5290,7 @@ print_symbol_info (struct symbol *sym, int block, const char *last) for non-debugging symbols to gdb_stdout. */ static void -print_msymbol_info (struct bound_minimal_symbol msymbol) +print_msymbol_info (bound_minimal_symbol msymbol) { struct gdbarch *gdbarch = msymbol.objfile->arch (); const char *tmp; @@ -6381,7 +6382,8 @@ make_source_files_completion_list (const char *text, const char *word) const char *base_name; struct add_partial_filename_data datum; - if (!have_full_symbols () && !have_partial_symbols ()) + if (!have_full_symbols (current_program_space) + && !have_partial_symbols (current_program_space)) return list; filename_seen_cache filenames_seen; @@ -6775,10 +6777,12 @@ symbol::get_maybe_copied_address () const gdb_assert (this->aclass () == LOC_STATIC); const char *linkage_name = this->linkage_name (); - bound_minimal_symbol minsym = lookup_minimal_symbol_linkage (linkage_name, - false); + bound_minimal_symbol minsym + = lookup_minimal_symbol_linkage (this->objfile ()->pspace (), linkage_name, + false); if (minsym.minsym != nullptr) return minsym.value_address (); + return this->m_value.address; } @@ -6791,10 +6795,11 @@ minimal_symbol::get_maybe_copied_address (objfile *objf) const gdb_assert ((objf->flags & OBJF_MAINLINE) == 0); const char *linkage_name = this->linkage_name (); - bound_minimal_symbol found = lookup_minimal_symbol_linkage (linkage_name, - true); + bound_minimal_symbol found + = lookup_minimal_symbol_linkage (objf->pspace (), linkage_name, true); if (found.minsym != nullptr) return found.value_address (); + return (this->m_value.address + objf->section_offsets[this->section_index ()]); } diff --git a/gdb/symtab.h b/gdb/symtab.h index a5631a2..4197a3a 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -2599,7 +2599,7 @@ struct symbol_search /* If msymbol is non-null, then a match was made on something for which only minimal_symbols exist. */ - struct bound_minimal_symbol msymbol; + bound_minimal_symbol msymbol; private: diff --git a/gdb/target-debug.h b/gdb/target-debug.h index b5eb338..bba51eb 100644 --- a/gdb/target-debug.h +++ b/gdb/target-debug.h @@ -26,7 +26,7 @@ behavior is needed. References to these printers are automatically generated by - make-target-delegates. See the generated file target-delegates.c. + make-target-delegates. See the generated file target-delegates-gen.c. In a couple cases, a special printing function is defined and then used via the TARGET_DEBUG_PRINTER macro. See target.h. @@ -46,8 +46,8 @@ #include "target/waitstatus.h" /* The functions defined in this header file are not marked "inline", such - that any function not used by target-delegates.c (the only user of this file) - will be flagged as unused. */ + that any function not used by target-delegates-gen.c (the only user of this + file) will be flagged as unused. */ static std::string target_debug_print_target_object (target_object object) diff --git a/gdb/target-delegates.c b/gdb/target-delegates-gen.c index dd20e14..dd20e14 100644 --- a/gdb/target-delegates.c +++ b/gdb/target-delegates-gen.c diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c index 4f21044..4bb48fc 100644 --- a/gdb/target-descriptions.c +++ b/gdb/target-descriptions.c @@ -500,7 +500,7 @@ target_find_description (void) struct gdbarch_info info; info.target_desc = tdesc_info->tdesc; - if (!gdbarch_update_p (info)) + if (!gdbarch_update_p (current_inferior (), info)) { warning (_("Architecture rejected target-supplied description")); tdesc_info->tdesc = nullptr; @@ -537,18 +537,16 @@ target_clear_description (void) tdesc_info->tdesc = nullptr; gdbarch_info info; - if (!gdbarch_update_p (info)) + if (!gdbarch_update_p (current_inferior (), info)) internal_error (_("Could not remove target-supplied description")); } -/* Return the global current target description. This should only be - used by gdbarch initialization code; most access should be through - an existing gdbarch. */ +/* See target-descriptions.h. */ -const struct target_desc * -target_current_description (void) +const target_desc * +target_current_description (inferior *inf) { - target_desc_info *tdesc_info = ¤t_inferior ()->tdesc_info; + target_desc_info *tdesc_info = &inf->tdesc_info; if (tdesc_info->fetched) return tdesc_info->tdesc; diff --git a/gdb/target-descriptions.h b/gdb/target-descriptions.h index 54c1f23..d708dbd 100644 --- a/gdb/target-descriptions.h +++ b/gdb/target-descriptions.h @@ -39,11 +39,10 @@ void target_find_description (void); void target_clear_description (void); -/* Return the current inferior's target description. This should only - be used by gdbarch initialization code; most access should be - through an existing gdbarch. */ +/* Return INF's target description. This should only be used by gdbarch + initialization code; most access should be through an existing gdbarch. */ -const struct target_desc *target_current_description (void); +const target_desc *target_current_description (inferior *inf); /* Record architecture-specific functions to call for pseudo-register support. If tdesc_use_registers is called and gdbarch_num_pseudo_regs diff --git a/gdb/target.c b/gdb/target.c index 1b5aa11..47f09f5 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -56,7 +56,7 @@ #include "cli/cli-decode.h" #include "cli/cli-style.h" -static void generic_tls_error (void) ATTRIBUTE_NORETURN; +[[noreturn]] static void generic_tls_error (void); static void default_rcmd (struct target_ops *, const char *, struct ui_file *); @@ -64,7 +64,7 @@ static int default_verify_memory (struct target_ops *self, const gdb_byte *data, CORE_ADDR memaddr, ULONGEST size); -static void tcomplain (void) ATTRIBUTE_NORETURN; +[[noreturn]] static void tcomplain (void); /* Mapping between target_info objects (which have address identity) and corresponding open/factory function/callback. Each add_target @@ -2428,7 +2428,7 @@ info_target_command (const char *args, int from_tty) resets (things which might change between targets). */ void -target_pre_inferior (int from_tty) +target_pre_inferior () { /* Clear out solib state. Otherwise the solib state of the previous inferior might have survived and is entirely wrong for the new @@ -2452,7 +2452,7 @@ target_pre_inferior (int from_tty) memory regions and features. */ if (!gdbarch_has_global_solist (current_inferior ()->arch ())) { - no_shared_libraries (NULL, from_tty); + no_shared_libraries (current_program_space); invalidate_target_mem_regions (); @@ -2504,7 +2504,7 @@ target_preopen (int from_tty) live process to a core of the same program. */ current_inferior ()->pop_all_targets_above (file_stratum); - target_pre_inferior (from_tty); + target_pre_inferior (); } /* See target.h. */ @@ -3199,6 +3199,14 @@ target_ops::fileio_fstat (int fd, struct stat *sb, fileio_error *target_errno) } int +target_ops::fileio_stat (struct inferior *inf, const char *filename, + struct stat *sb, fileio_error *target_errno) +{ + *target_errno = FILEIO_ENOSYS; + return -1; +} + +int target_ops::fileio_close (int fd, fileio_error *target_errno) { *target_errno = FILEIO_ENOSYS; @@ -3318,6 +3326,29 @@ target_fileio_fstat (int fd, struct stat *sb, fileio_error *target_errno) /* See target.h. */ int +target_fileio_stat (struct inferior *inf, const char *filename, + struct stat *sb, fileio_error *target_errno) +{ + for (target_ops *t = default_fileio_target (); t != NULL; t = t->beneath ()) + { + int ret = t->fileio_stat (inf, filename, sb, target_errno); + + if (ret == -1 && *target_errno == FILEIO_ENOSYS) + continue; + + target_debug_printf_nofunc ("target_fileio_stat (%s) = %d (%d)", + filename, ret, + ret != -1 ? 0 : *target_errno); + return ret; + } + + *target_errno = FILEIO_ENOSYS; + return -1; +} + +/* See target.h. */ + +int target_fileio_close (int fd, fileio_error *target_errno) { fileio_fh_t *fh = fileio_fd_to_fh (fd); @@ -3667,7 +3698,7 @@ dummy_make_corefile_notes (struct target_ops *self, return NULL; } -#include "target-delegates.c" +#include "target-delegates-gen.c" /* The initial current target, so that there is always a semi-valid current target. */ diff --git a/gdb/target.h b/gdb/target.h index 81de4a6..dcf68a6 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -1011,6 +1011,14 @@ struct target_ops *TARGET_ERRNO). */ virtual int fileio_fstat (int fd, struct stat *sb, fileio_error *target_errno); + /* Get information about the file FILENAME and put it in SB. Look for + FILENAME in the filesystem as seen by INF. If INF is NULL, use the + filesystem seen by the debugger (GDB or, for remote targets, the + remote stub). Return 0 on success, or -1 if an error occurs (and + set *TARGET_ERRNO). */ + virtual int fileio_stat (struct inferior *inf, const char *filename, + struct stat *sb, fileio_error *target_errno); + /* Close FD on the target. Return 0, or -1 if an error occurs (and set *TARGET_ERRNO). */ virtual int fileio_close (int fd, fileio_error *target_errno); @@ -2220,6 +2228,14 @@ extern int target_fileio_pread (int fd, gdb_byte *read_buf, int len, extern int target_fileio_fstat (int fd, struct stat *sb, fileio_error *target_errno); +/* Get information about the file at FILENAME on the target and put it in + SB. Look in the filesystem as seen by INF. If INF is NULL, use the + filesystem seen by the debugger (GDB or, for remote targets, the remote + stub). Return 0 on success, or -1 if an error occurs (and set + *TARGET_ERRNO). */ +extern int target_fileio_stat (struct inferior *inf, const char *filename, + struct stat *sb, fileio_error *target_errno); + /* Close FD on the target. Return 0, or -1 if an error occurs (and set *TARGET_ERRNO). */ extern int target_fileio_close (int fd, fileio_error *target_errno); @@ -2427,7 +2443,7 @@ struct target_unpusher typedef std::unique_ptr<struct target_ops, target_unpusher> target_unpush_up; -extern void target_pre_inferior (int); +extern void target_pre_inferior (); extern void target_preopen (int); @@ -2490,7 +2506,7 @@ extern int default_memory_insert_breakpoint (struct gdbarch *, extern void initialize_targets (void); -extern void noprocess (void) ATTRIBUTE_NORETURN; +[[noreturn]] extern void noprocess (void); extern void target_require_runnable (void); diff --git a/gdb/testsuite/gdb.ada/limited-length.exp b/gdb/testsuite/gdb.ada/limited-length.exp index 1350e7a..d0e912b 100644 --- a/gdb/testsuite/gdb.ada/limited-length.exp +++ b/gdb/testsuite/gdb.ada/limited-length.exp @@ -73,18 +73,15 @@ set elem_size [get_valueof "/d" "(Large_1d_Array(1)'Size + 7) / 8" "*unknown*"] gdb_test_no_output "set max-value-size [expr $elem_size * $elements]" with_test_prefix "with reduced max-value size" { - gdb_test "print Large_1d_Array" \ - "value of type `.*' requires $decimal bytes,\ - which is more than max-value-size" - gdb_test "output Large_1d_Array" \ - "value of type `.*' requires $decimal bytes,\ - which is more than max-value-size" - gdb_test "print Large_3d_Array" \ - "value of type `.*' requires $decimal bytes,\ - which is more than max-value-size" - gdb_test "output Large_3d_Array" \ - "value of type `.*' requires $decimal bytes,\ - which is more than max-value-size" + # GNAT historically named this type, but as the array type is + # nameless, this accepts both variants. + set response \ + "value (of type `.*' )?requires $decimal bytes, which is more than max-value-size" + + gdb_test "print Large_1d_Array" $response + gdb_test "output Large_1d_Array" $response + gdb_test "print Large_3d_Array" $response + gdb_test "output Large_3d_Array" $response } with_test_prefix "with reduced print -elements flag" { diff --git a/gdb/testsuite/gdb.ada/mi_task_arg.exp b/gdb/testsuite/gdb.ada/mi_task_arg.exp index 098396d..b4b7b49 100644 --- a/gdb/testsuite/gdb.ada/mi_task_arg.exp +++ b/gdb/testsuite/gdb.ada/mi_task_arg.exp @@ -49,7 +49,8 @@ set frame1 "frame=\{level=\"1\",args=\\\[${frame1_args}(,$frame1_opt_args)?\\\]\ # Frame for system.tasking.stages.task_wrapper set frame2_args "(\{name=\"self_id\",value=\"($hex|<optimized out>)\"\})?" set frame2 "frame=\{level=\"2\",args=\\\[$frame2_args\\\]\}" -mi_gdb_test "-stack-list-arguments 1" \ - "\\^done,stack-args=\\\[$frame0,$frame1,$frame2,.*" \ - "-stack-list-arguments 1" +set frames "$frame0,$frame1,${frame2}(,.*)?" +mi_gdb_test "-stack-list-arguments 1" \ + "\\^done,stack-args=\\\[$frames\\\]" \ + "-stack-list-arguments 1" diff --git a/gdb/testsuite/gdb.ada/mi_var_access.exp b/gdb/testsuite/gdb.ada/mi_var_access.exp index b71c8f3..e797a15 100644 --- a/gdb/testsuite/gdb.ada/mi_var_access.exp +++ b/gdb/testsuite/gdb.ada/mi_var_access.exp @@ -42,8 +42,9 @@ mi_continue_to_line \ # to match possible values. set re_ok "\\^done,name=\"A_String_Access\",numchild=\"$decimal\",.*" set re_error "\\^error,msg=\"Value out of range\.\".*" +set re_error2 "\\^error,msg=\"Cannot access memory at address $hex\"" mi_gdb_test "-var-create A_String_Access * A_String_Access" \ - "($re_ok|$re_error)" \ + "($re_ok|$re_error|$re_error2)" \ "Create varobj" set bp_location [gdb_get_line_number "STOP2" ${testdir}/mi_access.adb] diff --git a/gdb/testsuite/gdb.ada/multiarray.exp b/gdb/testsuite/gdb.ada/multiarray.exp index 3475647..9be0aaa 100644 --- a/gdb/testsuite/gdb.ada/multiarray.exp +++ b/gdb/testsuite/gdb.ada/multiarray.exp @@ -22,7 +22,8 @@ standard_ada_testfile p foreach_with_prefix scenario {all minimal} { set flags [list debug additional_flags=-fgnat-encodings=$scenario] - if {[gdb_compile_ada "${srcfile}" "${binfile}-${scenario}" executable {debug}] != ""} { + if {[gdb_compile_ada "${srcfile}" "${binfile}-${scenario}" \ + executable $flags] != ""} { return -1 } diff --git a/gdb/testsuite/gdb.ada/variant_record_field.exp b/gdb/testsuite/gdb.ada/variant_record_field.exp new file mode 100644 index 0000000..f3baa25 --- /dev/null +++ b/gdb/testsuite/gdb.ada/variant_record_field.exp @@ -0,0 +1,50 @@ +# 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/>. + +load_lib "ada.exp" + +require allow_ada_tests + +standard_ada_testfile foo + +# The compiler used to emit an invalid DWARF expression for the record +# size, so GDB could not 'print p_record' correctly: a direct 'print +# p_record.i' worked, but iteration over the record fields was broken. +# +# Originally observed at -O2, and the bug was reproducible with just +# -Og. The DWARF fix covered both optimization levels; not worth +# making guarantees beyond -Og though, so test that. + +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug optimize=-Og]] != ""} { + return -1 +} + +clean_restart ${testfile} + +set bp_location [gdb_get_line_number "BREAK" ${srcfile}] +runto "${testfile}.adb:${bp_location}" + +set test "print p_record" +gdb_test_multiple "$test" "$test" { + -re "\\(kind => five, i => 1200\\)" { + pass $test + } + -re "\\(kind => five, i => <error reading variable: access outside bounds of object>" { + if { [gcc_major_version] <= 14 } { + setup_xfail *-*-* + } + fail $test + } +} diff --git a/gdb/testsuite/gdb.ada/variant_record_field/foo.adb b/gdb/testsuite/gdb.ada/variant_record_field/foo.adb new file mode 100644 index 0000000..2526a1d --- /dev/null +++ b/gdb/testsuite/gdb.ada/variant_record_field/foo.adb @@ -0,0 +1,47 @@ +-- 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/>. +with Ada.Text_IO; + +procedure Foo is + + package P is + + type Int16 is range 0 .. 2 ** 16 - 1; + type Enum is (Zero, One, Two, Three, Four, Five, Six, Seven, Eight, Nine); + + type Rec (Kind : Enum := Zero) is record + case Kind is + when Four .. Seven => + I : Int16; + when others => + null; + end case; + end record; + + end P; + + P_Record : P.Rec; + I : P.Int16; + + procedure Dump is + begin + Ada.Text_IO.Put_Line ("P_Record.I => " & P_Record.I'Image); -- BREAK + end Dump; + +begin + I := P.Int16'(1200); + P_Record := (Kind => P.Five, I => I); + Dump; +end Foo; diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c index 49b0553..adda4b8 100644 --- a/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c +++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c @@ -24,10 +24,17 @@ break_here_c (uint64_t value) { } +__attribute__((target("arm"))) +uint64_t +caller_trampoline (void) +{ + return caller (); +} + int main (void) { - uint64_t value = caller (); + uint64_t value = caller_trampoline (); break_here_c (value); return 0; } diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind.c b/gdb/testsuite/gdb.arch/arm-pseudo-unwind.c index 49b0553..adda4b8 100644 --- a/gdb/testsuite/gdb.arch/arm-pseudo-unwind.c +++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind.c @@ -24,10 +24,17 @@ break_here_c (uint64_t value) { } +__attribute__((target("arm"))) +uint64_t +caller_trampoline (void) +{ + return caller (); +} + int main (void) { - uint64_t value = caller (); + uint64_t value = caller_trampoline (); break_here_c (value); return 0; } diff --git a/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.c b/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.c index 393004e..9b5e137 100644 --- a/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.c +++ b/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.c @@ -15,7 +15,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -static int *kernel_user_helper_version = (int *) 0xffff0ffc; +static int *kernel_user_helper_version_ptr = (int *) 0xffff0ffc; +static int kernel_user_helper_version; typedef void * (kernel_user_func_t)(void); #define kernel_user_get_tls (*(kernel_user_func_t *) 0xffff0fe0) @@ -25,6 +26,8 @@ main (void) { int i; + kernel_user_helper_version = *kernel_user_helper_version_ptr; + for (i = 0; i < 8; i++) kernel_user_get_tls (); } diff --git a/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.exp b/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.exp index 27be5d5..788bc86 100644 --- a/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.exp +++ b/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.exp @@ -26,10 +26,13 @@ if { ![runto_main] } { return -1 } +# Initialize kernel_user_helper_version. +gdb_test "next" "for .*" + # Check kernel helpers are supported or not. set kernel_helper_supported 0 -gdb_test_multiple "p *kernel_user_helper_version" \ +gdb_test_multiple "p kernel_user_helper_version" \ "check kernel helper version" { -re " = ($decimal)\r\n$gdb_prompt $" { if { $expect_out(1,string) >= 1 } { diff --git a/gdb/testsuite/gdb.base/assign.exp b/gdb/testsuite/gdb.base/assign.exp index 675ded4..38c2b2e 100644 --- a/gdb/testsuite/gdb.base/assign.exp +++ b/gdb/testsuite/gdb.base/assign.exp @@ -60,7 +60,7 @@ gdb_test_multiple "print v_int+=57" "v_int+=57" { } } -gdb_test_no_output "set variable v_int = 6" "set v_int to 6 (2)" +gdb_test_no_output "set variable v_int = 6" "set v_int to 6, 2" gdb_test_multiple "print v_int-=57" "v_int-=57" { -re " = -51.*$gdb_prompt $" { @@ -68,7 +68,7 @@ gdb_test_multiple "print v_int-=57" "v_int-=57" { } } -gdb_test_no_output "set variable v_int = 6" "set v_int to 6 (3)" +gdb_test_no_output "set variable v_int = 6" "set v_int to 6, 3" gdb_test_multiple "print v_int*=5" "v_int*=5" { -re " = 30.*$gdb_prompt $" { @@ -76,7 +76,7 @@ gdb_test_multiple "print v_int*=5" "v_int*=5" { } } -gdb_test_no_output "set variable v_int = 6" "set v_int to 6 (4)" +gdb_test_no_output "set variable v_int = 6" "set v_int to 6, 4" gdb_test_multiple "print v_int/=4" "v_int/=4" { -re " = 1.*$gdb_prompt $" { @@ -84,7 +84,7 @@ gdb_test_multiple "print v_int/=4" "v_int/=4" { } } -gdb_test_no_output "set variable v_int = 6" "set v_int to 6 (5)" +gdb_test_no_output "set variable v_int = 6" "set v_int to 6, 5" gdb_test_multiple "print v_int%=4" "v_int%=4" { -re " = 2.*$gdb_prompt $" { @@ -92,7 +92,7 @@ gdb_test_multiple "print v_int%=4" "v_int%=4" { } } -gdb_test_no_output "set variable v_int = 6" "set v_int to 6 (6)" +gdb_test_no_output "set variable v_int = 6" "set v_int to 6, 6" gdb_test_multiple "print v_int+=v_char" "v_int+=char" { -re " = 71.*$gdb_prompt $" { @@ -100,7 +100,7 @@ gdb_test_multiple "print v_int+=v_char" "v_int+=char" { } } -gdb_test_no_output "set variable v_int = 6" "set v_int to 6 (7)" +gdb_test_no_output "set variable v_int = 6" "set v_int to 6, 7" gdb_test_multiple "print v_int+=v_signed_char" "v_int+=signed_char" { -re " = 72.*$gdb_prompt $" { @@ -108,7 +108,7 @@ gdb_test_multiple "print v_int+=v_signed_char" "v_int+=signed_char" { } } -gdb_test_no_output "set variable v_int = 6" "set v_int to 6 (8)" +gdb_test_no_output "set variable v_int = 6" "set v_int to 6, 8" gdb_test_multiple "print v_int+=v_unsigned_char" "v_int+=unsigned_char" { -re " = 73.*$gdb_prompt $" { @@ -116,7 +116,7 @@ gdb_test_multiple "print v_int+=v_unsigned_char" "v_int+=unsigned_char" { } } -gdb_test_no_output "set variable v_int = 6" "set v_int to 6 (9)" +gdb_test_no_output "set variable v_int = 6" "set v_int to 6, 9" gdb_test_multiple "print v_int+=v_short" "v_int+=short" { -re " = 9.*$gdb_prompt $" { @@ -124,7 +124,7 @@ gdb_test_multiple "print v_int+=v_short" "v_int+=short" { } } -gdb_test_no_output "set variable v_int = 6" "set v_int to 6 (10)" +gdb_test_no_output "set variable v_int = 6" "set v_int to 6, 10" gdb_test_multiple "print v_int+=v_signed_short" "v_int+=signed_short" { -re " = 10.*$gdb_prompt $" { @@ -132,7 +132,7 @@ gdb_test_multiple "print v_int+=v_signed_short" "v_int+=signed_short" { } } -gdb_test_no_output "set variable v_int = 6" "set v_int to 6 (11)" +gdb_test_no_output "set variable v_int = 6" "set v_int to 6, 11" gdb_test_multiple "print v_int+=v_unsigned_short" "v_int=+unsigned_short" { -re " = 11.*$gdb_prompt $" { @@ -140,7 +140,7 @@ gdb_test_multiple "print v_int+=v_unsigned_short" "v_int=+unsigned_short" { } } -gdb_test_no_output "set variable v_int = 6" "set v_int to 6 (12)" +gdb_test_no_output "set variable v_int = 6" "set v_int to 6, 12" gdb_test_multiple "print v_int+=v_signed_int" "v_int+=signed_int" { -re " = 13.*$gdb_prompt $" { @@ -148,7 +148,7 @@ gdb_test_multiple "print v_int+=v_signed_int" "v_int+=signed_int" { } } -gdb_test_no_output "set variable v_int = 6" "set v_int to 6 (13)" +gdb_test_no_output "set variable v_int = 6" "set v_int to 6, 13" gdb_test_multiple "print v_int+=v_unsigned_int" "v_int+=unsigned_int" { -re " = 14.*$gdb_prompt $" { @@ -156,7 +156,7 @@ gdb_test_multiple "print v_int+=v_unsigned_int" "v_int+=unsigned_int" { } } -gdb_test_no_output "set variable v_int = 6" "set v_int to 6 (14)" +gdb_test_no_output "set variable v_int = 6" "set v_int to 6, 14" gdb_test_multiple "print v_int+=v_long" "v_int+=long" { -re " = 15.*$gdb_prompt $" { @@ -164,7 +164,7 @@ gdb_test_multiple "print v_int+=v_long" "v_int+=long" { } } -gdb_test_no_output "set variable v_int = 6" "set v_int to 6 (15)" +gdb_test_no_output "set variable v_int = 6" "set v_int to 6, 15" gdb_test_multiple "print v_int+=v_signed_long" "v_int+=signed_long" { -re " = 16.*$gdb_prompt $" { @@ -172,7 +172,7 @@ gdb_test_multiple "print v_int+=v_signed_long" "v_int+=signed_long" { } } -gdb_test_no_output "set variable v_int = 6" "set v_int to 6 (16)" +gdb_test_no_output "set variable v_int = 6" "set v_int to 6, 16" gdb_test_multiple "print v_int+=v_unsigned_long" "v_int+=unsigned_long" { -re " = 17.*$gdb_prompt $" { @@ -180,7 +180,7 @@ gdb_test_multiple "print v_int+=v_unsigned_long" "v_int+=unsigned_long" { } } -gdb_test_no_output "set variable v_int = 6" "set v_int to 6 (17)" +gdb_test_no_output "set variable v_int = 6" "set v_int to 6, 17" gdb_test_multiple "print v_int+=v_float" "v_int+=v_float" { -re " = 106.*$gdb_prompt $" { @@ -188,7 +188,7 @@ gdb_test_multiple "print v_int+=v_float" "v_int+=v_float" { } } -gdb_test_no_output "set variable v_int = 6" "set v_int to 6 (18)" +gdb_test_no_output "set variable v_int = 6" "set v_int to 6, 18" gdb_test_multiple "print v_int+=v_double" "v_int+=double" { -re " = 206.*$gdb_prompt $" { diff --git a/gdb/testsuite/gdb.base/bitfields.exp b/gdb/testsuite/gdb.base/bitfields.exp index ce420fa..6954a35 100644 --- a/gdb/testsuite/gdb.base/bitfields.exp +++ b/gdb/testsuite/gdb.base/bitfields.exp @@ -45,23 +45,23 @@ proc bitfield_uniqueness {} { # treat it correctly as a signed 1bit field (values 0 or -1) while # printing its value does not cause a spurious failure. We do the # signedness preservation test later. - gdb_test "print flags" ".*uc = 0 .*, s1 = (1|-1), u1 = 0, s2 = 0, u2 = 0, s3 = 0, u3 = 0, s9 = 0, u9 = 0, sc = 0.*" "bitfield uniqueness (s1)" + gdb_test "print flags" ".*uc = 0 .*, s1 = (1|-1), u1 = 0, s2 = 0, u2 = 0, s3 = 0, u3 = 0, s9 = 0, u9 = 0, sc = 0.*" "bitfield uniqueness, s1" gdb_test "cont" "Break.*break1 \\(\\) at .*$srcfile:$decimal.*" "continuing to break1 #2" - gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 1, s2 = 0, u2 = 0, s3 = 0, u3 = 0, s9 = 0, u9 = 0, sc = 0.*" "bitfield uniqueness (u1)" + gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 1, s2 = 0, u2 = 0, s3 = 0, u3 = 0, s9 = 0, u9 = 0, sc = 0.*" "bitfield uniqueness, u1" gdb_test "cont" "Break.*break1 \\(\\) at .*$srcfile:$decimal.*" "continuing to break1 #3" - gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 1, u2 = 0, s3 = 0, u3 = 0, s9 = 0, u9 = 0, sc = 0.*" "bitfield uniqueness (s2)" + gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 1, u2 = 0, s3 = 0, u3 = 0, s9 = 0, u9 = 0, sc = 0.*" "bitfield uniqueness, s2" gdb_test "cont" "Break.*break1 \\(\\) at .*$srcfile:$decimal.*" "continuing to break1 #4" - gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 1, s3 = 0, u3 = 0, s9 = 0, u9 = 0, sc = 0.*" "bitfield uniqueness (u2)" + gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 1, s3 = 0, u3 = 0, s9 = 0, u9 = 0, sc = 0.*" "bitfield uniqueness, u2" gdb_test "cont" "Break.*break1 \\(\\) at .*$srcfile:$decimal.*" "continuing to break1 #5" - gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 0, s3 = 1, u3 = 0, s9 = 0, u9 = 0, sc = 0.*" "bitfield uniqueness (s3)" + gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 0, s3 = 1, u3 = 0, s9 = 0, u9 = 0, sc = 0.*" "bitfield uniqueness, s3" gdb_test "cont" "Break.*break1 \\(\\) at .*$srcfile:$decimal.*" "continuing to break1 #6" - gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 0, s3 = 0, u3 = 1, s9 = 0, u9 = 0, sc = 0.*" "bitfield uniqueness (u3)" + gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 0, s3 = 0, u3 = 1, s9 = 0, u9 = 0, sc = 0.*" "bitfield uniqueness, u3" gdb_test "cont" "Break.*break1 \\(\\) at .*$srcfile:$decimal.*" "continuing to break1 #7" - gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 0, s3 = 0, u3 = 0, s9 = 1, u9 = 0, sc = 0.*" "bitfield uniqueness (s9)" + gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 0, s3 = 0, u3 = 0, s9 = 1, u9 = 0, sc = 0.*" "bitfield uniqueness, s9" gdb_test "cont" "Break.*break1 \\(\\) at .*$srcfile:$decimal.*" "continuing to break1 #8" - gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 0, s3 = 0, u3 = 0, s9 = 0, u9 = 1, sc = 0.*" "bitfield uniqueness (u9)" + gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 0, s3 = 0, u3 = 0, s9 = 0, u9 = 1, sc = 0.*" "bitfield uniqueness, u9" gdb_test "cont" "Break.*break1 \\(\\) at .*$srcfile:$decimal.*" "continuing to break1 #9" - gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 0, s3 = 0, u3 = 0, s9 = 0, u9 = 0, sc = 1.*" "bitfield uniqueness (sc)" + gdb_test "print flags" ".*uc = 0 .*, s1 = 0, u1 = 0, s2 = 0, u2 = 0, s3 = 0, u3 = 0, s9 = 0, u9 = 0, sc = 1.*" "bitfield uniqueness, sc" } diff --git a/gdb/testsuite/gdb.base/build-id-seqno.c b/gdb/testsuite/gdb.base/build-id-seqno.c new file mode 100644 index 0000000..e2119ba7 --- /dev/null +++ b/gdb/testsuite/gdb.base/build-id-seqno.c @@ -0,0 +1,22 @@ +/* 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/>. */ + +int +main (void) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.base/build-id-seqno.exp b/gdb/testsuite/gdb.base/build-id-seqno.exp new file mode 100644 index 0000000..9566933 --- /dev/null +++ b/gdb/testsuite/gdb.base/build-id-seqno.exp @@ -0,0 +1,134 @@ +# 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/>. + +# Setup a .build-id/ based debug directory containing multiple entries +# for the same build-id, with each entry given a different sequence +# number. +# +# Ensure that GDB will scan over broken symlinks for the same build-id +# (but different sequence number) to find later working symlinks. +# +# This test only places debug information on the host, so it is always +# local to GDB. + +require {!is_remote host} + +standard_testfile + +if {[build_executable "failed to prepare" $testfile $srcfile \ + {debug build-id}] == -1} { + return -1 +} + +# Split out BINFILE.debug. Remove debug from BINFILE. +if {[gdb_gnu_strip_debug $binfile] != 0} { + return -1 +} + +# Get the '.build-id/xx/xxx...xxx' part of the filename. +set build_id_filename [build_id_debug_filename_get $binfile] + +# Hide (rename) BINFILE.debug, this should ensure GDB can't find it +# directly but needs to look for the build-id based file in the debug +# directory. +set hidden_debuginfo [standard_output_file "hidden_$testfile.debug"] +remote_exec build "mv ${binfile}.debug $hidden_debuginfo" + +# A filename that doesn't exist. Some symlinks will point at this +# file. +set missing_debuginfo [host_standard_output_file "missing_debuginfo"] + +# Create the debug directory, and the .build-id directory structure +# within it. +set debugdir [host_standard_output_file "debug"] +remote_exec host "mkdir -p $debugdir/[file dirname $build_id_filename]" + +set host_hidden_debuginfo [gdb_remote_download host $hidden_debuginfo] +remote_exec host "ln -fs $host_hidden_debuginfo $debugdir/$build_id_filename" + +# Start GDB and load global BINFILE. If FIND_DEBUGINFO is true then +# we expect GDB to find the debug information matching BINFILE, +# otherwise, we expect GDB not to find the debug information. +proc load_binfile_check_debug_is_found { find_debuginfo testname } { + with_test_prefix "$testname" { + clean_restart + + gdb_test_no_output "set debug-file-directory $::debugdir" \ + "set debug-file-directory" + + gdb_file_cmd $::binfile + + if { $find_debuginfo } { + gdb_assert { [regexp [string_to_regexp \ + "Reading symbols from $::hidden_debuginfo..."] \ + $::gdb_file_cmd_msg] } \ + "debuginfo was read via build-id" + } else { + gdb_assert { [regexp "\\(No debugging symbols found in \[^\r\n\]+/$::testfile\\)" \ + $::gdb_file_cmd_msg] } \ + } + } +} + +# Return a copy of FILENAME, which should end '.debug', with NUMBER +# added, e.g. add_seqno 1 "foo.debug" --> "foo.1.debug". +proc add_seqno { number filename } { + return [regsub "\.debug\$" $filename ".${number}.debug"] +} + +load_binfile_check_debug_is_found true \ + "find debuginfo with a single build-id file" + +remote_exec host "ln -fs $host_hidden_debuginfo \ + $debugdir/[add_seqno 1 $build_id_filename]" +remote_exec host "ln -fs $host_hidden_debuginfo \ + $debugdir/[add_seqno 2 $build_id_filename]" +remote_exec host "ln -fs $host_hidden_debuginfo \ + $debugdir/[add_seqno 3 $build_id_filename]" + +load_binfile_check_debug_is_found true \ + "find debuginfo with 4 build-id files" + +remote_exec host "ln -fs $missing_debuginfo $debugdir/$build_id_filename" + +load_binfile_check_debug_is_found true \ + "find debuginfo, first build-id file is bad" + +remote_exec host "ln -fs $missing_debuginfo \ + $debugdir/[add_seqno 1 $build_id_filename]" +remote_exec host "ln -fs $missing_debuginfo \ + $debugdir/[add_seqno 3 $build_id_filename]" + +load_binfile_check_debug_is_found true \ + "find debuginfo, first 2 build-id files are bad" + +remote_exec host "ln -fs $missing_debuginfo \ + $debugdir/[add_seqno 2 $build_id_filename]" + +load_binfile_check_debug_is_found false \ + "cannot find debuginfo, all build-id files are bad" + +remote_exec host "ln -fs $host_hidden_debuginfo \ + $debugdir/[add_seqno 3 $build_id_filename]" + +load_binfile_check_debug_is_found true \ + "find debuginfo, last build-id file is good" + +remote_exec host "rm -f $debugdir/[add_seqno 1 $build_id_filename]" + +load_binfile_check_debug_is_found false \ + "cannot find debuginfo, file with seqno 1 is missing" diff --git a/gdb/testsuite/gdb.base/catch-syscall.exp b/gdb/testsuite/gdb.base/catch-syscall.exp index 075498a..431bfd5 100644 --- a/gdb/testsuite/gdb.base/catch-syscall.exp +++ b/gdb/testsuite/gdb.base/catch-syscall.exp @@ -171,7 +171,7 @@ proc insert_catch_syscall_with_arg { syscall } { global decimal # Trying to set the catchpoint - set thistest "catch syscall with arguments ($syscall)" + set thistest "catch syscall with arguments, $syscall" gdb_test "catch syscall $syscall" "Catchpoint $decimal \\(syscall \'?${syscall}\'?( \[${decimal}\])?\\)" $thistest check_info_bp_specific_syscall $syscall diff --git a/gdb/testsuite/gdb.base/completion.exp b/gdb/testsuite/gdb.base/completion.exp index 3dbdd0f..4a0a373 100644 --- a/gdb/testsuite/gdb.base/completion.exp +++ b/gdb/testsuite/gdb.base/completion.exp @@ -543,10 +543,10 @@ gdb_test_multiple "" "$test" { # Eat the prompt gdb_expect { -re "$gdb_prompt " { - pass "$test (eat prompt)" + pass "$test, eat prompt" } timeout { - fail "(timeout) $test (eat prompt)" + fail "$test, eat prompt (timeout)" } } @@ -572,10 +572,10 @@ gdb_test_multiple "" "$test" { # Eat the prompt gdb_expect { -re "$gdb_prompt " { - pass "$test (eat prompt)" + pass "$test, eat prompt" } timeout { - fail "(timeout) $test (eat prompt)" + fail "$test, eat prompt (timeout)" } } diff --git a/gdb/testsuite/gdb.base/complex-parts.exp b/gdb/testsuite/gdb.base/complex-parts.exp index e678cfc..40f14f4 100644 --- a/gdb/testsuite/gdb.base/complex-parts.exp +++ b/gdb/testsuite/gdb.base/complex-parts.exp @@ -23,12 +23,13 @@ if {![runto_main]} { return 0 } -gdb_breakpoint [gdb_get_line_number "Break Here"] -gdb_continue_to_breakpoint "breakpt" ".* Break Here\\. .*" +set marker " Break Here. " +gdb_breakpoint [gdb_get_line_number $marker] +gdb_continue_to_breakpoint "breakpt" ".*[string_to_regexp $marker].*" -gdb_test "p z1" " = 1.5 \\+ 4.5i" -gdb_test "p z2" " = 2.5 \\+ -5.5i" -gdb_test "p z3" " = 3.5 \\+ 6.5i" +gdb_test "p z1" [string_to_regexp " = 1.5 + 4.5i"] +gdb_test "p z2" [string_to_regexp " = 2.5 + -5.5i"] +gdb_test "p z3" [string_to_regexp " = 3.5 + 6.5i"] # The following 3 tests are broken for Clang. # More info at https://github.com/llvm/llvm-project/issues/52996. @@ -40,59 +41,71 @@ if {[test_compiler_info clang-*-*]} { setup_xfail *-*-* } gdb_test "ptype z3" " = complex long double" with_test_prefix "double imaginary" { - gdb_test "p \$_cimag (z1)" " = 4.5" - gdb_test "ptype \$" " = double" + set expr {$_cimag (z1)} + gdb_test "p $expr" " = 4.5" + gdb_test {ptype $} " = double" + gdb_test "ptype $expr" " = double" } with_test_prefix "float imaginary" { - gdb_test "p \$_cimag (z2)" " = -5.5" - gdb_test "ptype \$" " = float" + set expr {$_cimag (z2)} + gdb_test "p $expr" " = -5.5" + gdb_test {ptype $} " = float" + gdb_test "ptype $expr" " = float" } with_test_prefix "long double imaginary" { - gdb_test "p \$_cimag (z3)" " = 6.5" - gdb_test "ptype \$" " = long double" + set expr {$_cimag (z3)} + gdb_test "p $expr" " = 6.5" + gdb_test {ptype $} " = long double" + gdb_test "ptype $expr" " = long double" } with_test_prefix "double real" { - gdb_test "p \$_creal (z1)" " = 1.5" - gdb_test "ptype \$" " = double" + set expr {$_creal (z1)} + gdb_test "p $expr" " = 1.5" + gdb_test {ptype $} " = double" + gdb_test "ptype $expr" " = double" } with_test_prefix "float real" { - gdb_test "p \$_creal (z2)" " = 2.5" - gdb_test "ptype \$" " = float" + set expr {$_creal (z2)} + gdb_test "p $expr" " = 2.5" + gdb_test {ptype $} " = float" + gdb_test "ptype $expr" " = float" } with_test_prefix "long double real" { - gdb_test "p \$_creal (z3)" " = 3.5" - gdb_test "ptype \$" " = long double" + set expr {$_creal (z3)} + gdb_test "p $expr" " = 3.5" + gdb_test {ptype $} " = long double" + gdb_test "ptype $expr" " = long double" } -gdb_test "p \$_cimag (d1)" "expected a complex number" -gdb_test "p \$_cimag (f1)" "expected a complex number" -gdb_test "p \$_cimag (i1)" "expected a complex number" +gdb_test {p $_cimag (d1)} "expected a complex number" +gdb_test {p $_cimag (f1)} "expected a complex number" +gdb_test {p $_cimag (i1)} "expected a complex number" -gdb_test "p \$_creal (d1)" "expected a complex number" -gdb_test "p \$_creal (f1)" "expected a complex number" -gdb_test "p \$_creal (i1)" "expected a complex number" +gdb_test {p $_creal (d1)} "expected a complex number" +gdb_test {p $_creal (f1)} "expected a complex number" +gdb_test {p $_creal (i1)} "expected a complex number" # # General complex number tests. # -gdb_test "print 23 + 7i" " = 23 \\+ 7i" -gdb_test "print 23.125f + 7i" " = 23.125 \\+ 7i" -gdb_test "print 23 + 7.25fi" " = 23 \\+ 7.25i" -gdb_test "print (23 + 7i) + (17 + 10i)" " = 40 \\+ 17i" -gdb_test "print 23 + -7i" " = 23 \\+ -7i" -gdb_test "print 23 - 7i" " = 23 \\+ -7i" +gdb_test "print 23 + 7i" [string_to_regexp " = 23 + 7i"] +gdb_test "print 23.125f + 7i" [string_to_regexp " = 23.125 + 7i"] +gdb_test "print 23 + 7.25fi" [string_to_regexp " = 23 + 7.25i"] +gdb_test "print (23 + 7i) + (17 + 10i)" [string_to_regexp " = 40 + 17i"] +gdb_test "print 23 + -7i" [string_to_regexp " = 23 + -7i"] +gdb_test "print 23 - 7i" [string_to_regexp " = 23 + -7i"] -gdb_test "print -(23 + 7i)" " = -23 \\+ -7i" -gdb_test "print +(23 + 7i)" " = 23 \\+ 7i" -gdb_test "print ~(23 + 7i)" " = 23 \\+ -7i" +gdb_test "print -(23 + 7i)" [string_to_regexp " = -23 + -7i"] +gdb_test "print +(23 + 7i)" [string_to_regexp " = 23 + 7i"] +gdb_test "print ~(23 + 7i)" [string_to_regexp " = 23 + -7i"] -gdb_test "print (5 + 5i) * (2 + 2i)" " = 0 \\+ 20i" +gdb_test "print (5 + 5i) * (2 + 2i)" [string_to_regexp " = 0 + 20i"] gdb_test "print (5 + 7i) == (5 + 7i)" " = 1" gdb_test "print (5 + 7i) == (8 + 7i)" " = 0" @@ -101,14 +114,16 @@ gdb_test "print (5 + 7i) != (5 + 7i)" " = 0" gdb_test "print (5 + 7i) != (8 + 7i)" " = 1" gdb_test "print (5 + 7i) != (5 + 92i)" " = 1" -gdb_test "print (20 - 4i) / (3 + 2i)" " = 4 \\+ -4i" +gdb_test "print (20 - 4i) / (3 + 2i)" [string_to_regexp " = 4 + -4i"] -gdb_test "print (_Complex int) 4" " = 4 \\+ 0i" -gdb_test "print (_Complex float) 4.5" " = 4.5 \\+ 0i" +gdb_test "print (_Complex int) 4" [string_to_regexp " = 4 + 0i"] +gdb_test "print (_Complex float) 4.5" [string_to_regexp " = 4.5 + 0i"] gdb_test "ptype __complex__ short" " = _Complex short" -gdb_test "print (_Complex int) (23.75 + 8.88i)" " = 23 \\+ 8i" +gdb_test "print (_Complex int) (23.75 + 8.88i)" [string_to_regexp " = 23 + 8i"] -set re_reject_arg "Argument to complex arithmetic operation not supported\\." +set re_reject_arg \ + [string_to_regexp \ + "Argument to complex arithmetic operation not supported."] gdb_test "print (void *)0 + 5i" $re_reject_arg gdb_test "print (_Decimal32)0 + 5i" $re_reject_arg @@ -117,4 +132,4 @@ clean_restart gdb_test_no_output "set language c++" # C++ type tests. -gdb_test "print (bool)1 + 1i" " = 1 \\+ 1i" +gdb_test "print (bool)1 + 1i" [string_to_regexp "= 1 + 1i"] diff --git a/gdb/testsuite/gdb.base/cond-expr.exp b/gdb/testsuite/gdb.base/cond-expr.exp index 5956d68..67918cf 100644 --- a/gdb/testsuite/gdb.base/cond-expr.exp +++ b/gdb/testsuite/gdb.base/cond-expr.exp @@ -47,22 +47,22 @@ if {![runto_main]} { } gdb_test "print (2 ? 3 : 4)" "\[0-9\]* = 3" \ - "print value of cond expr (const true)" + "print value of cond expr, const true" gdb_test "print (0 ? 3 : 4)" "\[0-9\]* = 4" \ - "print value of cond expr (const false)" + "print value of cond expr, const false" gdb_test_no_output "set variable x=14" "set variable x=14" gdb_test_no_output "set variable y=2" "set variable y=2" gdb_test_no_output "set variable z=3" "set variable z=3" gdb_test "print (x ? y : z)" "\[0-9\]* = 2" \ - "print value of cond expr (var true)" + "print value of cond expr, var true" gdb_test_no_output "set variable x=0" "set variable x=0" gdb_test "print (x ? y : z)" "\[0-9\]* = 3" \ - "print value of cond expr (var false)" + "print value of cond expr, var false" gdb_test "whatis (0 ? 3 : 4)" "type = int" \ "print whatis of cond expr" diff --git a/gdb/testsuite/gdb.base/coredump-filter-build-id.exp b/gdb/testsuite/gdb.base/coredump-filter-build-id.exp index b62796f..cddacce 100644 --- a/gdb/testsuite/gdb.base/coredump-filter-build-id.exp +++ b/gdb/testsuite/gdb.base/coredump-filter-build-id.exp @@ -30,7 +30,7 @@ if { ![istarget *-*-linux*] } { } require is_x86_64_m64_target -if { [prepare_for_testing "failed to prepare" $testfile $srcfile debug] } { +if { [prepare_for_testing "failed to prepare" $testfile $srcfile {debug build-id}] } { return -1 } diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp index 28b723e..79363c5 100644 --- a/gdb/testsuite/gdb.base/corefile.exp +++ b/gdb/testsuite/gdb.base/corefile.exp @@ -195,7 +195,7 @@ gdb_test "x/wx buf3" "$hex:\[ \t\]+0x00000000" \ # test reinit_frame_cache gdb_load ${binfile} -gdb_test "up" "#\[0-9\]* *(\[0-9xa-fH'\]* in)? .* \\(.*\\).*" "up (reinit)" +gdb_test "up" "#\[0-9\]* *(\[0-9xa-fH'\]* in)? .* \\(.*\\).*" "up, reinit" gdb_test "core" "No core file now." diff --git a/gdb/testsuite/gdb.base/cursal.c b/gdb/testsuite/gdb.base/cursal.c index 8dc713f..bc1e46f 100644 --- a/gdb/testsuite/gdb.base/cursal.c +++ b/gdb/testsuite/gdb.base/cursal.c @@ -31,7 +31,7 @@ func1 () int main () -{ +{ /* main prologue */ int v0 = 0; func1 (); diff --git a/gdb/testsuite/gdb.base/cursal.exp b/gdb/testsuite/gdb.base/cursal.exp index 3acced8..6c1fe38 100644 --- a/gdb/testsuite/gdb.base/cursal.exp +++ b/gdb/testsuite/gdb.base/cursal.exp @@ -25,9 +25,9 @@ clean_restart gdb_file_cmd ${binfile} gdb_test_no_output "set listsize 1" -# initial sal should be first statement in main +# initial sal should be main's prologue. gdb_test "list" \ - "v0 = 0;" \ + "{ /\\* main prologue \\*/" \ "list before run" gdb_load ${binfile} diff --git a/gdb/testsuite/gdb.base/cvexpr.exp b/gdb/testsuite/gdb.base/cvexpr.exp index fd15efe..439bf71 100644 --- a/gdb/testsuite/gdb.base/cvexpr.exp +++ b/gdb/testsuite/gdb.base/cvexpr.exp @@ -47,55 +47,55 @@ proc do_test {dir options} { gdb_test "whatis (const char) v_char" \ "type = const char" \ - "(const char)" + "cast to const char" gdb_test "whatis (const signed char) v_signed_char" \ "type = const signed char" \ - "(const signed char)" + "cast to const signed char" gdb_test "whatis (const unsigned char) v_unsigned_char" \ "type = const (unsigned char|char)" \ - "(const unsigned char)" + "cast to const unsigned char" gdb_test "whatis (const short) v_short" \ "type = const (short|short int)" \ - "(const short)" + "cast to const short" gdb_test "whatis (const signed short) v_signed_short" \ "type = const (short|short int|signed short|signed short int)" \ - "(const signed short)" + "cast to const signed short" gdb_test "whatis (const unsigned short) v_unsigned_short" \ "type = const (unsigned short|short unsigned int)" \ - "(const unsigned short)" + "cast to const unsigned short" gdb_test "whatis (const int) v_int" \ "type = const int" \ - "(const int)" + "cast to const int" gdb_test "whatis (const signed int) v_signed_int" \ "type = const (signed int|int)" \ - "(const signed int)" + "cast to const signed int" gdb_test "whatis (const unsigned int) v_unsigned_int" \ "type = const unsigned int" \ - "(const unsigned int)" + "cast to const unsigned int" gdb_test "whatis (const long) v_long" \ "type = const (long|long int)" \ - "(const long)" + "cast to const long" gdb_test "whatis (const signed long) v_signed_long" \ "type = const (signed |)long( int|)" \ - "(const signed long)" + "cast to const signed long" gdb_test "whatis (const unsigned long) v_unsigned_long" \ "type = const (unsigned long|long unsigned int)" \ - "(const unsigned long)" + "cast to const unsigned long" gdb_test "whatis (const long long) v_long_long" \ "type = const long long( int|)" \ - "(const long long)" + "cast to const long long" gdb_test "whatis (const signed long long) v_signed_long_long" \ "type = const (signed |)long long( int|)" \ - "(const signed long long)" + "cast to const signed long long" gdb_test "whatis (const unsigned long long) v_unsigned_long_long" \ "type = const (unsigned long long|long long unsigned int)" \ - "(const unsigned long long)" + "cast to const unsigned long long" gdb_test "whatis (const float) v_float" \ "type = const float" \ - "(const float)" + "cast to const float" gdb_test "whatis (const double) v_double" \ "type = const double" \ - "(const double)" + "cast to const double" # # Test casting a scalar to volatile @@ -103,55 +103,55 @@ proc do_test {dir options} { gdb_test "whatis (volatile char) v_char" \ "type = volatile char" \ - "(volatile char)" + "cast to volatile char" gdb_test "whatis (volatile signed char) v_signed_char" \ "type = volatile signed char" \ - "(volatile signed char)" + "cast to volatile signed char" gdb_test "whatis (volatile unsigned char) v_unsigned_char" \ "type = volatile (unsigned char|char)" \ - "(volatile unsigned char)" + "cast to volatile unsigned char" gdb_test "whatis (volatile short) v_short" \ "type = volatile (short|short int)" \ - "(volatile short)" + "cast to volatile short" gdb_test "whatis (volatile signed short) v_signed_short" \ "type = volatile (short|short int|signed short|signed short int)" \ - "(volatile signed short)" + "cast to volatile signed short" gdb_test "whatis (volatile unsigned short) v_unsigned_short" \ "type = volatile (unsigned short|short unsigned int)" \ - "(volatile unsigned short)" + "cast to volatile unsigned short" gdb_test "whatis (volatile int) v_int" \ "type = volatile int" \ - "(volatile int)" + "cast to volatile int" gdb_test "whatis (volatile signed int) v_signed_int" \ "type = volatile (signed int|int)" \ - "(volatile signed int)" + "cast to volatile signed int" gdb_test "whatis (volatile unsigned int) v_unsigned_int" \ "type = volatile unsigned int" \ - "(volatile unsigned int)" + "cast to volatile unsigned int" gdb_test "whatis (volatile long) v_long" \ "type = volatile (long|long int)" \ - "(volatile long)" + "cast to volatile long" gdb_test "whatis (volatile signed long) v_signed_long" \ "type = volatile (signed |)long( int|)" \ - "(volatile signed long)" + "cast to volatile signed long" gdb_test "whatis (volatile unsigned long) v_unsigned_long" \ "type = volatile (unsigned long|long unsigned int)" \ - "(volatile unsigned long)" + "cast to volatile unsigned long" gdb_test "whatis (volatile long long) v_long_long" \ "type = volatile long long( int|)" \ - "(volatile long long)" + "cast to volatile long long" gdb_test "whatis (volatile signed long long) v_signed_long_long" \ "type = volatile (signed |)long long( int|)" \ - "(volatile signed long long)" + "cast to volatile signed long long" gdb_test "whatis (volatile unsigned long long) v_unsigned_long_long" \ "type = volatile (unsigned long long|long long unsigned int)" \ - "(volatile unsigned long long)" + "cast to volatile unsigned long long" gdb_test "whatis (volatile float) v_float" \ "type = volatile float" \ - "(volatile float)" + "cast to volatile float" gdb_test "whatis (volatile double) v_double" \ "type = volatile double" \ - "(volatile double)" + "cast to volatile double" # # Combine const and volatile @@ -159,47 +159,47 @@ proc do_test {dir options} { gdb_test "whatis (const volatile int) v_int" \ "type = const volatile int" \ - "(const volatile int)" + "cast to const volatile int" gdb_test "whatis (volatile const int) v_int" \ "type = const volatile int" \ - "(volatile const int)" + "cast to volatile const int" gdb_test "whatis (const int volatile) v_int" \ "type = const volatile int" \ - "(const int volatile)" + "cast to const int volatile" gdb_test "whatis (volatile int const) v_int" \ "type = const volatile int" \ - "(volatile int const)" + "cast to volatile int const" gdb_test "whatis (int const volatile) v_int" \ "type = const volatile int" \ - "(int const volatile)" + "cast to int const volatile" gdb_test "whatis (int volatile const) v_int" \ "type = const volatile int" \ - "(int volatile const)" + "cast to int volatile const" gdb_test "whatis (const volatile int *) v_int_pointer" \ "type = const volatile int${ws}\\*" \ - "(const volatile int *)" + "cast to const volatile int *" gdb_test "whatis (volatile const int *) v_int_pointer" \ "type = const volatile int${ws}\\*" \ - "(volatile const int *)" + "cast to volatile const int *" gdb_test "whatis (const int volatile *) v_int_pointer" \ "type = const volatile int${ws}\\*" \ - "(const int volatile *)" + "cast to const int volatile *" gdb_test "whatis (volatile int const *) v_int_pointer" \ "type = const volatile int${ws}\\*" \ - "(volatile int const *)" + "cast to volatile int const *" gdb_test "whatis (int const volatile *) v_int_pointer" \ "type = const volatile int${ws}\\*" \ - "(int const volatile *)" + "cast to int const volatile *" gdb_test "whatis (int volatile const *) v_int_pointer" \ "type = const volatile int${ws}\\*" \ - "(int volatile const *)" + "cast to int volatile const *" gdb_test "whatis (int * const volatile) v_int_pointer" \ "type = int${ws}\\*${ws}const volatile" \ - "(int * const volatile)" + "cast to int * const volatile" gdb_test "whatis (int * volatile const) v_int_pointer" \ "type = int${ws}\\*${ws}const volatile" \ - "(int * volatile const)" + "cast to int * volatile const" # @@ -208,65 +208,65 @@ proc do_test {dir options} { #gdb_test "whatis (signed const char) v_signed_char" \ # "type = const char" \ - # "(signed const char)" + # "cast to signed const char" #gdb_test "whatis (unsigned const char) v_unsigned_char" \ # "type = const (unsigned char|char)" \ - # "(unsigned const char)" + # "cast to unsigned const char" #gdb_test "whatis (signed const short) v_signed_short" \ # "type = const (short|short int|signed short|signed short int)" \ - # "(signed const short)" + # "cast to signed const short" #gdb_test "whatis (unsigned const short) v_unsigned_short" \ # "type = const (unsigned short|short unsigned int)" \ - # "(unsigned const short)" + # "cast to unsigned const short" #gdb_test "whatis (signed const int) v_signed_int" \ # "type = const (signed int|int)" \ - # "(signed const int)" + # "cast to signed const int" #gdb_test "whatis (unsigned const int) v_unsigned_int" \ # "type = const unsigned int" \ - # "(unsigned const int)" + # "cast to unsigned const int" #gdb_test "whatis (signed const long) v_signed_long" \ # "type = const (signed |)long( int|)" \ - # "(signed const long)" + # "cast to signed const long" #gdb_test "whatis (unsigned const long) v_unsigned_long" \ # "type = const (unsigned long|long unsigned int)" \ - # "(unsigned const long)" + # "cast to unsigned const long" #gdb_test "whatis (signed const long long) v_signed_long_long" \ # "type = const (signed |)long long( int|)" \ - # "(signed const long long)" + # "cast to signed const long long" #gdb_test "whatis (unsigned const long long) v_unsigned_long_long" \ # "type = const (unsigned long long|long long unsigned int)" \ - # "(const unsigned long long)" + # "cast to const unsigned long long" #gdb_test "whatis (signed volatile char) v_signed_char" \ # "type = volatile char" \ - # "(signed volatile char)" + # "cast to signed volatile char" #gdb_test "whatis (unsigned volatile char) v_unsigned_char" \ # "type = volatile (unsigned char|char)" \ - # "(unsigned volatile char)" + # "cast to unsigned volatile char" #gdb_test "whatis (signed volatile short) v_signed_short" \ # "type = volatile (short|short int|signed short|signed short int)" \ - # "(signed volatile short)" + # "cast to signed volatile short" #gdb_test "whatis (unsigned volatile short) v_unsigned_short" \ # "type = volatile (unsigned short|short unsigned int)" \ - # "(unsigned volatile short)" + # "cast to unsigned volatile short" #gdb_test "whatis (signed volatile int) v_signed_int" \ # "type = volatile (signed int|int)" \ - # "(signed volatile int)" + # "cast to signed volatile int" #gdb_test "whatis (unsigned volatile int) v_unsigned_int" \ # "type = volatile unsigned int" \ - # "(unsigned volatile int)" + # "cast to unsigned volatile int" #gdb_test "whatis (signed volatile long) v_signed_long" \ # "type = volatile (signed |)long( int|)" \ - # "(signed volatile long)" + # "cast to signed volatile long" #gdb_test "whatis (unsigned volatile long) v_unsigned_long" \ # "type = volatile (unsigned long|long unsigned int)" \ - # "(unsigned volatile long)" + # "cast to unsigned volatile long" #gdb_test "whatis (signed volatile long long) v_signed_long_long" \ # "type = volatile (signed |)long long( int|)" \ - # "(signed volatile long long)" + # "cast to signed volatile long long" #gdb_test "whatis (unsigned volatile long long) v_unsigned_long_long" \ # "type = volatile (unsigned long long|long long unsigned int)" \ - # "(unsigned volatile long long)" + # "cast to unsigned volatile long long" # # Now put the 'const' and 'volatile' keywords after the base type. @@ -274,107 +274,107 @@ proc do_test {dir options} { gdb_test "whatis (char const) v_char" \ "type = const char" \ - "(char const)" + "cast to char const" gdb_test "whatis (signed char const) v_signed_char" \ "type = const signed char" \ - "(signed char const)" + "cast to signed char const" gdb_test "whatis (unsigned char const) v_unsigned_char" \ "type = const (unsigned char|char)" \ - "(unsigned char const)" + "cast to unsigned char const" gdb_test "whatis (short const) v_short" \ "type = const (short|short int)" \ - "(short const)" + "cast to short const" gdb_test "whatis (signed short const) v_signed_short" \ "type = const (short|short int|signed short|signed short int)" \ - "(signed short const)" + "cast to signed short const" gdb_test "whatis (unsigned short const) v_unsigned_short" \ "type = const (unsigned short|short unsigned int)" \ - "(unsigned short const)" + "cast to unsigned short const" gdb_test "whatis (int const) v_int" \ "type = const int" \ - "(int const)" + "cast to int const" gdb_test "whatis (signed int const) v_signed_int" \ "type = const (signed int|int)" \ - "(signed int const)" + "cast to signed int const" gdb_test "whatis (unsigned int const) v_unsigned_int" \ "type = const unsigned int" \ - "(unsigned int const)" + "cast to unsigned int const" gdb_test "whatis (long const) v_long" \ "type = const (long|long int)" \ - "(long const)" + "cast to long const" gdb_test "whatis (signed long const) v_signed_long" \ "type = const (signed |)long( int|)" \ - "(signed long const)" + "cast to signed long const" gdb_test "whatis (unsigned long const) v_unsigned_long" \ "type = const (unsigned long|long unsigned int)" \ - "(unsigned long const)" + "cast to unsigned long const" gdb_test "whatis (long long const) v_long_long" \ "type = const long long( int|)" \ - "(long long const)" + "cast to long long const" gdb_test "whatis (signed long long const) v_signed_long_long" \ "type = const (signed |)long long( int|)" \ - "(signed long long const)" + "cast to signed long long const" gdb_test "whatis (unsigned long long const) v_unsigned_long_long" \ "type = const (unsigned long long|long long unsigned int)" \ - "(unsigned long long const)" + "cast to unsigned long long const" gdb_test "whatis (float const) v_float" \ "type = const float" \ - "(float const)" + "cast to float const" gdb_test "whatis (double const) v_double" \ "type = const double" \ - "(double const)" + "cast to double const" gdb_test "whatis (char volatile) v_char" \ "type = volatile char" \ - "(char volatile)" + "cast to char volatile" gdb_test "whatis (signed char volatile) v_signed_char" \ "type = volatile signed char" \ - "(signed char volatile)" + "cast to signed char volatile" gdb_test "whatis (unsigned char volatile) v_unsigned_char" \ "type = volatile (unsigned char|char)" \ - "(unsigned char volatile)" + "cast to unsigned char volatile" gdb_test "whatis (short volatile) v_short" \ "type = volatile (short|short int)" \ - "(short volatile)" + "cast to short volatile" gdb_test "whatis (signed short volatile) v_signed_short" \ "type = volatile (short|short int|signed short|signed short int)" \ - "(signed short volatile)" + "cast to signed short volatile" gdb_test "whatis (unsigned short volatile) v_unsigned_short" \ "type = volatile (unsigned short|short unsigned int)" \ - "(unsigned short volatile)" + "cast to unsigned short volatile" gdb_test "whatis (int volatile) v_int" \ "type = volatile int" \ - "(int volatile)" + "cast to int volatile" gdb_test "whatis (signed int volatile) v_signed_int" \ "type = volatile (signed int|int)" \ - "(signed int volatile)" + "cast to signed int volatile" gdb_test "whatis (unsigned int volatile) v_unsigned_int" \ "type = volatile unsigned int" \ - "(unsigned int volatile)" + "cast to unsigned int volatile" gdb_test "whatis (long volatile) v_long" \ "type = volatile (long|long int)" \ - "(long volatile)" + "cast to long volatile" gdb_test "whatis (signed long volatile) v_signed_long" \ "type = volatile (signed |)long( int|)" \ - "(signed long volatile)" + "cast to signed long volatile" gdb_test "whatis (unsigned long volatile) v_unsigned_long" \ "type = volatile (unsigned long|long unsigned int)" \ - "(unsigned long volatile)" + "cast to unsigned long volatile" gdb_test "whatis (long long volatile) v_long_long" \ "type = volatile long long( int|)" \ - "(long long volatile)" + "cast to long long volatile" gdb_test "whatis (signed long long volatile) v_signed_long_long" \ "type = volatile (signed |)long long( int|)" \ - "(signed long long volatile)" + "cast to signed long long volatile" gdb_test "whatis (unsigned long long volatile) v_unsigned_long_long" \ "type = volatile (unsigned long long|long long unsigned int)" \ - "(unsigned long long volatile)" + "cast to unsigned long long volatile" gdb_test "whatis (float volatile) v_float" \ "type = volatile float" \ - "(float volatile)" + "cast to float volatile" gdb_test "whatis (double volatile) v_double" \ "type = volatile double" \ - "(double volatile)" + "cast to double volatile" # # enums @@ -382,16 +382,16 @@ proc do_test {dir options} { gdb_test "whatis (const enum misordered) v_misordered" \ "type = const enum misordered" \ - "(const enum misordered)" + "cast to const enum misordered" gdb_test "whatis (enum misordered const) v_misordered" \ "type = const enum misordered" \ - "(enum misordered const)" + "cast to enum misordered const" gdb_test "whatis (volatile enum misordered) v_misordered" \ "type = volatile enum misordered" \ - "(volatile enum misordered)" + "cast to volatile enum misordered" gdb_test "whatis (enum misordered volatile) v_misordered" \ "type = volatile enum misordered" \ - "(enum misordered volatile)" + "cast to enum misordered volatile" # # Pointers @@ -399,41 +399,41 @@ proc do_test {dir options} { gdb_test "whatis (const int *) v_int_pointer" \ "type = const int${ws}\\*" \ - "(const int *)" + "cast to const int *" gdb_test "whatis (int const *) v_int_pointer" \ "type = const int${ws}\\*" \ - "(int const *)" + "cast to int const *" gdb_test "whatis (int * const) v_int_pointer" \ "type = int \\*${ws}const" \ - "(int * const)" + "cast to int * const" gdb_test "whatis (const int * const) v_int_pointer" \ "type = const int${ws}\\*${ws}const" \ - "(const int * const)" + "cast to const int * const" gdb_test "whatis (int const * const) v_int_pointer" \ "type = const int${ws}\\*${ws}const" \ - "(int const * const)" + "cast to int const * const" gdb_test "whatis (const int **) v_int_pointer_pointer" \ "type = const int${ws}\\*${ws}\\*" \ - "(const int **)" + "cast to const int **" gdb_test "whatis (int const **) v_int_pointer_pointer" \ "type = const int${ws}\\*${ws}\\*" \ - "(int const **)" + "cast to int const **" gdb_test "whatis (int ** const) v_int_pointer_pointer" \ "type = int \\*${ws}\\*${ws}const" \ - "(int ** const)" + "cast to int ** const" gdb_test "whatis (const int * const *) v_int_pointer_pointer" \ "type = const int${ws}\\*${ws}const${ws}\\*" \ - "(const int * const *)" + "cast to const int * const *" gdb_test "whatis (int const * const *) v_int_pointer_pointer" \ "type = const int${ws}\\*${ws}const${ws}\\*" \ - "(int const * const *)" + "cast to int const * const *" gdb_test "whatis (const int * const * const) v_int_pointer_pointer" \ "type = const int${ws}\\*${ws}const${ws}\\*${ws}const" \ - "(const int * const * const)" + "cast to const int * const * const" gdb_test "whatis (int const * const * const) v_int_pointer_pointer" \ "type = const int${ws}\\*${ws}const${ws}\\*${ws}const" \ - "(int const * const * const)" + "cast to int const * const * const" # # Arrays TODO @@ -449,46 +449,46 @@ proc do_test {dir options} { gdb_test "whatis (const struct t_struct) v_struct1" \ "type = const struct t_struct" \ - "(const struct t_struct)" + "cast to const struct t_struct" gdb_test "whatis (const union t_union) v_union" \ "type = const union t_union" \ - "(const union t_union)" + "cast to const union t_union" gdb_test "whatis (struct t_struct const) v_struct1" \ "type = const struct t_struct" \ - "(struct t_struct const)" + "cast to struct t_struct const" gdb_test "whatis (union t_union const) v_union" \ "type = const union t_union" \ - "(union t_union const)" + "cast to union t_union const" gdb_test "whatis (const struct t_struct *) &v_struct1" \ "type = const struct t_struct${ws}\\*" \ - "(const struct t_struct *)" + "cast to const struct t_struct *" gdb_test "whatis (const union t_union *) &v_union" \ "type = const union t_union${ws}\\*" \ - "(const union t_union *)" + "cast to const union t_union *" gdb_test "whatis (struct t_struct const *) &v_struct1" \ "type = const struct t_struct${ws}\\*" \ - "(struct t_struct const *)" + "cast to struct t_struct const *" gdb_test "whatis (union t_union const *) &v_union" \ "type = const union t_union${ws}\\*" \ - "(union t_union const *)" + "cast to union t_union const *" gdb_test "whatis (struct t_struct * const) &v_struct1" \ "type = struct t_struct${ws}\\*${ws}const" \ - "(struct t_struct * const)" + "cast to struct t_struct * const" gdb_test "whatis (union t_union * const) &v_union" \ "type = union t_union${ws}\\*${ws}const" \ - "(union t_union * const)" + "cast to union t_union * const" gdb_test "whatis (const struct t_struct * const) &v_struct1" \ "type = const struct t_struct${ws}\\*${ws}const" \ - "(const struct t_struct * const)" + "cast to const struct t_struct * const" gdb_test "whatis (const union t_union * const) &v_union" \ "type = const union t_union${ws}\\*${ws}const" \ - "(const union t_union * const)" + "cast to const union t_union * const" gdb_test "whatis (struct t_struct const * const) &v_struct1" \ "type = const struct t_struct${ws}\\*${ws}const" \ - "(struct t_struct const * const)" + "cast to struct t_struct const * const" gdb_test "whatis (union t_union const * const) &v_union" \ "type = const union t_union${ws}\\*${ws}const" \ - "(union t_union const * const)" + "cast to union t_union const * const" # # Function pointers TODO diff --git a/gdb/testsuite/gdb.base/eval-skip.exp b/gdb/testsuite/gdb.base/eval-skip.exp index 7b28513..e8f766e 100644 --- a/gdb/testsuite/gdb.base/eval-skip.exp +++ b/gdb/testsuite/gdb.base/eval-skip.exp @@ -54,86 +54,63 @@ gdb_test_no_output "set variable y=2" "set variable y=2" gdb_test_no_output "set variable z=2" "set variable z=2" gdb_test_no_output "set variable w=3" "set variable w=3" -gdb_test "print (0 && (x+y))" ".$decimal = $false" \ - "print value of (0 && (x+y))" +proc test { val re } { + gdb_test "print $val" $re "print value of $val value" +} + +test "(0 && (x+y))" ".$decimal = $false" -gdb_test "print (0 && (x-y))" ".$decimal = $false" \ - "print value of (0 && (x-y))" +test "(0 && (x-y))" ".$decimal = $false" -gdb_test "print (0 && (x*y))" ".$decimal = $false" \ - "print value of (0 && (x*y))" +test "(0 && (x*y))" ".$decimal = $false" -gdb_test "print (0 && (x/y))" ".$decimal = $false" \ - "print value of (0 && (x/y))" +test "(0 && (x/y))" ".$decimal = $false" -gdb_test "print (0 && (x%y))" ".$decimal = $false" \ - "print value of (0 && (x%y))" +test "(0 && (x%y))" ".$decimal = $false" -gdb_test "print (0 && (x&&y))" ".$decimal = $false" \ - "print value of (0 && (x&&y))" +test "(0 && (x&&y))" ".$decimal = $false" -gdb_test "print (0 && (x||y))" ".$decimal = $false" \ - "print value of (0 && (x||y))" +test "(0 && (x||y))" ".$decimal = $false" -gdb_test "print (0 && (x&y))" ".$decimal = $false" \ - "print value of (0 && (x&y))" +test "(0 && (x&y))" ".$decimal = $false" -gdb_test "print (0 && (x|y))" ".$decimal = $false" \ - "print value of (0 && (x|y))" +test "(0 && (x|y))" ".$decimal = $false" -gdb_test "print (0 && (x^y))" ".$decimal = $false" \ - "print value of (0 && (x^y))" +test "(0 && (x^y))" ".$decimal = $false" -gdb_test "print (0 && (x < y))" ".$decimal = $false" \ - "print value of (0 && (x < y))" +test "(0 && (x < y))" ".$decimal = $false" -gdb_test "print (0 && (x <= y))" ".$decimal = $false" \ - "print value of (0 && (x <= y))" +test "(0 && (x <= y))" ".$decimal = $false" -gdb_test "print (0 && (x>y))" ".$decimal = $false" \ - "print value of (0 && (x>y))" +test "(0 && (x>y))" ".$decimal = $false" -gdb_test "print (0 && (x>=y))" ".$decimal = $false" \ - "print value of (0 && (x>=y))" +test "(0 && (x>=y))" ".$decimal = $false" -gdb_test "print (0 && (x==y))" ".$decimal = $false" \ - "print value of (0 && (x==y))" +test "(0 && (x==y))" ".$decimal = $false" -gdb_test "print (0 && (x!=y))" ".$decimal = $false" \ - "print value of (0 && (x!=y))" +test "(0 && (x!=y))" ".$decimal = $false" -gdb_test "print (0 && (x<<31))" ".$decimal = $false" \ - "print value of (0 && (x<<31))" +test "(0 && (x<<31))" ".$decimal = $false" -gdb_test "print (0 && (x>>31))" ".$decimal = $false" \ - "print value of (0 && (x>>31))" +test "(0 && (x>>31))" ".$decimal = $false" -gdb_test "print (0 && (!x))" ".$decimal = $false" \ - "print value of (0 && (!x))" +test "(0 && (!x))" ".$decimal = $false" -gdb_test "print (0 && (~x))" ".$decimal = $false" \ - "print value of (0 && (~x))" +test "(0 && (~x))" ".$decimal = $false" -gdb_test "print (0 && (-x))" ".$decimal = $false" \ - "print value of (0 && (-x))" +test "(0 && (-x))" ".$decimal = $false" -gdb_test "print (0 && (x++))" ".$decimal = $false" \ - "print value of (0 && (x++))" +test "(0 && (x++))" ".$decimal = $false" -gdb_test "print (0 && (++x))" ".$decimal = $false" \ - "print value of (0 && (++x))" +test "(0 && (++x))" ".$decimal = $false" -gdb_test "print (0 && (x--))" ".$decimal = $false" \ - "print value of (0 && (x--))" +test "(0 && (x--))" ".$decimal = $false" -gdb_test "print (0 && (--x))" ".$decimal = $false" \ - "print value of (0 && (--x))" +test "(0 && (--x))" ".$decimal = $false" -gdb_test "print (0 && (x+=7))" ".$decimal = $false" \ - "print value of (0 && (x+=7))" +test "(0 && (x+=7))" ".$decimal = $false" -gdb_test "print (0 && (x=y))" ".$decimal = $false" \ - "print value of (0 && (x=y))" +test "(0 && (x=y))" ".$decimal = $false" gdb_exit diff --git a/gdb/testsuite/gdb.base/examine-backward.exp b/gdb/testsuite/gdb.base/examine-backward.exp index dcb1371..fe3d13e 100644 --- a/gdb/testsuite/gdb.base/examine-backward.exp +++ b/gdb/testsuite/gdb.base/examine-backward.exp @@ -172,17 +172,17 @@ with_test_prefix "char-width=1, print-max=20" { } gdb_test "x/-xb" "0x39" "take 1 char backward again" gdb_test "x/-s" "\"01234567890123456789\"\.\.\." \ - "take 1 string backward (1/6)" + "take 1 string backward, 1/6" gdb_test "x/-s" "\".+\"" \ - "take 1 string backward (2/6)" + "take 1 string backward, 2/6" gdb_test "x/-s" "\"\"" \ - "take 1 string backward (3/6)" + "take 1 string backward, 3/6" gdb_test "x/-s" "\"\"" \ - "take 1 string backward (4/6)" + "take 1 string backward, 4/6" gdb_test "x/-s" "\"GHIJKLMNOPQRSTUVWXYZ\"" \ - "take 1 string backward (5/6)" + "take 1 string backward, 5/6" gdb_test "x/-s" "\"ABCDEFGHIJKLMNOPQRST\"\.\.\." \ - "take 1 string backward (6/6)" + "take 1 string backward, 6/6" } with_test_prefix "char-width=2, print-max=20" { @@ -214,17 +214,17 @@ with_test_prefix "char-width=2, print-max=20" { } gdb_test "x/-xh" "0x0039" "take 1 char backward again" gdb_test "x/-sh" "u\"01234567890123456789\"\.\.\." \ - "take 1 string backward (1/6)" + "take 1 string backward, 1/6" gdb_test "x/-sh" "u\".+\"" \ - "take 1 string backward (2/6)" + "take 1 string backward, 2/6" gdb_test "x/-sh" "u\"\"" \ - "take 1 string backward (3/6)" + "take 1 string backward, 3/6" gdb_test "x/-sh" "u\"\"" \ - "take 1 string backward (4/6)" + "take 1 string backward, 4/6" gdb_test "x/-sh" "u\"GHIJKLMNOPQRSTUVWXYZ\"" \ - "take 1 string backward (5/6)" + "take 1 string backward, 5/6" gdb_test "x/-sh" "u\"ABCDEFGHIJKLMNOPQRST\"\.\.\." \ - "take 1 string backward (6/6)" + "take 1 string backward, 6/6" } with_test_prefix "char-width=4, print-max=20" { @@ -256,17 +256,17 @@ with_test_prefix "char-width=4, print-max=20" { } gdb_test "x/-xw" "0x00000039" "take 1 char backward again" gdb_test "x/-sw" "U\"01234567890123456789\"\.\.\." \ - "take 1 string backward (1/6)" + "take 1 string backward, 1/6" gdb_test "x/-sw" "U\".+\"" \ - "take 1 string backward (2/6)" + "take 1 string backward, 2/6" gdb_test "x/-sw" "U\"\"" \ - "take 1 string backward (3/6)" + "take 1 string backward, 3/6" gdb_test "x/-sw" "U\"\"" \ - "take 1 string backward (4/6)" + "take 1 string backward, 4/6" gdb_test "x/-sw" "U\"GHIJKLMNOPQRSTUVWXYZ\"" \ - "take 1 string backward (5/6)" + "take 1 string backward, 5/6" gdb_test "x/-sw" "U\"ABCDEFGHIJKLMNOPQRST\"\.\.\." \ - "take 1 string backward (6/6)" + "take 1 string backward, 6/6" } with_test_prefix "char-width=2, print-max=0" { @@ -299,17 +299,17 @@ with_test_prefix "char-width=2, print-max=0" { } gdb_test "x/-xh" "0x0000" "take 1 char backward" gdb_test "x/-sh" "u\"!!!!!!\"" \ - "take 1 string backward (1/6)" + "take 1 string backward, 1/6" gdb_test "x/-sh" "u\"012345678901234567890123456789\"" \ - "take 1 string backward (2/6)" + "take 1 string backward, 2/6" gdb_test "x/-sh" "u\".+\"" \ - "take 1 string backward (3/6)" + "take 1 string backward, 3/6" gdb_test "x/-sh" "u\"\"" \ - "take 1 string backward (4/6)" + "take 1 string backward, 4/6" gdb_test "x/-sh" "u\"\"" \ - "take 1 string backward (5/6)" + "take 1 string backward, 5/6" gdb_test "x/-sh" "u\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"" \ - "take 1 string backward (6/6)" + "take 1 string backward, 6/6" } with_test_prefix "char-width=1, print-max=4" { @@ -326,13 +326,13 @@ with_test_prefix "char-width=1, print-max=4" { "\"\"" } gdb_test "x/-xb" "0x00" "take 1 byte backward" - gdb_test_sequence "x/-4s" "take 4 strings backward (1/2)" { + gdb_test_sequence "x/-4s" "take 4 strings backward, 1/2" { "\"TUVW\"\.\.\." "\"XYZ\"" "\"\"" "\"\"" } - gdb_test_sequence "x/-4s" "take 4 strings backward (2/2)" { + gdb_test_sequence "x/-4s" "take 4 strings backward, 2/2" { "\"CDEF\"\.\.\." "\"GHIJ\"\.\.\." "\"KLMN\"\.\.\." @@ -348,9 +348,9 @@ with_test_prefix "backward disassemble general" { set main_re "main(\\(\\))?" gdb_test "x/i main" "0x\[0-9a-fA-F\]+ <$main_re>:\t.*" \ - "move the current position to main (x/i)" + "move the current position to main, x/i" gdb_test "x/-i" "0x\[0-9a-fA-F\]+ <$main_re>:\t.*" \ - "move the current position to main (x/-i)" + "move the current position to main, x/-i" for {set i 0} {$i < [llength $length_to_examine]} {incr i} { set len [lindex $length_to_examine $i] set instructions [capture_command_output "x/${len}i" ""] diff --git a/gdb/testsuite/gdb.base/exprs.exp b/gdb/testsuite/gdb.base/exprs.exp index 0f8c53b..375af6b 100644 --- a/gdb/testsuite/gdb.base/exprs.exp +++ b/gdb/testsuite/gdb.base/exprs.exp @@ -46,9 +46,9 @@ proc test_expr { args } { } set last_ent [expr [llength $args] - 1] set testname [lindex $args $last_ent] - gdb_test [lindex $args 0] ".*" "$testname (setup)" + gdb_test [lindex $args 0] ".*" "$testname, setup" for {set x 1} {$x < $last_ent} {set x [expr $x + 2]} { - gdb_test [lindex $args $x] [lindex $args [expr $x + 1]] "$testname ([lindex $args $x])" + gdb_test [lindex $args $x] [lindex $args [expr $x + 1]] "$testname, [lindex $args $x]" } } # diff --git a/gdb/testsuite/gdb.base/fileio.exp b/gdb/testsuite/gdb.base/fileio.exp index 4b01248..f31a775 100644 --- a/gdb/testsuite/gdb.base/fileio.exp +++ b/gdb/testsuite/gdb.base/fileio.exp @@ -149,23 +149,23 @@ gdb_test continue \ gdb_test continue \ "Continuing\\..*isatty 1:.*OK$stop_msg" \ -"Isatty (stdin)" +"Isatty, stdin" gdb_test continue \ "Continuing\\..*isatty 2:.*OK$stop_msg" \ -"Isatty (stdout)" +"Isatty, stdout" gdb_test continue \ "Continuing\\..*isatty 3:.*OK$stop_msg" \ -"Isatty (stderr)" +"Isatty, stderr" gdb_test continue \ "Continuing\\..*isatty 4:.*OK$stop_msg" \ -"Isatty (invalid fd)" +"Isatty, invalid fd" gdb_test continue \ "Continuing\\..*isatty 5:.*OK$stop_msg" \ -"Isatty (open file)" +"Isatty, open file" gdb_test_no_output "set debug remote 1" set msg "System says shell is not available" diff --git a/gdb/testsuite/gdb.base/foll-exec.exp b/gdb/testsuite/gdb.base/foll-exec.exp index e162cdf..206e713 100644 --- a/gdb/testsuite/gdb.base/foll-exec.exp +++ b/gdb/testsuite/gdb.base/foll-exec.exp @@ -139,23 +139,23 @@ proc do_exec_tests {} { send_gdb "print global_i\n" gdb_expect { -re ".* = 0.*$gdb_prompt $"\ - {pass "print execd-program/global_i (after execlp)"} - -re "$gdb_prompt $" {fail "print execd-program/global_i (after execlp)"} - timeout {fail "(timeout) print execd-program/global_i (after execlp)"} + {pass "print execd-program/global_i, after execlp"} + -re "$gdb_prompt $" {fail "print execd-program/global_i, after execlp"} + timeout {fail "(timeout) print execd-program/global_i, after execlp"} } send_gdb "print local_j\n" gdb_expect { -re ".* = 2.*$gdb_prompt $"\ - {pass "print execd-program/local_j (after execlp)"} - -re "$gdb_prompt $" {fail "print execd-program/local_j (after execlp)"} - timeout {fail "(timeout) print execd-program/local_j (after execlp)"} + {pass "print execd-program/local_j, after execlp"} + -re "$gdb_prompt $" {fail "print execd-program/local_j, after execlp"} + timeout {fail "(timeout) print execd-program/local_j, after execlp"} } send_gdb "print local_k\n" gdb_expect { -re "No symbol \"local_k\" in current context.*$gdb_prompt $"\ - {pass "print follow-exec/local_k (after execlp)"} - -re "$gdb_prompt $" {fail "print follow-exec/local_k (after execlp)"} - timeout {fail "(timeout) print follow-exec/local_k (after execlp)"} + {pass "print follow-exec/local_k, after execlp"} + -re "$gdb_prompt $" {fail "print follow-exec/local_k, after execlp"} + timeout {fail "(timeout) print follow-exec/local_k, after execlp"} } # Explicitly kill this program, or a subsequent rerun actually runs @@ -288,9 +288,9 @@ proc do_exec_tests {} { send_gdb "print local_j\n" gdb_expect { -re ".* = 3.*$gdb_prompt $"\ - {pass "print execd-program/local_j (after execl)"} - -re "$gdb_prompt $" {fail "print execd-program/local_j (after execl)"} - timeout {fail "(timeout) print execd-program/local_j (after execl)"} + {pass "print execd-program/local_j, after execl"} + -re "$gdb_prompt $" {fail "print execd-program/local_j, after execl"} + timeout {fail "(timeout) print execd-program/local_j, after execl"} } # Explicitly kill this program, or a subsequent rerun actually runs @@ -349,9 +349,9 @@ proc do_exec_tests {} { send_gdb "print local_j\n" gdb_expect { -re ".* = 2.*$gdb_prompt $"\ - {pass "print execd-program/local_j (after execv)"} - -re "$gdb_prompt $" {fail "print execd-program/local_j (after execv)"} - timeout {fail "(timeout) print execd-program/local_j (after execv)"} + {pass "print execd-program/local_j, after execv"} + -re "$gdb_prompt $" {fail "print execd-program/local_j, after execv"} + timeout {fail "(timeout) print execd-program/local_j, after execv"} } # Explicitly kill this program, or a subsequent rerun actually runs diff --git a/gdb/testsuite/gdb.base/gcorebg.c b/gdb/testsuite/gdb.base/gcorebg.c new file mode 100644 index 0000000..9b585b5 --- /dev/null +++ b/gdb/testsuite/gdb.base/gcorebg.c @@ -0,0 +1,76 @@ +/* Copyright 2007-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/>. */ + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <sys/wait.h> +#include <errno.h> + +/* Expects 4 arguments: + + 1. Either 'standard' or 'detached', where 'standard' tests + a general gcore script spawn with its controlling terminal available + and 'detached' tests gcore script spawn without its controlling + terminal available. + 2. Path to the gcore script. + 3. Path to the data-directory to pass to the gcore script. + 4. The core file output name. */ + +int +main (int argc, char **argv) +{ + pid_t pid = 0; + pid_t ppid; + char buf[1024*2 + 500]; + int gotint, res; + + assert (argc == 5); + + pid = fork (); + + switch (pid) + { + case 0: + if (strcmp (argv[1], "detached") == 0) + setpgrp (); + ppid = getppid (); + gotint = snprintf (buf, sizeof (buf), "%s -d %s -o %s %d", + argv[2], argv[3], argv[4], (int) ppid); + assert (gotint < sizeof (buf)); + res = system (buf); + assert (res != -1); + break; + + case -1: + perror ("fork err\n"); + exit (1); + break; + + default: + do + { + res = waitpid (pid, NULL, 0); + } + while (res == -1 && errno == EINTR); + + assert (res == pid); + break; + } + + return 0; +} diff --git a/gdb/testsuite/gdb.base/gcorebg.exp b/gdb/testsuite/gdb.base/gcorebg.exp new file mode 100644 index 0000000..c271251 --- /dev/null +++ b/gdb/testsuite/gdb.base/gcorebg.exp @@ -0,0 +1,82 @@ +# Copyright 2007-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/>. +# +# This is a test for the gcore script (not the gcore command from +# inside GDB). It also tests the gcore script being run without its +# accessible terminal. + +standard_testfile +require {!is_remote host} +require {!is_remote target} +require has_gcore_script +require can_spawn_for_attach + +set corefile [standard_output_file ${testfile}.core] + +if {[build_executable "failed to build" $testfile ${srcfile}] == -1 } { + return -1 +} + +# Cleanup. + +proc core_clean {} { + global corefile + + foreach file [glob -nocomplain [join [list $corefile *] ""]] { + verbose "Delete file $file" 1 + remote_file target delete $file + } +} +core_clean + +# Generate the core file. +proc test_body { detached } { + global binfile + global GCORE + global corefile + global GDB_DATA_DIRECTORY + + # We can't use gdb_test_multiple here because GDB is not started. + set res [remote_spawn target "$binfile $detached $GCORE $GDB_DATA_DIRECTORY $corefile"] + if { ![gdb_assert { ![expr {$res < 0 || $res == ""}] } \ + "spawned gcore"] } { + return + } + + set saw_corefile_created false + set testname "Spawned gcore finished" + remote_expect target 20 { + timeout { + fail "$testname (timeout)" + remote_exec target "kill -9 -[exp_pid -i $res]" + return + } + -re "Saved corefile \[^\r\n\]+\r\n" { + set saw_corefile_created true + exp_continue + } + eof { + gdb_assert { $saw_corefile_created } $testname + } + } + + gdb_assert {1 == [llength [glob -nocomplain [join [list $corefile *] ""]]]}\ + "Core file generated by gcore" + core_clean +} + +foreach_with_prefix detached { detached standard } { + test_body $detached +} diff --git a/gdb/testsuite/gdb.base/hbreak2.exp b/gdb/testsuite/gdb.base/hbreak2.exp index 8f5735b..d22b363 100644 --- a/gdb/testsuite/gdb.base/hbreak2.exp +++ b/gdb/testsuite/gdb.base/hbreak2.exp @@ -150,7 +150,7 @@ delete_breakpoints # gdb_test "hbreak -q main" \ "Hardware assisted breakpoint.*at.* file .*$srcfile, line.*" \ - "hardware breakpoint function (2)" + "hardware breakpoint function, 2" gdb_run_cmd gdb_test "" \ "Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.* \{.*" \ @@ -162,7 +162,7 @@ delete_breakpoints # gdb_test "hbreak $bp_location1" \ "Hardware assisted breakpoint.*at.* file .*$srcfile, line $bp_location1\\." \ - "hardware breakpoint line number (2)" + "hardware breakpoint line number, 2" gdb_test "continue" \ "Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:$bp_location1.*$bp_location1\[\t \]+printf.*factorial.*" \ "run until breakpoint set at a line number" @@ -173,7 +173,7 @@ delete_breakpoints # gdb_test "hbreak $srcfile:factorial" \ "Hardware assisted breakpoint.*at.* file .*$srcfile, line.*" \ - "hardware breakpoint function in file (2)" + "hardware breakpoint function in file, 2" for {set i 6} {$i >= 1} {incr i -1} { gdb_test "continue" \ "Continuing\\..*Breakpoint \[0-9\]+, factorial \\(value=$i\\) at .*$srcfile:$bp_location7.*$bp_location7\[\t \]+.*if .value > 1. \{.*" \ @@ -186,7 +186,7 @@ delete_breakpoints # gdb_test "hbreak \"marker2\"" \ "Hardware assisted breakpoint.*at.* file .*$srcfile1, line.*" \ - "hardware breakpoint quoted function (2)" + "hardware breakpoint quoted function, 2" gdb_test "continue" \ "Continuing\\..*Breakpoint \[0-9\]+, (0x\[0-9a-f\]+ in )?marker2 \\(a=43\\) at .*$srcfile1:$bp_location8.*" \ "run until quoted breakpoint" @@ -196,7 +196,7 @@ delete_breakpoints # gdb_test "hbreak $srcfile:$bp_location2" \ "Hardware assisted breakpoint.*at.* file .*$srcfile, line $bp_location2\\." \ - "hardware breakpoint line number in file (2)" + "hardware breakpoint line number in file, 2" gdb_test "continue" \ "Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:$bp_location2.*$bp_location2\[\t \]+argc = \\(argc == 12345\\);.*" \ "run until file:linenum breakpoint" diff --git a/gdb/testsuite/gdb.base/history-duplicates.exp b/gdb/testsuite/gdb.base/history-duplicates.exp index b2f30e6..5ac4a35 100644 --- a/gdb/testsuite/gdb.base/history-duplicates.exp +++ b/gdb/testsuite/gdb.base/history-duplicates.exp @@ -46,7 +46,7 @@ proc run_print_on_each_thing { things } { set index 0 foreach thing $things { - gdb_test "print $thing" "" "printing $thing (item #$index)" + gdb_test "print $thing" "" "printing $thing, item #$index" incr index } } @@ -90,8 +90,8 @@ with_test_prefix "remove-duplicates=1" { check_prev_history_entry "print 1" check_prev_history_entry "print 2" check_prev_history_entry "print 0" - check_prev_history_entry "print 1" "(again)" - check_prev_history_entry "print 0" "(again)" + check_prev_history_entry "print 1" ", again" + check_prev_history_entry "print 0" ", again" } @@ -104,9 +104,9 @@ with_test_prefix "remove-duplicates=0" { run_print_on_each_thing { 0 0 1 1 } check_prev_history_entry "print 1" - check_prev_history_entry "print 1" "(again)" + check_prev_history_entry "print 1" ", again" check_prev_history_entry "print 0" - check_prev_history_entry "print 0" "(again)" + check_prev_history_entry "print 0" ", again" } diff --git a/gdb/testsuite/gdb.base/index-cache.exp b/gdb/testsuite/gdb.base/index-cache.exp index 0e19bfb..af64faa 100644 --- a/gdb/testsuite/gdb.base/index-cache.exp +++ b/gdb/testsuite/gdb.base/index-cache.exp @@ -19,7 +19,7 @@ standard_testfile .c -2.c if { [build_executable "failed to prepare" $testfile [list $srcfile $srcfile2] \ - {debug ldflags=-Wl,--build-id}] } { + {debug build-id}] } { return } diff --git a/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.exp b/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.exp index 85e3cc3..45086f6 100644 --- a/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.exp +++ b/gdb/testsuite/gdb.base/inline-frame-cycle-unwind.exp @@ -37,7 +37,7 @@ # mechanism such that the fact that "inline_frame" was inlined into # "normal_frame" would cause GDB to trigger an assertion. # -# This text makes use of a Python unwinder which can fake the cyclic +# This test makes use of a Python unwinder which can fake the cyclic # stack cycle, further the test sets up multiple levels of normal and # inline frames. At the point of testing the stack looks like this: # diff --git a/gdb/testsuite/gdb.base/interact.exp b/gdb/testsuite/gdb.base/interact.exp index b7a30e0..5779efc 100644 --- a/gdb/testsuite/gdb.base/interact.exp +++ b/gdb/testsuite/gdb.base/interact.exp @@ -38,7 +38,7 @@ gdb_test "source $script" "$script_output" \ gdb_test "print 3" "= 3" "sanity check with interactive-mode auto" gdb_test "show interactive-mode" \ "Debugger's interactive mode is auto \\(currently .*\\)\\." \ - "show interactive-mode (auto)" + "show interactive-mode, auto" # Test sourcing of the script with interactive mode `on'. # Verify that evaluating the script does not cause an unexpected @@ -49,7 +49,7 @@ gdb_test "source $script" "$script_output" \ gdb_test "print 4" "= 4" "sanity check with interactive-mode on" gdb_test "show interactive-mode" \ "Debugger's interactive mode is on\\." \ - "show interactive-mode (on)" + "show interactive-mode, on" # Test sourcing of the script with interactive mode `off'. # Verify that evaluating the script does not cause an unexpected @@ -60,5 +60,5 @@ gdb_test "source $script" "$script_output" \ gdb_test "print 5" "= 5" "sanity check with interactive-mode off" gdb_test "show interactive-mode" \ "Debugger's interactive mode is off\\." \ - "show interactive-mode (off)" + "show interactive-mode, off" 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.base/list-ambiguous0.c b/gdb/testsuite/gdb.base/list-ambiguous0.c index cff16e5..db11702 100644 --- a/gdb/testsuite/gdb.base/list-ambiguous0.c +++ b/gdb/testsuite/gdb.base/list-ambiguous0.c @@ -37,6 +37,6 @@ static int __attribute__ ((used)) ambiguous_var; int main (void) -{ +{ /* main prologue */ return 0; } diff --git a/gdb/testsuite/gdb.base/list-before-start.exp b/gdb/testsuite/gdb.base/list-before-start.exp new file mode 100644 index 0000000..5499257 --- /dev/null +++ b/gdb/testsuite/gdb.base/list-before-start.exp @@ -0,0 +1,36 @@ +# 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/>. + +# Test the "list" command to print the location around main before the +# program is started. + +standard_testfile list-ambiguous0.c + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} { + return -1 +} + +set fill "${decimal}\\s+\[^\n\r\]+" + +gdb_test_no_output "set listsize 10" + +gdb_test "list" \ + [multi_line \ + "${decimal}\\s+" \ + "${decimal}\\s+int" \ + "${decimal}\\s+main\[^\n\r\]+" \ + "${decimal}\\s+\\{ /\\* main prologue \\*/" \ + "${fill}" \ + "${fill}" ] diff --git a/gdb/testsuite/gdb.base/list-dot-nodebug.exp b/gdb/testsuite/gdb.base/list-dot-nodebug.exp index c9d732e..b7359be 100644 --- a/gdb/testsuite/gdb.base/list-dot-nodebug.exp +++ b/gdb/testsuite/gdb.base/list-dot-nodebug.exp @@ -34,21 +34,36 @@ standard_testfile .c -extra.c foreach_with_prefix debug {"none" "some"} { - set flags "nodebug" if {$debug == "some"} { - set flags "debug" - } + if {[prepare_for_testing_full "failed to prepare" \ + [list ${testfile}-${debug} $linkflags \ + $srcfile [list nodebug] \ + $srcfile2 [list debug]]]} { + return -1 + } - if {[prepare_for_testing_full "failed to prepare" \ - [list ${testfile}-${debug} $linkflags \ - $srcfile [list nodebug] \ - $srcfile2 [list $debug]]]} { - return -1 + # We don't test "list ." before starting with some debug info + # because GDB will choose the symtab that has debuginfo, and + # print the copyright blurb. This test isn't interested (yet?) + # in checking if this default location choice is consistent. + } else { + set executable ${testfile}-none + if {[build_executable "failed to prepare" ${executable} \ + [list $srcfile $srcfile2] $linkflags]} { + return -1 + } + + # Stripping is a backup in case the system has static libc debuginfo. + # We can continue the test even if it fails. + gdb_gnu_strip_debug $executable no-debuglink + + clean_restart ${executable} + + gdb_test "list ." \ + "^Insufficient debug info for showing source lines at default location" \ + "print before start" } - gdb_test "list ." \ - "^Insufficient debug info for showing source lines at default location" \ - "print before start" if { ![runto bar] } { return -1 diff --git a/gdb/testsuite/gdb.base/new-ui.exp b/gdb/testsuite/gdb.base/new-ui.exp index 2dfcbf7..a56d213 100644 --- a/gdb/testsuite/gdb.base/new-ui.exp +++ b/gdb/testsuite/gdb.base/new-ui.exp @@ -184,9 +184,11 @@ proc_with_prefix do_test_invalid_args {} { "new-ui with bad interpreter name" # Test that the TUI cannot be used for a new UI. - gdb_test "new-ui tui $extra_tty_name" \ - "interpreter 'tui' cannot be used with a new UI" \ - "new-ui with tui" + if [allow_tui_tests] { + gdb_test "new-ui tui $extra_tty_name" \ + "interpreter 'tui' cannot be used with a new UI" \ + "new-ui with tui" + } # Test that we can continue working normally. if ![runto_main] { diff --git a/gdb/testsuite/gdb.base/opaque.exp b/gdb/testsuite/gdb.base/opaque.exp index 1bd1918..d803714 100644 --- a/gdb/testsuite/gdb.base/opaque.exp +++ b/gdb/testsuite/gdb.base/opaque.exp @@ -66,7 +66,7 @@ if {[istarget "rs6000-*-aix*"] && !$gcc_compiled} { setup_xfail_on_opaque_pointer gdb_test "whatis foop" \ "type = struct foo \[*\]+" \ - "whatis on opaque struct pointer (statically)" + "whatis on opaque struct pointer, statically" # Ensure that we know the form of the structure that foop points to. @@ -122,7 +122,7 @@ if ![runto_main] { setup_xfail_on_opaque_pointer gdb_test "whatis foop" \ "type = struct foo \[*\]+" \ - "whatis on opaque struct pointer (dynamically)" + "whatis on opaque struct pointer, dynamically" # Ensure that we know the form of the thing foop points to. @@ -131,18 +131,18 @@ setup_xfail_on_opaque_pointer if {!$gcc_compiled} { setup_xfail "rs6000-*-*" } gdb_test "ptype foop" \ "type = struct foo \{\[\r\n\]+ int a;\[\r\n\]+ int b;\[\r\n\]+\} \[*\]+" \ - "ptype on opaque struct pointer (dynamically) 1" + "ptype on opaque struct pointer, dynamically 1" gdb_test "whatis afoo" \ "type = struct foo" \ - "whatis on opaque struct instance (dynamically) 1" + "whatis on opaque struct instance, dynamically 1" # Ensure that we know the form of afoo, an instance of a struct foo. gdb_test "ptype afoo" \ "type = struct foo \{\[\r\n\]+ int a;\[\r\n\]+ int b;\[\r\n\]+\}" \ - "ptype on opaque struct instance (dynamically) 1" + "ptype on opaque struct instance, dynamically 1" # Ensure that we know the form of an explicit struct foo. @@ -150,7 +150,7 @@ gdb_test "ptype afoo" \ if {!$gcc_compiled} { setup_xfail "rs6000-*-*" } gdb_test "ptype struct foo" \ "type = struct foo \{\[\r\n\]+ int a;\[\r\n\]+ int b;\[\r\n\]+\}" \ - "ptype on opaque struct tagname (dynamically) 1" + "ptype on opaque struct tagname, dynamically 1" # Now reload the symbols again so we forget about anything we might @@ -170,7 +170,7 @@ if ![runto getfoo] { setup_xfail_on_opaque_pointer gdb_test "whatis foop" \ "type = struct foo \[*\]+" \ - "whatis on opaque struct pointer (dynamically) 1" + "whatis on opaque struct pointer, dynamically 1" # Ensure that we know the form of the thing foop points to. @@ -178,22 +178,22 @@ gdb_test "whatis foop" \ setup_xfail_on_opaque_pointer gdb_test "ptype foop" \ "type = struct foo \{\[\r\n\]+ int a;\[\r\n\]+ int b;\[\r\n\]+\} \[*\]+" \ - "ptype on opaque struct pointer (dynamically) 2" + "ptype on opaque struct pointer, dynamically 2" gdb_test "whatis afoo" \ "type = struct foo" \ - "whatis on opaque struct instance (dynamically) 2" + "whatis on opaque struct instance, dynamically 2" # Ensure that we know the form of afoo, an instance of a struct foo. gdb_test "ptype afoo" \ "type = struct foo \{\[\r\n\]+ int a;\[\r\n\]+ int b;\[\r\n\]+\}" \ - "ptype on opaque struct instance (dynamically) 2" + "ptype on opaque struct instance, dynamically 2" # Ensure that we know the form of an explicit struct foo. gdb_test "ptype struct foo" \ "type = struct foo \{\[\r\n\]+ int a;\[\r\n\]+ int b;\[\r\n\]+\}" \ - "ptype on opaque struct tagname (dynamically) 2" + "ptype on opaque struct tagname, dynamically 2" diff --git a/gdb/testsuite/gdb.base/pending.exp b/gdb/testsuite/gdb.base/pending.exp index 737b0c4..5ee31d3 100644 --- a/gdb/testsuite/gdb.base/pending.exp +++ b/gdb/testsuite/gdb.base/pending.exp @@ -39,7 +39,7 @@ clean_restart gdb_test_multiple "break pendfunc1" "set pending breakpoint" { -re ".*Make breakpoint pending.*y or \\\[n\\\]. $" { - gdb_test "y" "Breakpoint.*pendfunc1.*pending." "set pending breakpoint (without symbols)" + gdb_test "y" "Breakpoint.*pendfunc1.*pending." "set pending breakpoint, without symbols" } } @@ -49,7 +49,7 @@ gdb_test "complete condition " "condition 1" gdb_test "info break" \ "Num Type\[ \]+Disp Enb Address\[ \]+What.* \[0-9\]+\[\t \]+breakpoint keep y.*PENDING.*pendfunc1.*" \ -"single pending breakpoint info (without symbols)" +"single pending breakpoint info, without symbols" with_test_prefix "first load" { gdb_load ${binfile} diff --git a/gdb/testsuite/gdb.base/printcmds.exp b/gdb/testsuite/gdb.base/printcmds.exp index 9132071a..40176c6 100644 --- a/gdb/testsuite/gdb.base/printcmds.exp +++ b/gdb/testsuite/gdb.base/printcmds.exp @@ -1186,7 +1186,7 @@ gdb_test_no_output "complete p -source" gdb_file_cmd ${binfile} -gdb_test "print \$pc" "No registers\\." "print \$pc (with file)" +gdb_test {print $pc} [string_to_regexp "No registers."] {print $pc, with file} gdb_test_no_output "set print sevenbit-strings" gdb_test_no_output "set print address off" diff --git a/gdb/testsuite/gdb.base/recurse.exp b/gdb/testsuite/gdb.base/recurse.exp index f5f0760..01ba55a 100644 --- a/gdb/testsuite/gdb.base/recurse.exp +++ b/gdb/testsuite/gdb.base/recurse.exp @@ -52,15 +52,15 @@ proc recurse_tests {} { # Continue inward for a few iterations gdb_test "continue" "Breakpoint.* recurse \\(a=9\\).*" \ - "continue to recurse (a = 9)" + "continue to recurse, a = 9" gdb_test "continue" "Breakpoint.* recurse \\(a=8\\).*" \ - "continue to recurse (a = 8)" + "continue to recurse, a = 8" gdb_test "continue" "Breakpoint.* recurse \\(a=7\\).*" \ - "continue to recurse (a = 7)" + "continue to recurse, a = 7" gdb_test "continue" "Breakpoint.* recurse \\(a=6\\).*" \ - "continue to recurse (a = 6)" + "continue to recurse, a = 6" gdb_test "continue" "Breakpoint.* recurse \\(a=5\\).*" \ - "continue to recurse (a = 5)" + "continue to recurse, a = 5" # Put a watchpoint on another instance of b # First we need to step over the assignment of b, so it has a known @@ -76,13 +76,13 @@ proc recurse_tests {} { # Continue inward for a few iterations gdb_test "continue" "Breakpoint.* recurse \\(a=4\\).*" \ - "continue to recurse (a = 4)" + "continue to recurse, a = 4" gdb_test "continue" "Breakpoint.* recurse \\(a=3\\).*" \ - "continue to recurse (a = 3)" + "continue to recurse, a = 3" gdb_test "continue" "Breakpoint.* recurse \\(a=2\\).*" \ - "continue to recurse (a = 2)" + "continue to recurse, a = 2" gdb_test "continue" "Breakpoint.* recurse \\(a=1\\).*" \ - "continue to recurse (a = 1)" + "continue to recurse, a = 1" # Continue until second set of b (second instance). gdb_test "continue" \ diff --git a/gdb/testsuite/gdb.base/setshow.exp b/gdb/testsuite/gdb.base/setshow.exp index 9eb44b3..9380331 100644 --- a/gdb/testsuite/gdb.base/setshow.exp +++ b/gdb/testsuite/gdb.base/setshow.exp @@ -67,12 +67,12 @@ proc_with_prefix test_setshow_annotate {} { #test set annotate 1 gdb_test "set annotate 1" ".*post-prompt.*" - gdb_test "show annotate" "Annotation_level is 1..*" "show annotate (1)" + gdb_test "show annotate" "Annotation_level is 1..*" "show annotate, 1" #test annotation_level 1 gdb_test "info line 1" "Line 1 of .* is at address .* but contains no code.*:1:0:beg:0x.*" "annotation_level 1" #test set annotate 0 gdb_test_no_output "set annotate 0" "set annotate 0" - gdb_test "show annotate" "Annotation_level is 0..*" "show annotate (0)" + gdb_test "show annotate" "Annotation_level is 0..*" "show annotate, 0" #test annotation_level 0 gdb_test "info line 1" "Line 1 of .* is at address .* but contains no code.*" "annotation_level 0" } @@ -121,13 +121,13 @@ proc_with_prefix test_setshow_check {} { "_gdb_setting check range on" #test show check range on - gdb_test "show check range" "Range checking is \"on\"\..*" "show check range (on)" + gdb_test "show check range" "Range checking is \"on\"\..*" "show check range, on" #test set check range off with trailing space gdb_test_no_output "set check range off " "set check range off" #test show check range off - gdb_test "show check range" "Range checking is \"off\"\..*" "show check range (off)" + gdb_test "show check range" "Range checking is \"off\"\..*" "show check range, off" gdb_test "p \$_gdb_setting(\"check range\")" " = \"off\"" \ "_gdb_setting check range off" @@ -144,7 +144,7 @@ proc_with_prefix test_setshow_check {} { # Test show check type on gdb_test "show check type" "Strict type checking is on\..*" \ - "show check type (on)" + "show check type, on" gdb_test "p \$_gdb_setting_str(\"check type\")" " = \"on\"" \ "_gdb_setting_str check type on" gdb_test "p \$_gdb_setting(\"check type\")" " = 1" \ @@ -159,7 +159,7 @@ proc_with_prefix test_setshow_check {} { # Test show check type off gdb_test "show check type" "Strict type checking is off\..*" \ - "show check type (off)" + "show check type, off" } proc_with_prefix test_setshow_breakpoint_pending {} { @@ -200,11 +200,11 @@ proc_with_prefix test_setshow_complaints {} { #test set complaints 100 gdb_test_no_output "set complaints 100" "set complaints 100" #test show complaints 100 - gdb_test "show complaints" "Max number of complaints about incorrect symbols is 100..*" "show complaints (100)" + gdb_test "show complaints" "Max number of complaints about incorrect symbols is 100..*" "show complaints, 100" #test set complaints 0 gdb_test_no_output "set complaints 0" "set complaints 0" #test show complaints 0 - gdb_test "show complaints" "Max number of complaints about incorrect symbols is 0..*" "show complaints (0)" + gdb_test "show complaints" "Max number of complaints about incorrect symbols is 0..*" "show complaints, 0" } proc_with_prefix test_setshow_confirm {} { @@ -213,11 +213,11 @@ proc_with_prefix test_setshow_confirm {} { #test set confirm off gdb_test_no_output "set confirm off" "set confirm off" #test show confirm off - gdb_test "show confirm" "Whether to confirm potentially dangerous operations is off..*" "show confirm (off)" + gdb_test "show confirm" "Whether to confirm potentially dangerous operations is off..*" "show confirm, off" #test set confirm on gdb_test_no_output "set confirm on" "set confirm on" #test show confirm on - gdb_test "show confirm" "Whether to confirm potentially dangerous operations is on..*" "show confirm (on)" + gdb_test "show confirm" "Whether to confirm potentially dangerous operations is on..*" "show confirm, on" } proc_with_prefix test_setshow_editing {} { @@ -331,7 +331,7 @@ proc_with_prefix test_setshow_history {} { #test show history filename foobar.baz gdb_test "show history filename" \ "The filename in which to record the command history is \"[string_to_regexp $PWD]/foobar.baz\"..*" \ - "show history filename (current_directory/foobar.baz)" + "show history filename, current_directory/foobar.baz" #test set history save on gdb_test_no_output "set history save on" "set history save on" @@ -356,13 +356,13 @@ proc_with_prefix test_setshow_language {} { gdb_test_no_output "set language asm" #test show language asm - gdb_test "show language" "The current source language is \"asm\"..*" "show language (asm)" + gdb_test "show language" "The current source language is \"asm\"..*" "show language, asm" #test set language rust, with a trailing space gdb_test_no_output "set language rust " "set language rust" #test show language rust - gdb_test "show language" "The current source language is \"rust\"..*" "show language (rust)" + gdb_test "show language" "The current source language is \"rust\"..*" "show language, rust" #test completion for set language. gdb_test "complete set language min" "set language minimal" \ @@ -372,7 +372,7 @@ proc_with_prefix test_setshow_language {} { gdb_test_no_output "set language auto" "set language auto" #test show language - gdb_test "show language" "The current source language is \"auto.*\"..*" "show language (auto)" + gdb_test "show language" "The current source language is \"auto.*\"..*" "show language, auto" } proc_with_prefix test_setshow_listsize {} { @@ -447,13 +447,13 @@ proc_with_prefix test_setshow_radix {} { gdb_test "set radix 16" "Input and output radices now set to decimal 16, hex 10, octal 20..*" #test show radix 16 - gdb_test "show radix" "Input and output radices set to decimal 16, hex 10, octal 20..*" "show radix (16)" + gdb_test "show radix" "Input and output radices set to decimal 16, hex 10, octal 20..*" "show radix, 16" #test set radix 10 gdb_test "set radix" "Input and output radices now set to decimal 10, hex a, octal 12..*" "set radix 10" #test show radix 10 - gdb_test "show radix" "Input and output radices set to decimal 10, hex a, octal 12..*" "show radix (10)" + gdb_test "show radix" "Input and output radices set to decimal 10, hex a, octal 12..*" "show radix, 10" } proc_with_prefix test_setshow_width {} { @@ -492,13 +492,13 @@ proc_with_prefix test_setshow_verbose {} { gdb_test_no_output "set verbose on" "set verbose on" #test show verbose on - gdb_test "show verbose" "Verbose printing of informational messages is on..*" "show verbose (on)" + gdb_test "show verbose" "Verbose printing of informational messages is on..*" "show verbose, on" #test set verbose off gdb_test_no_output "set verbose off" "set verbose off" #test show verbose off - gdb_test "show verbose" "Verbosity is off..*" "show verbose (off)" + gdb_test "show verbose" "Verbosity is off..*" "show verbose, off" } proc_with_prefix test_argument_preceded_by_space {} { diff --git a/gdb/testsuite/gdb.base/setvar.exp b/gdb/testsuite/gdb.base/setvar.exp index 9ac2402..416dcc6 100644 --- a/gdb/testsuite/gdb.base/setvar.exp +++ b/gdb/testsuite/gdb.base/setvar.exp @@ -390,13 +390,13 @@ set timeout $prev_timeout if {[is_c_compiler_gcc]} { gdb_test "print sef.field=sm1" ".*.\[0-9\]* = sm1" - gdb_test "print sef.field" ".*.\[0-9\]* = sm1" "print sef.field (sm1)" + gdb_test "print sef.field" ".*.\[0-9\]* = sm1" "print sef.field, sm1" gdb_test "print sef.field=s1" ".*.\[0-9\]* = s1" - gdb_test "print sef.field" ".*.\[0-9\]* = s1" "print sef.field (s1)" + gdb_test "print sef.field" ".*.\[0-9\]* = s1" "print sef.field, s1" gdb_test "print uef.field=u2" ".*.\[0-9\]* = u2" - gdb_test "print uef.field" ".*.\[0-9\]* = u2" "print uef.field (u2)" + gdb_test "print uef.field" ".*.\[0-9\]* = u2" "print uef.field, u2" gdb_test "print uef.field=u1" ".*.\[0-9\]* = u1" - gdb_test "print uef.field" ".*.\[0-9\]* = u1" "print uef.field (u1)" + gdb_test "print uef.field" ".*.\[0-9\]* = u1" "print uef.field, u1" # Test for truncation when assigning invalid values to bitfields. gdb_test "print sef.field=7" \ diff --git a/gdb/testsuite/gdb.base/skip.exp b/gdb/testsuite/gdb.base/skip.exp index d3936bb..ccc7ca3 100644 --- a/gdb/testsuite/gdb.base/skip.exp +++ b/gdb/testsuite/gdb.base/skip.exp @@ -31,9 +31,9 @@ set srcfile1 skip1.c # Right after we start gdb, there's no default file or function to skip. -gdb_test "skip file" "No default file now." "skip file (no default file)" +gdb_test "skip file" "No default file now." "skip file, no default file" gdb_test "skip function" "No default function now." -gdb_test "skip" "No default function now." "skip (no default function)" +gdb_test "skip" "No default function now." "skip, no default function" # Test elided args. @@ -59,8 +59,8 @@ gdb_test "info skip" "Not skipping any files or functions\." "info skip empty" # Create a skiplist entry for the current file and function. -gdb_test "skip file" "File .*$srcfile will be skipped when stepping\." "skip file ($srcfile)" -gdb_test "skip" "Function main will be skipped when stepping\." "skip (main)" +gdb_test "skip file" "File .*$srcfile will be skipped when stepping\." "skip file, $srcfile" +gdb_test "skip" "Function main will be skipped when stepping\." "skip, main" # Create a skiplist entry for a specified file and function. diff --git a/gdb/testsuite/gdb.base/solib-display.exp b/gdb/testsuite/gdb.base/solib-display.exp index 5c27f29..c9c66f6 100644 --- a/gdb/testsuite/gdb.base/solib-display.exp +++ b/gdb/testsuite/gdb.base/solib-display.exp @@ -126,7 +126,7 @@ foreach libsepdebug {NO IN SEP} { with_test_prefix "$libsepdebug" { "1: \\(int\\) a_global = 41" \ "warning: .*b_global.*" \ "3: \\(int\\) c_global = 43" \ - ] "after rerun (2)" + ] "after rerun, 2" # Now verify that displays which are not in the shared library # are not cleared permaturely. diff --git a/gdb/testsuite/gdb.base/solib-search.exp b/gdb/testsuite/gdb.base/solib-search.exp index 581046a..f038a04 100644 --- a/gdb/testsuite/gdb.base/solib-search.exp +++ b/gdb/testsuite/gdb.base/solib-search.exp @@ -108,9 +108,9 @@ proc test_backtrace { expect_fail } { set total_expected 5 if { $expect_fail } { - set testname "backtrace (with wrong libs)" + set testname "backtrace, with wrong libs" } else { - set testname "backtrace (with right libs)" + set testname "backtrace, with right libs" } # N.B. The order of the tests here is important. # We need to count each function in the backtrace, and expect matches @@ -137,7 +137,7 @@ proc test_backtrace { expect_fail } { exp_continue } -re "\[\r\n\]$gdb_prompt $" { - pass "$testname (data collection)" + pass "$testname, data collection" } } diff --git a/gdb/testsuite/gdb.base/step-break.exp b/gdb/testsuite/gdb.base/step-break.exp index da804e3..7dc0492 100644 --- a/gdb/testsuite/gdb.base/step-break.exp +++ b/gdb/testsuite/gdb.base/step-break.exp @@ -34,9 +34,9 @@ gdb_test "break $bp_location" \ gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, main \\(\\) at .*$srcfile:$bp_location.*set breakpoint here.*" \ "run until breakpoint set at a line number" -gdb_test "next 2" ".*place2.*" "next 2 (1)" -gdb_test "next 2" ".*place3.*" "next 2 (2)" -gdb_test "next 2" ".*place2.*" "next 2 (3)" -gdb_test "next 2" ".*place3.*" "next 2 (4)" -gdb_test "next 2" ".*place2.*" "next 2 (5)" -gdb_test "next 2" ".*place3.*" "next 2 (6)" +gdb_test "next 2" ".*place2.*" "next 2, 1" +gdb_test "next 2" ".*place3.*" "next 2, 2" +gdb_test "next 2" ".*place2.*" "next 2, 3" +gdb_test "next 2" ".*place3.*" "next 2, 4" +gdb_test "next 2" ".*place2.*" "next 2, 5" +gdb_test "next 2" ".*place3.*" "next 2, 6" diff --git a/gdb/config/nm-nto.h b/gdb/testsuite/gdb.base/step-into-other-file.c index 5a002df..5ec7c33 100644 --- a/gdb/config/nm-nto.h +++ b/gdb/testsuite/gdb.base/step-into-other-file.c @@ -1,10 +1,6 @@ -/* Native support for QNX Neutrino version 6. +/* This testcase is part of GDB, the GNU debugger. - Copyright (C) 2003-2024 Free Software Foundation, Inc. - - This code was donated by QNX Software Systems Ltd. - - This file is part of GDB. + 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 @@ -19,11 +15,17 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef CONFIG_NM_NTO_H -#define CONFIG_NM_NTO_H +int var; -/* Setup the valid realtime signal range. */ -#define REALTIME_LO 41 -#define REALTIME_HI 56 +int +foo (void) +{ + var = 1; +#include "step-into-other-file.h" +} -#endif /* CONFIG_NM_NTO_H */ +int +main () +{ + return foo (); +} diff --git a/gdb/testsuite/gdb.base/step-into-other-file.exp b/gdb/testsuite/gdb.base/step-into-other-file.exp new file mode 100644 index 0000000..f0e8c3f --- /dev/null +++ b/gdb/testsuite/gdb.base/step-into-other-file.exp @@ -0,0 +1,36 @@ +# Copyright (C) 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 when stepping into another file, the file is shown. + +standard_testfile .c .h + +set flags {} +lappend flags debug +lappend_include_file flags $srcdir/$subdir/$srcfile2 + +if { [prepare_for_testing "failed to prepare" $testfile $srcfile \ + $flags] == -1 } { + return -1 +} + +if ![runto_main] { + return -1 +} + +gdb_test step $srcfile:$decimal\r\n.* + +# Regression test for PR32011. +gdb_test next $srcfile2:$decimal\r\n.* diff --git a/gdb/testsuite/gdb.base/step-into-other-file.h b/gdb/testsuite/gdb.base/step-into-other-file.h new file mode 100644 index 0000000..60b4816 --- /dev/null +++ b/gdb/testsuite/gdb.base/step-into-other-file.h @@ -0,0 +1,18 @@ +/* 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/>. */ + + return 1; diff --git a/gdb/testsuite/gdb.base/step-over-syscall.exp b/gdb/testsuite/gdb.base/step-over-syscall.exp index 8cacc09..c40b20f 100644 --- a/gdb/testsuite/gdb.base/step-over-syscall.exp +++ b/gdb/testsuite/gdb.base/step-over-syscall.exp @@ -99,13 +99,13 @@ proc setup { syscall } { gdb_test "break \*$syscall" "Breakpoint \[0-9\]* at .*" gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in )?(__libc_)?$syscall \\(\\).*" \ - "continue to $syscall (1st time)" + "continue to $syscall, 1st time" # Hit the breakpoint on $syscall for the first time. In this time, # we will let PLT resolution done, and the number single steps we will # do later will be reduced. gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in )?(__libc_)?$syscall \\(\\).*" \ - "continue to $syscall (2nd time)" + "continue to $syscall, 2nd time" # Hit the breakpoint on $syscall for the second time. In this time, # the address of syscall insn and next insn of syscall are recorded. @@ -236,7 +236,7 @@ proc step_over_syscall { syscall } { } gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, (.* in )?(__libc_)?$syscall \\(\\).*" \ - "continue to $syscall (3rd time)" + "continue to $syscall, 3rd time" # Hit the breakpoint on $syscall for the third time. In this time, we'll set # breakpoint on the syscall insn we recorded previously, and single step over it. diff --git a/gdb/testsuite/gdb.base/sysroot-debug-lookup.exp b/gdb/testsuite/gdb.base/sysroot-debug-lookup.exp index 5f17315..80cad95 100644 --- a/gdb/testsuite/gdb.base/sysroot-debug-lookup.exp +++ b/gdb/testsuite/gdb.base/sysroot-debug-lookup.exp @@ -78,9 +78,8 @@ proc_with_prefix lookup_via_build_id {} { gdb_assert { $::gdb_file_cmd_debug_info eq "debug" } \ "ensure debug information was found" - if { $sysroot_prefix eq "" } { - set lookup_filename $debug_filename - } else { + if { $sysroot_prefix eq "target:" + && [target_info gdb_protocol] == "extended-remote"} { # Only when using the extended-remote board will we have # started a remote target by this point. In this case GDB # will see the 'target:' prefix as remote, and so the @@ -89,11 +88,9 @@ proc_with_prefix lookup_via_build_id {} { # In all other cases we will still be using the default, # initial target, in which case GDB considers the # 'target:' prefix to indicate the local filesystem. - if {[target_info gdb_protocol] == "extended-remote"} { - set lookup_filename $sysroot_prefix$debug_symlink - } else { - set lookup_filename $debug_symlink - } + set lookup_filename $sysroot_prefix$debug_symlink + } else { + set lookup_filename $debug_filename } set re [string_to_regexp "Reading symbols from $lookup_filename..."] gdb_assert {[regexp $re $::gdb_file_cmd_msg]} \ @@ -174,24 +171,9 @@ proc_with_prefix lookup_via_debuglink {} { # in the sysroot. gdb_file_cmd ${sysroot_prefix}$exec_in_sysroot - # Giving a sysroot a 'target:' prefix doesn't seem to work as - # might be expected for debug-link based lookups. For this - # style of lookup GDB only seems to care if the original file - # itself had a 'target:' prefix. The 'target:' prefix on the - # sysroot just seems to cause GDB to bail on looking up via - # the 'target:' prefixed sysroot. - # - # Bug PR gdb/30866 seems to be the (or a) relevant bug for - # this problem. - if { $sysroot_prefix ne "" } { - setup_kfail "*-*-*" 31804 - } gdb_assert { $::gdb_file_cmd_debug_info eq "debug" } \ "ensure debug information was found" - if { $sysroot_prefix ne "" } { - setup_kfail "*-*-*" 31804 - } set re [string_to_regexp "Reading symbols from ${sysroot_prefix}$debug_symlink..."] gdb_assert {[regexp $re $::gdb_file_cmd_msg]} \ "debug symbols read from correct file" diff --git a/gdb/testsuite/gdb.base/vla-optimized-out.exp b/gdb/testsuite/gdb.base/vla-optimized-out.exp index a0762d5..b57e474 100644 --- a/gdb/testsuite/gdb.base/vla-optimized-out.exp +++ b/gdb/testsuite/gdb.base/vla-optimized-out.exp @@ -57,15 +57,15 @@ proc vla_optimized_out {exe_suffix options} { # that case to reply with 'no such vector element'. gdb_test "p a\[0\]" \ "(= <optimized out>|no such vector element)" \ - "print out of range element of vla (0)" + "print out of range element of vla, 0" gdb_test "p a\[6\]" \ "no such vector element" \ - "print out of range element of vla (6)" + "print out of range element of vla, 6" gdb_test "p a\[0xffffffff\]" \ "no such vector element" \ - "print out of range element of vla (0xffffffff)" + "print out of range element of vla, 0xffffffff" } set o1_sizeof_result "6" diff --git a/gdb/testsuite/gdb.base/vla-ptr.exp b/gdb/testsuite/gdb.base/vla-ptr.exp index a784c18..df1b8f0 100644 --- a/gdb/testsuite/gdb.base/vla-ptr.exp +++ b/gdb/testsuite/gdb.base/vla-ptr.exp @@ -29,13 +29,13 @@ set sizeof_int [get_sizeof "int" 4] # Check that VLA passed to function (pointer) points to the first element. gdb_breakpoint [gdb_get_line_number "foo_bp"] gdb_continue_to_breakpoint "foo_bp" -gdb_test "print vla_ptr" "\\\(int \\\*\\\) $hex" "print vla_ptr (foo)" -gdb_test "print *vla_ptr" " = 2" "print *vla_ptr (foo)" +gdb_test "print vla_ptr" "\\\(int \\\*\\\) $hex" "print vla_ptr, foo" +gdb_test "print *vla_ptr" " = 2" "print *vla_ptr, foo" gdb_breakpoint [gdb_get_line_number "bar_bp"] gdb_continue_to_breakpoint "bar_bp" -gdb_test "print vla_ptr" "\\\(int \\\*\\\) $hex" "print vla_ptr (bar)" -gdb_test "print *vla_ptr" " = 2" "print *vla_ptr (bar)" +gdb_test "print vla_ptr" "\\\(int \\\*\\\) $hex" "print vla_ptr, bar" +gdb_test "print *vla_ptr" " = 2" "print *vla_ptr, bar" gdb_breakpoint [gdb_get_line_number "vla_func_bp"] gdb_continue_to_breakpoint "vla_func_bp" diff --git a/gdb/testsuite/gdb.base/vla-sideeffect.exp b/gdb/testsuite/gdb.base/vla-sideeffect.exp index e17037d..8215ec2 100644 --- a/gdb/testsuite/gdb.base/vla-sideeffect.exp +++ b/gdb/testsuite/gdb.base/vla-sideeffect.exp @@ -52,30 +52,30 @@ gdb_test "print vla1\[0\]" " = 10" \ gdb_test "print sizeof (vla2\[i++\])" " = ${sizeof_vla}" gdb_test "print i" " = 1" \ - "print i - sizeof with side effects (1)" + "print i - sizeof with side effects, 1" gdb_test "print sizeof (vla2\[i++ + sizeof(j++)\])" " = ${sizeof_vla}" gdb_test "print i" " = 2" \ - "print i - sizeof with side effects (2)" + "print i - sizeof with side effects, 2" gdb_test "print j" " = 0" \ "print j - sizeof with no side effects" gdb_test "ptype vla2\[i++\]" "type = int \\\[10\\\]" gdb_test "print i" " = 2" \ - "print i - ptype with side effects (1)" + "print i - ptype with side effects, 1" gdb_test "ptype vla2\[i++ + sizeof(j++)\]" "type = int \\\[10\\\]" gdb_test "print i" " = 2" \ - "print i - ptype with side effects (2)" + "print i - ptype with side effects, 2" gdb_test "print j" " = 0" \ "print j - ptype with no side effects" gdb_test "whatis vla2\[i++\]" "type = int \\\[10\\\]" gdb_test "print i" " = 2" \ - "print i - whatis with side effects (1)" + "print i - whatis with side effects, 1" gdb_test "whatis vla2\[i++ + sizeof(j++)\]" "type = int \\\[10\\\]" gdb_test "print i" " = 2" \ - "print i - whatis with side effects (2)" + "print i - whatis with side effects, 2" gdb_test "print j" " = 0" \ "print j - whatis with no side effects" diff --git a/gdb/testsuite/gdb.base/watch-vfork.exp b/gdb/testsuite/gdb.base/watch-vfork.exp index 617a975..f7e268f 100644 --- a/gdb/testsuite/gdb.base/watch-vfork.exp +++ b/gdb/testsuite/gdb.base/watch-vfork.exp @@ -37,11 +37,11 @@ proc test_watchpoint_across_vfork { hw teststr } { gdb_test "watch global" \ "atchpoint .*: global" \ - "Watchpoint on global variable ($teststr)" + "Watchpoint on global variable, $teststr" gdb_test "continue" \ "atchpoint .*: global.*" \ - "Watchpoint triggers after vfork ($teststr)" + "Watchpoint triggers after vfork, $teststr" } if { [allow_hw_watchpoint_tests] } { diff --git a/gdb/testsuite/gdb.base/wchar.exp b/gdb/testsuite/gdb.base/wchar.exp index a4127fc..0fc97cf 100644 --- a/gdb/testsuite/gdb.base/wchar.exp +++ b/gdb/testsuite/gdb.base/wchar.exp @@ -60,15 +60,15 @@ gdb_test "print repeat_p" \ gdb_test_no_output "set print null on" gdb_test "print repeat" "= L\"A\", '$cent' <repeats 21 times>, \"B\"" \ - "print repeat (print null on)" + "print repeat, print null on" gdb_test_no_output "set print elements 3" gdb_test "print repeat" "= L\"A$cent$cent\"\.\.\." \ - "print repeat (print elements 3)" + "print repeat, print elements 3" gdb_test "print repeat_p" "= $hex L\"A$cent$cent\"\.\.\." \ - "print repeat_p (print elements 3)" + "print repeat_p, print elements 3" # From PR cli/14977, but here because it requires wchar_t. gdb_test "printf \"%ls\\n\", 0" "\\(null\\)" diff --git a/gdb/testsuite/gdb.base/whatis-ptype-typedefs.exp b/gdb/testsuite/gdb.base/whatis-ptype-typedefs.exp index eb575b3..ebe009a 100644 --- a/gdb/testsuite/gdb.base/whatis-ptype-typedefs.exp +++ b/gdb/testsuite/gdb.base/whatis-ptype-typedefs.exp @@ -271,8 +271,11 @@ proc run_tests {lang} { if {([string match "v_*" $to] || (![string match "v_*" $from] && ![string match "*method" $from]) || [string match "*method" $to])} { - gdb_test "whatis ($to) $from" "syntax error.*" "whatis ($to) $from (syntax)" - gdb_test "ptype ($to) $from" "syntax error.*" "ptype ($to) $from (syntax)" + set cmd "whatis ($to) $from" + gdb_test $cmd "syntax error.*" "$cmd, syntax" + + set cmd "ptype ($to) $from" + gdb_test $cmd "syntax error.*" "$cmd, syntax" } elseif {([string match "*float*" $from] && [string match "*array*" $to]) || (!$float_ptr_same_size && ([string match "float*" $to] && [string match "*array*" $from] @@ -289,8 +292,11 @@ proc run_tests {lang} { || ([string match "*ftype2" $to] && [string match "*method" $from]) || ([string match "*method_ptr*" $to] && [string match "*method" $from]) || ([string match "*method_ptr*" $to] && [string match "*array*" $from])} { - gdb_test "whatis ($to) $from" "Invalid cast." "whatis ($to) $from (invalid)" - gdb_test "ptype ($to) $from" "Invalid cast." "ptype ($to) $from (invalid)" + set cmd "whatis ($to) $from" + gdb_test $cmd "Invalid cast." "$cmd, invalid" + + set cmd "ptype ($to) $from" + gdb_test $cmd "Invalid cast." "$cmd, invalid" } else { gdb_test "whatis ($to) $from" "type = [string_to_regexp $to]" gdb_test "ptype ($to) $from" "type = $ptype" diff --git a/gdb/testsuite/gdb.btrace/i386-ptwrite.S b/gdb/testsuite/gdb.btrace/i386-ptwrite.S new file mode 100644 index 0000000..5c649cf --- /dev/null +++ b/gdb/testsuite/gdb.btrace/i386-ptwrite.S @@ -0,0 +1,550 @@ +/* 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/>. + + + This file has been generated using gcc version 10.3.1 20210422 + (Red Hat 10.3.1-1): + gcc -S -dA -g -m32 -mptwrite ptwrite.c -o i386-ptwrite.S. */ + + + .file "ptwrite.c" + .text +.Ltext0: + .globl ptwrite1 + .type ptwrite1, @function +ptwrite1: +.LFB4021: + .file 1 "ptwrite.c" + # ptwrite.c:22:1 + .loc 1 22 1 + .cfi_startproc +# BLOCK 2 seq:0 +# PRED: ENTRY (FALLTHRU) + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + # ptwrite.c:23:3 + .loc 1 23 3 + movl 8(%ebp), %eax + movl %eax, -4(%ebp) +.LBB6: +.LBB7: + .file 2 "/usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h" + # /usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h:307:3 + .loc 2 307 3 + movl -4(%ebp), %eax + ptwrite %eax + # /usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h:308:1 + .loc 2 308 1 + nop +.LBE7: +.LBE6: + # ptwrite.c:24:1 + .loc 1 24 1 + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 +# SUCC: EXIT [always] + ret + .cfi_endproc +.LFE4021: + .size ptwrite1, .-ptwrite1 + .globl ptwrite2 + .type ptwrite2, @function +ptwrite2: +.LFB4022: + # ptwrite.c:28:1 + .loc 1 28 1 + .cfi_startproc +# BLOCK 2 seq:0 +# PRED: ENTRY (FALLTHRU) + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + # ptwrite.c:29:3 + .loc 1 29 3 + movl 8(%ebp), %eax + movl %eax, -4(%ebp) +.LBB8: +.LBB9: + # /usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h:307:3 + .loc 2 307 3 + movl -4(%ebp), %eax + ptwrite %eax + # /usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h:308:1 + .loc 2 308 1 + nop +.LBE9: +.LBE8: + # ptwrite.c:30:1 + .loc 1 30 1 + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 +# SUCC: EXIT [always] + ret + .cfi_endproc +.LFE4022: + .size ptwrite2, .-ptwrite2 + .globl main + .type main, @function +main: +.LFB4023: + # ptwrite.c:34:1 + .loc 1 34 1 + .cfi_startproc +# BLOCK 2 seq:0 +# PRED: ENTRY (FALLTHRU) + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + # ptwrite.c:35:3 + .loc 1 35 3 + pushl $66 + call ptwrite1 + addl $4, %esp + # ptwrite.c:36:3 + .loc 1 36 3 + pushl $67 + call ptwrite2 + addl $4, %esp + # ptwrite.c:38:10 + .loc 1 38 10 + movl $0, %eax + # ptwrite.c:39:1 + .loc 1 39 1 + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 +# SUCC: EXIT [always] + ret + .cfi_endproc +.LFE4023: + .size main, .-main +.Letext0: + .section .debug_info,"",@progbits +.Ldebug_info0: + .long 0x129 # Length of Compilation Unit Info + .value 0x4 # DWARF version number + .long .Ldebug_abbrev0 # Offset Into Abbrev. Section + .byte 0x4 # Pointer Size (in bytes) + .uleb128 0x1 # (DIE (0xb) DW_TAG_compile_unit) + .long .LASF15 # DW_AT_producer: "GNU C17 10.3.1 20210422 (Red Hat 10.3.1-1) -m32 -mptwrite -mtune=generic -march=i686 -g" + .byte 0xc # DW_AT_language + .long .LASF16 # DW_AT_name: "ptwrite.c" + .long .LASF17 # DW_AT_comp_dir: "gdb/gdb/testsuite/gdb.btrace" + .long .Ltext0 # DW_AT_low_pc + .long .Letext0-.Ltext0 # DW_AT_high_pc + .long .Ldebug_line0 # DW_AT_stmt_list + .uleb128 0x2 # (DIE (0x25) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .ascii "int\0" # DW_AT_name + .uleb128 0x3 # (DIE (0x2c) DW_TAG_base_type) + .byte 0x2 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .long .LASF0 # DW_AT_name: "short int" + .uleb128 0x3 # (DIE (0x33) DW_TAG_base_type) + .byte 0x1 # DW_AT_byte_size + .byte 0x6 # DW_AT_encoding + .long .LASF1 # DW_AT_name: "char" + .uleb128 0x3 # (DIE (0x3a) DW_TAG_base_type) + .byte 0x8 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .long .LASF2 # DW_AT_name: "long long int" + .uleb128 0x3 # (DIE (0x41) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x4 # DW_AT_encoding + .long .LASF3 # DW_AT_name: "float" + .uleb128 0x3 # (DIE (0x48) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x7 # DW_AT_encoding + .long .LASF4 # DW_AT_name: "unsigned int" + .uleb128 0x3 # (DIE (0x4f) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .long .LASF5 # DW_AT_name: "long int" + .uleb128 0x3 # (DIE (0x56) DW_TAG_base_type) + .byte 0x1 # DW_AT_byte_size + .byte 0x8 # DW_AT_encoding + .long .LASF6 # DW_AT_name: "unsigned char" + .uleb128 0x3 # (DIE (0x5d) DW_TAG_base_type) + .byte 0x2 # DW_AT_byte_size + .byte 0x7 # DW_AT_encoding + .long .LASF7 # DW_AT_name: "short unsigned int" + .uleb128 0x3 # (DIE (0x64) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x7 # DW_AT_encoding + .long .LASF8 # DW_AT_name: "long unsigned int" + .uleb128 0x3 # (DIE (0x6b) DW_TAG_base_type) + .byte 0x1 # DW_AT_byte_size + .byte 0x6 # DW_AT_encoding + .long .LASF9 # DW_AT_name: "signed char" + .uleb128 0x3 # (DIE (0x72) DW_TAG_base_type) + .byte 0x8 # DW_AT_byte_size + .byte 0x7 # DW_AT_encoding + .long .LASF10 # DW_AT_name: "long long unsigned int" + .uleb128 0x3 # (DIE (0x79) DW_TAG_base_type) + .byte 0x8 # DW_AT_byte_size + .byte 0x4 # DW_AT_encoding + .long .LASF11 # DW_AT_name: "double" + .uleb128 0x4 # (DIE (0x80) DW_TAG_subprogram) + # DW_AT_external + .long .LASF18 # DW_AT_name: "main" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x21 # DW_AT_decl_line + .byte 0x1 # DW_AT_decl_column + # DW_AT_prototyped + .long 0x25 # DW_AT_type + .long .LFB4023 # DW_AT_low_pc + .long .LFE4023-.LFB4023 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + # DW_AT_GNU_all_tail_call_sites + .uleb128 0x5 # (DIE (0x96) DW_TAG_subprogram) + # DW_AT_external + .long .LASF12 # DW_AT_name: "ptwrite2" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x1b # DW_AT_decl_line + .byte 0x1 # DW_AT_decl_column + # DW_AT_prototyped + .long .LFB4022 # DW_AT_low_pc + .long .LFE4022-.LFB4022 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + # DW_AT_GNU_all_call_sites + .long 0xd5 # DW_AT_sibling + .uleb128 0x6 # (DIE (0xac) DW_TAG_formal_parameter) + .long .LASF14 # DW_AT_name: "value" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x1b # DW_AT_decl_line + .byte 0xf # DW_AT_decl_column + .long 0x25 # DW_AT_type + .uleb128 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 0 + .uleb128 0x7 # (DIE (0xbb) DW_TAG_inlined_subroutine) + .long 0x114 # DW_AT_abstract_origin + .long .LBB8 # DW_AT_low_pc + .long .LBE8-.LBB8 # DW_AT_high_pc + .byte 0x1 # DW_AT_call_file (ptwrite.c) + .byte 0x1d # DW_AT_call_line + .byte 0x3 # DW_AT_call_column + .uleb128 0x8 # (DIE (0xcb) DW_TAG_formal_parameter) + .long 0x11e # DW_AT_abstract_origin + .uleb128 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 -12 + .byte 0 # end of children of DIE 0xbb + .byte 0 # end of children of DIE 0x96 + .uleb128 0x5 # (DIE (0xd5) DW_TAG_subprogram) + # DW_AT_external + .long .LASF13 # DW_AT_name: "ptwrite1" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x15 # DW_AT_decl_line + .byte 0x1 # DW_AT_decl_column + # DW_AT_prototyped + .long .LFB4021 # DW_AT_low_pc + .long .LFE4021-.LFB4021 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + # DW_AT_GNU_all_call_sites + .long 0x114 # DW_AT_sibling + .uleb128 0x6 # (DIE (0xeb) DW_TAG_formal_parameter) + .long .LASF14 # DW_AT_name: "value" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x15 # DW_AT_decl_line + .byte 0xf # DW_AT_decl_column + .long 0x25 # DW_AT_type + .uleb128 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 0 + .uleb128 0x7 # (DIE (0xfa) DW_TAG_inlined_subroutine) + .long 0x114 # DW_AT_abstract_origin + .long .LBB6 # DW_AT_low_pc + .long .LBE6-.LBB6 # DW_AT_high_pc + .byte 0x1 # DW_AT_call_file (ptwrite.c) + .byte 0x17 # DW_AT_call_line + .byte 0x3 # DW_AT_call_column + .uleb128 0x8 # (DIE (0x10a) DW_TAG_formal_parameter) + .long 0x11e # DW_AT_abstract_origin + .uleb128 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 -12 + .byte 0 # end of children of DIE 0xfa + .byte 0 # end of children of DIE 0xd5 + .uleb128 0x9 # (DIE (0x114) DW_TAG_subprogram) + # DW_AT_external + .long .LASF19 # DW_AT_name: "_ptwrite32" + .byte 0x2 # DW_AT_decl_file (/usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h) + .value 0x131 # DW_AT_decl_line + .byte 0x1 # DW_AT_decl_column + # DW_AT_prototyped + .byte 0x3 # DW_AT_inline + # DW_AT_artificial + .uleb128 0xa # (DIE (0x11e) DW_TAG_formal_parameter) + .ascii "__B\0" # DW_AT_name + .byte 0x2 # DW_AT_decl_file (/usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h) + .value 0x131 # DW_AT_decl_line + .byte 0x16 # DW_AT_decl_column + .long 0x48 # DW_AT_type + .byte 0 # end of children of DIE 0x114 + .byte 0 # end of children of DIE 0xb + .section .debug_abbrev,"",@progbits +.Ldebug_abbrev0: + .uleb128 0x1 # (abbrev code) + .uleb128 0x11 # (TAG: DW_TAG_compile_unit) + .byte 0x1 # DW_children_yes + .uleb128 0x25 # (DW_AT_producer) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x13 # (DW_AT_language) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x1b # (DW_AT_comp_dir) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x6 # (DW_FORM_data4) + .uleb128 0x10 # (DW_AT_stmt_list) + .uleb128 0x17 # (DW_FORM_sec_offset) + .byte 0 + .byte 0 + .uleb128 0x2 # (abbrev code) + .uleb128 0x24 # (TAG: DW_TAG_base_type) + .byte 0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3e # (DW_AT_encoding) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .byte 0 + .byte 0 + .uleb128 0x3 # (abbrev code) + .uleb128 0x24 # (TAG: DW_TAG_base_type) + .byte 0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3e # (DW_AT_encoding) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .byte 0 + .byte 0 + .uleb128 0x4 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0 # DW_children_no + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x6 # (DW_FORM_data4) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0x18 # (DW_FORM_exprloc) + .uleb128 0x2116 # (DW_AT_GNU_all_tail_call_sites) + .uleb128 0x19 # (DW_FORM_flag_present) + .byte 0 + .byte 0 + .uleb128 0x5 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x6 # (DW_FORM_data4) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0x18 # (DW_FORM_exprloc) + .uleb128 0x2117 # (DW_AT_GNU_all_call_sites) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x1 # (DW_AT_sibling) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0x6 # (abbrev code) + .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x18 # (DW_FORM_exprloc) + .byte 0 + .byte 0 + .uleb128 0x7 # (abbrev code) + .uleb128 0x1d # (TAG: DW_TAG_inlined_subroutine) + .byte 0x1 # DW_children_yes + .uleb128 0x31 # (DW_AT_abstract_origin) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x6 # (DW_FORM_data4) + .uleb128 0x58 # (DW_AT_call_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x59 # (DW_AT_call_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x57 # (DW_AT_call_column) + .uleb128 0xb # (DW_FORM_data1) + .byte 0 + .byte 0 + .uleb128 0x8 # (abbrev code) + .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) + .byte 0 # DW_children_no + .uleb128 0x31 # (DW_AT_abstract_origin) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x18 # (DW_FORM_exprloc) + .byte 0 + .byte 0 + .uleb128 0x9 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0x5 # (DW_FORM_data2) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x20 # (DW_AT_inline) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x34 # (DW_AT_artificial) + .uleb128 0x19 # (DW_FORM_flag_present) + .byte 0 + .byte 0 + .uleb128 0xa # (abbrev code) + .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0x5 # (DW_FORM_data2) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .byte 0 + .section .debug_aranges,"",@progbits + .long 0x1c # Length of Address Ranges Info + .value 0x2 # DWARF aranges version + .long .Ldebug_info0 # Offset of Compilation Unit Info + .byte 0x4 # Size of Address + .byte 0 # Size of Segment Descriptor + .value 0 # Pad to 8 byte boundary + .value 0 + .long .Ltext0 # Address + .long .Letext0-.Ltext0 # Length + .long 0 + .long 0 + .section .debug_line,"",@progbits +.Ldebug_line0: + .section .debug_str,"MS",@progbits,1 +.LASF2: + .string "long long int" +.LASF14: + .string "value" +.LASF19: + .string "_ptwrite32" +.LASF4: + .string "unsigned int" +.LASF17: + .string "gdb/gdb/testsuite/gdb.btrace" +.LASF18: + .string "main" +.LASF16: + .string "ptwrite.c" +.LASF8: + .string "long unsigned int" +.LASF10: + .string "long long unsigned int" +.LASF13: + .string "ptwrite1" +.LASF12: + .string "ptwrite2" +.LASF6: + .string "unsigned char" +.LASF1: + .string "char" +.LASF5: + .string "long int" +.LASF15: + .string "GNU C17 10.3.1 20210422 (Red Hat 10.3.1-1) -m32 -mptwrite -mtune=generic -march=i686 -g" +.LASF11: + .string "double" +.LASF7: + .string "short unsigned int" +.LASF9: + .string "signed char" +.LASF3: + .string "float" +.LASF0: + .string "short int" + .ident "GCC: (GNU) 10.3.1 20210422 (Red Hat 10.3.1-1)" + .section .note.GNU-stack,"",@progbits diff --git a/gdb/testsuite/gdb.btrace/ptwrite.c b/gdb/testsuite/gdb.btrace/ptwrite.c new file mode 100644 index 0000000..e10b885 --- /dev/null +++ b/gdb/testsuite/gdb.btrace/ptwrite.c @@ -0,0 +1,39 @@ +/* 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/>. */ + +#include <immintrin.h> + +void +ptwrite1 (int value) +{ + _ptwrite32 (value); +} + +void +ptwrite2 (int value) +{ + _ptwrite32 (value); +} + +int +main (void) +{ + ptwrite1 (0x42); + ptwrite2 (0x43); + + return 0; +} diff --git a/gdb/testsuite/gdb.btrace/ptwrite.exp b/gdb/testsuite/gdb.btrace/ptwrite.exp new file mode 100644 index 0000000..0970d31 --- /dev/null +++ b/gdb/testsuite/gdb.btrace/ptwrite.exp @@ -0,0 +1,201 @@ +# 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/>. + +load_lib gdb-python.exp + +require allow_btrace_ptw_tests allow_python_tests + +set opts {} + +if [info exists COMPILE] { + # make check RUNTESTFLAGS="gdb.btrace/ptwrite.exp COMPILE=1" + standard_testfile ptwrite.c + lappend opts debug additional_flags=-mptwrite +} elseif {[istarget "i?86-*-*"] || [istarget "x86_64-*-*"]} { + if {[is_amd64_regs_target]} { + standard_testfile x86_64-ptwrite.S + } else { + standard_testfile i386-ptwrite.S + } +} else { + unsupported "target architecture not supported" + return -1 +} + +if [prepare_for_testing "failed to prepare" $testfile $srcfile $opts] { + return -1 +} + +if { ![runto_main] } { + untested "failed to run to main" + return -1 +} + +### 1. Default testrun + +# Setup recording +gdb_test_no_output "set record instruction-history-size unlimited" +gdb_test_no_output "record btrace pt" +gdb_test "next 2" ".*" + +with_test_prefix "Default" { + # Test record instruction-history + gdb_test "record instruction-history 1" [multi_line \ + ".*\[0-9\]+\t $hex <ptwrite1\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t \\\[0x42\\\]" \ + ".*\[0-9\]+\t $hex <ptwrite2\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t \\\[0x43\\\].*" \ + ] + + gdb_test "record instruction-history /a 1" [multi_line \ + ".*\[0-9\]+\t $hex <ptwrite1\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \ + ".*\[0-9\]+\t $hex <ptwrite2\\+\[0-9\]+>:\tptwrite %\[a-z\]+.*" \ + ] + + # Test function call history + gdb_test "record function-call-history 1,4" [multi_line \ + "1\tmain" \ + "2\tptwrite1" \ + "\t \\\[0x42\\\]" \ + "3\tmain" \ + "4\tptwrite2" \ + "\t \\\[0x43\\\]" \ + ] + + gdb_test "record function-call-history /a 1,4" [multi_line \ + "1\tmain" \ + "2\tptwrite1" \ + "3\tmain" \ + "4\tptwrite2" \ + ] +} + +# Test payload printing during stepping +with_test_prefix "Stepping" { + gdb_test "record goto 10" "Can't go to an auxiliary instruction\." + gdb_test "record goto 9" ".*ptwrite.* at .*" + gdb_test "stepi" ".*\\\[0x42\\\].*" + gdb_test "reverse-stepi" ".*\\\[0x42\\\].*" + gdb_test "continue" [multi_line \ + ".*\\\[0x42\\\]" \ + "\\\[0x43\\\].*" \ + ] + gdb_test "reverse-continue" [multi_line \ + ".*\\\[0x43\\\]" \ + "\\\[0x42\\\].*" \ + ] +} + +# Test auxiliary type in python +gdb_test_multiline "auxiliary type in python" \ + "python" "" \ + "h = gdb.current_recording().instruction_history" "" \ + "for insn in h:" "" \ + " if hasattr(insn, 'decoded'):" "" \ + " print(insn.decoded.decode())" "" \ + " elif hasattr(insn, 'data'):" "" \ + " print(insn.data)" "" \ + "end" \ + [multi_line \ + ".*mov -0x4\\\(%(e|r)bp\\\),%(e|r)ax" \ + "ptwrite %eax" \ + "0x42" \ + "nop.*" \ + "mov -0x4\\\(%(e|r)bp\\\),%(e|r)ax" \ + "ptwrite %eax" \ + "0x43" \ + "nop.*" + ] + + +### 2. Test filter registration +### 2.1 Custom filter +with_test_prefix "Custom" { + gdb_test_multiline "register filter in python" \ + "python" "" \ + "def my_filter(payload, ip):" "" \ + " if payload == 66:" "" \ + " return \"payload: {0}, ip: {1:#x}\".format(payload, ip)" "" \ + " else:" "" \ + " return None" "" \ + "def factory(thread): return my_filter" "" \ + "import gdb.ptwrite" "" \ + "gdb.ptwrite.register_filter_factory(factory)" "" \ + "end" "" + + gdb_test "record instruction-history 1" [multi_line \ + ".*\[0-9\]+\t $hex <ptwrite1\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t \\\[payload: 66, ip: $hex\\\]" \ + ".*\[0-9\]+\t $hex <ptwrite2\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t $hex <ptwrite2\\+\[0-9\]+>:.*" \ + ] +} + +### 2.2 None as filter. This resets the default behaviour. +with_test_prefix "None" { + gdb_test_multiline "register filter in python" \ + "python" "" \ + "import gdb.ptwrite" "" \ + "gdb.ptwrite.register_filter_factory(None)" "" \ + "end" "" + + gdb_test "record instruction-history 1" [multi_line \ + ".*\[0-9\]+\t $hex <ptwrite1\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t \\\[0x42\\\]" \ + ".*\[0-9\]+\t $hex <ptwrite2\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t \\\[0x43\\\].*" \ + ] +} + +### 2.3 Lambdas as filter +with_test_prefix "Lambdas" { + gdb_test_multiline "register filter in python" \ + "python" "" \ + "import gdb.ptwrite" "" \ + "lambda_filter = lambda payload, ip: \"{}\".format(payload + 2)" "" \ + "gdb.ptwrite.register_filter_factory(lambda thread : lambda_filter)" "" \ + "end" "" + + gdb_test "record instruction-history 1" [multi_line \ + ".*\[0-9\]+\t $hex <ptwrite1\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t \\\[68\\\]" \ + ".*\[0-9\]+\t $hex <ptwrite2\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t \\\[69\\\].*" \ + ] "Lambdas: record instruction-history 1" +} + +### 2.4 Functors as filter +with_test_prefix "Functors" { + gdb_test_multiline "register filter in python" \ + "python" "" \ + "import gdb.ptwrite" "" \ + "class foobar(object):" "" \ + " def __init__(self):" "" \ + " self.variable = 0" "" \ + " def __call__(self, payload, ip):" "" \ + " self.variable += 1" "" \ + " return \"{}, {}\".format(self.variable, payload)" "" \ + "gdb.ptwrite.register_filter_factory(lambda thread : foobar())" "" \ + "end" "" + + gdb_test "record instruction-history 1" [multi_line \ + ".*\[0-9\]+\t $hex <ptwrite1\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t \\\[1, 66\\\]" \ + ".*\[0-9\]+\t $hex <ptwrite2\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \ + "\[0-9\]+\t \\\[2, 67\\\].*" \ + ] "Functors: record instruction-history 1" +} diff --git a/gdb/testsuite/gdb.btrace/x86_64-ptwrite.S b/gdb/testsuite/gdb.btrace/x86_64-ptwrite.S new file mode 100644 index 0000000..be4d204 --- /dev/null +++ b/gdb/testsuite/gdb.btrace/x86_64-ptwrite.S @@ -0,0 +1,544 @@ +/* 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/>. + + + This file has been generated using gcc version 10.3.1 20210422 + (Red Hat 10.3.1-1): + gcc -S -dA -g -mptwrite ptwrite.c -o x86_64-ptwrite.S. */ + + .file "ptwrite.c" + .text +.Ltext0: + .globl ptwrite1 + .type ptwrite1, @function +ptwrite1: +.LFB4096: + .file 1 "ptwrite.c" + # ptwrite.c:22:1 + .loc 1 22 1 + .cfi_startproc +# BLOCK 2 seq:0 +# PRED: ENTRY (FALLTHRU) + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -20(%rbp) + # ptwrite.c:23:3 + .loc 1 23 3 + movl -20(%rbp), %eax + movl %eax, -4(%rbp) +.LBB6: +.LBB7: + .file 2 "/usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h" + # /usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h:307:3 + .loc 2 307 3 + movl -4(%rbp), %eax + ptwrite %eax + # /usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h:308:1 + .loc 2 308 1 + nop +.LBE7: +.LBE6: + # ptwrite.c:24:1 + .loc 1 24 1 + nop + popq %rbp + .cfi_def_cfa 7, 8 +# SUCC: EXIT [always] + ret + .cfi_endproc +.LFE4096: + .size ptwrite1, .-ptwrite1 + .globl ptwrite2 + .type ptwrite2, @function +ptwrite2: +.LFB4097: + # ptwrite.c:28:1 + .loc 1 28 1 + .cfi_startproc +# BLOCK 2 seq:0 +# PRED: ENTRY (FALLTHRU) + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -20(%rbp) + # ptwrite.c:29:3 + .loc 1 29 3 + movl -20(%rbp), %eax + movl %eax, -4(%rbp) +.LBB8: +.LBB9: + # /usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h:307:3 + .loc 2 307 3 + movl -4(%rbp), %eax + ptwrite %eax + # /usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h:308:1 + .loc 2 308 1 + nop +.LBE9: +.LBE8: + # ptwrite.c:30:1 + .loc 1 30 1 + nop + popq %rbp + .cfi_def_cfa 7, 8 +# SUCC: EXIT [always] + ret + .cfi_endproc +.LFE4097: + .size ptwrite2, .-ptwrite2 + .globl main + .type main, @function +main: +.LFB4098: + # ptwrite.c:34:1 + .loc 1 34 1 + .cfi_startproc +# BLOCK 2 seq:0 +# PRED: ENTRY (FALLTHRU) + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + # ptwrite.c:35:3 + .loc 1 35 3 + movl $66, %edi + call ptwrite1 + # ptwrite.c:36:3 + .loc 1 36 3 + movl $67, %edi + call ptwrite2 + # ptwrite.c:38:10 + .loc 1 38 10 + movl $0, %eax + # ptwrite.c:39:1 + .loc 1 39 1 + popq %rbp + .cfi_def_cfa 7, 8 +# SUCC: EXIT [always] + ret + .cfi_endproc +.LFE4098: + .size main, .-main +.Letext0: + .section .debug_info,"",@progbits +.Ldebug_info0: + .long 0x159 # Length of Compilation Unit Info + .value 0x4 # DWARF version number + .long .Ldebug_abbrev0 # Offset Into Abbrev. Section + .byte 0x8 # Pointer Size (in bytes) + .uleb128 0x1 # (DIE (0xb) DW_TAG_compile_unit) + .long .LASF15 # DW_AT_producer: "GNU C17 10.3.1 20210422 (Red Hat 10.3.1-1) -mptwrite -mtune=generic -march=x86-64 -g" + .byte 0xc # DW_AT_language + .long .LASF16 # DW_AT_name: "ptwrite.c" + .long .LASF17 # DW_AT_comp_dir: "gdb/gdb/testsuite/gdb.btrace" + .quad .Ltext0 # DW_AT_low_pc + .quad .Letext0-.Ltext0 # DW_AT_high_pc + .long .Ldebug_line0 # DW_AT_stmt_list + .uleb128 0x2 # (DIE (0x2d) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .ascii "int\0" # DW_AT_name + .uleb128 0x3 # (DIE (0x34) DW_TAG_base_type) + .byte 0x2 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .long .LASF0 # DW_AT_name: "short int" + .uleb128 0x3 # (DIE (0x3b) DW_TAG_base_type) + .byte 0x1 # DW_AT_byte_size + .byte 0x6 # DW_AT_encoding + .long .LASF1 # DW_AT_name: "char" + .uleb128 0x3 # (DIE (0x42) DW_TAG_base_type) + .byte 0x8 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .long .LASF2 # DW_AT_name: "long long int" + .uleb128 0x3 # (DIE (0x49) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x4 # DW_AT_encoding + .long .LASF3 # DW_AT_name: "float" + .uleb128 0x3 # (DIE (0x50) DW_TAG_base_type) + .byte 0x8 # DW_AT_byte_size + .byte 0x7 # DW_AT_encoding + .long .LASF4 # DW_AT_name: "long unsigned int" + .uleb128 0x3 # (DIE (0x57) DW_TAG_base_type) + .byte 0x8 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .long .LASF5 # DW_AT_name: "long int" + .uleb128 0x3 # (DIE (0x5e) DW_TAG_base_type) + .byte 0x1 # DW_AT_byte_size + .byte 0x8 # DW_AT_encoding + .long .LASF6 # DW_AT_name: "unsigned char" + .uleb128 0x3 # (DIE (0x65) DW_TAG_base_type) + .byte 0x2 # DW_AT_byte_size + .byte 0x7 # DW_AT_encoding + .long .LASF7 # DW_AT_name: "short unsigned int" + .uleb128 0x3 # (DIE (0x6c) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x7 # DW_AT_encoding + .long .LASF8 # DW_AT_name: "unsigned int" + .uleb128 0x3 # (DIE (0x73) DW_TAG_base_type) + .byte 0x1 # DW_AT_byte_size + .byte 0x6 # DW_AT_encoding + .long .LASF9 # DW_AT_name: "signed char" + .uleb128 0x3 # (DIE (0x7a) DW_TAG_base_type) + .byte 0x8 # DW_AT_byte_size + .byte 0x7 # DW_AT_encoding + .long .LASF10 # DW_AT_name: "long long unsigned int" + .uleb128 0x3 # (DIE (0x81) DW_TAG_base_type) + .byte 0x8 # DW_AT_byte_size + .byte 0x4 # DW_AT_encoding + .long .LASF11 # DW_AT_name: "double" + .uleb128 0x4 # (DIE (0x88) DW_TAG_subprogram) + # DW_AT_external + .long .LASF18 # DW_AT_name: "main" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x21 # DW_AT_decl_line + .byte 0x1 # DW_AT_decl_column + # DW_AT_prototyped + .long 0x2d # DW_AT_type + .quad .LFB4098 # DW_AT_low_pc + .quad .LFE4098-.LFB4098 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + # DW_AT_GNU_all_tail_call_sites + .uleb128 0x5 # (DIE (0xa6) DW_TAG_subprogram) + # DW_AT_external + .long .LASF12 # DW_AT_name: "ptwrite2" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x1b # DW_AT_decl_line + .byte 0x1 # DW_AT_decl_column + # DW_AT_prototyped + .quad .LFB4097 # DW_AT_low_pc + .quad .LFE4097-.LFB4097 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + # DW_AT_GNU_all_call_sites + .long 0xf5 # DW_AT_sibling + .uleb128 0x6 # (DIE (0xc4) DW_TAG_formal_parameter) + .long .LASF14 # DW_AT_name: "value" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x1b # DW_AT_decl_line + .byte 0xf # DW_AT_decl_column + .long 0x2d # DW_AT_type + .uleb128 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 -36 + .uleb128 0x7 # (DIE (0xd3) DW_TAG_inlined_subroutine) + .long 0x144 # DW_AT_abstract_origin + .quad .LBB8 # DW_AT_low_pc + .quad .LBE8-.LBB8 # DW_AT_high_pc + .byte 0x1 # DW_AT_call_file (ptwrite.c) + .byte 0x1d # DW_AT_call_line + .byte 0x3 # DW_AT_call_column + .uleb128 0x8 # (DIE (0xeb) DW_TAG_formal_parameter) + .long 0x14e # DW_AT_abstract_origin + .uleb128 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 -20 + .byte 0 # end of children of DIE 0xd3 + .byte 0 # end of children of DIE 0xa6 + .uleb128 0x5 # (DIE (0xf5) DW_TAG_subprogram) + # DW_AT_external + .long .LASF13 # DW_AT_name: "ptwrite1" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x15 # DW_AT_decl_line + .byte 0x1 # DW_AT_decl_column + # DW_AT_prototyped + .quad .LFB4096 # DW_AT_low_pc + .quad .LFE4096-.LFB4096 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + # DW_AT_GNU_all_call_sites + .long 0x144 # DW_AT_sibling + .uleb128 0x6 # (DIE (0x113) DW_TAG_formal_parameter) + .long .LASF14 # DW_AT_name: "value" + .byte 0x1 # DW_AT_decl_file (ptwrite.c) + .byte 0x15 # DW_AT_decl_line + .byte 0xf # DW_AT_decl_column + .long 0x2d # DW_AT_type + .uleb128 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 -36 + .uleb128 0x7 # (DIE (0x122) DW_TAG_inlined_subroutine) + .long 0x144 # DW_AT_abstract_origin + .quad .LBB6 # DW_AT_low_pc + .quad .LBE6-.LBB6 # DW_AT_high_pc + .byte 0x1 # DW_AT_call_file (ptwrite.c) + .byte 0x17 # DW_AT_call_line + .byte 0x3 # DW_AT_call_column + .uleb128 0x8 # (DIE (0x13a) DW_TAG_formal_parameter) + .long 0x14e # DW_AT_abstract_origin + .uleb128 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 -20 + .byte 0 # end of children of DIE 0x122 + .byte 0 # end of children of DIE 0xf5 + .uleb128 0x9 # (DIE (0x144) DW_TAG_subprogram) + # DW_AT_external + .long .LASF19 # DW_AT_name: "_ptwrite32" + .byte 0x2 # DW_AT_decl_file (/usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h) + .value 0x131 # DW_AT_decl_line + .byte 0x1 # DW_AT_decl_column + # DW_AT_prototyped + .byte 0x3 # DW_AT_inline + # DW_AT_artificial + .uleb128 0xa # (DIE (0x14e) DW_TAG_formal_parameter) + .ascii "__B\0" # DW_AT_name + .byte 0x2 # DW_AT_decl_file (/usr/lib/gcc/x86_64-redhat-linux/10/include/immintrin.h) + .value 0x131 # DW_AT_decl_line + .byte 0x16 # DW_AT_decl_column + .long 0x6c # DW_AT_type + .byte 0 # end of children of DIE 0x144 + .byte 0 # end of children of DIE 0xb + .section .debug_abbrev,"",@progbits +.Ldebug_abbrev0: + .uleb128 0x1 # (abbrev code) + .uleb128 0x11 # (TAG: DW_TAG_compile_unit) + .byte 0x1 # DW_children_yes + .uleb128 0x25 # (DW_AT_producer) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x13 # (DW_AT_language) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x1b # (DW_AT_comp_dir) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x7 # (DW_FORM_data8) + .uleb128 0x10 # (DW_AT_stmt_list) + .uleb128 0x17 # (DW_FORM_sec_offset) + .byte 0 + .byte 0 + .uleb128 0x2 # (abbrev code) + .uleb128 0x24 # (TAG: DW_TAG_base_type) + .byte 0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3e # (DW_AT_encoding) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .byte 0 + .byte 0 + .uleb128 0x3 # (abbrev code) + .uleb128 0x24 # (TAG: DW_TAG_base_type) + .byte 0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3e # (DW_AT_encoding) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .byte 0 + .byte 0 + .uleb128 0x4 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0 # DW_children_no + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x7 # (DW_FORM_data8) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0x18 # (DW_FORM_exprloc) + .uleb128 0x2116 # (DW_AT_GNU_all_tail_call_sites) + .uleb128 0x19 # (DW_FORM_flag_present) + .byte 0 + .byte 0 + .uleb128 0x5 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x7 # (DW_FORM_data8) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0x18 # (DW_FORM_exprloc) + .uleb128 0x2117 # (DW_AT_GNU_all_call_sites) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x1 # (DW_AT_sibling) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0x6 # (abbrev code) + .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x18 # (DW_FORM_exprloc) + .byte 0 + .byte 0 + .uleb128 0x7 # (abbrev code) + .uleb128 0x1d # (TAG: DW_TAG_inlined_subroutine) + .byte 0x1 # DW_children_yes + .uleb128 0x31 # (DW_AT_abstract_origin) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x7 # (DW_FORM_data8) + .uleb128 0x58 # (DW_AT_call_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x59 # (DW_AT_call_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x57 # (DW_AT_call_column) + .uleb128 0xb # (DW_FORM_data1) + .byte 0 + .byte 0 + .uleb128 0x8 # (abbrev code) + .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) + .byte 0 # DW_children_no + .uleb128 0x31 # (DW_AT_abstract_origin) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x18 # (DW_FORM_exprloc) + .byte 0 + .byte 0 + .uleb128 0x9 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0x5 # (DW_FORM_data2) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x20 # (DW_AT_inline) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x34 # (DW_AT_artificial) + .uleb128 0x19 # (DW_FORM_flag_present) + .byte 0 + .byte 0 + .uleb128 0xa # (abbrev code) + .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0x5 # (DW_FORM_data2) + .uleb128 0x39 # (DW_AT_decl_column) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .byte 0 + .section .debug_aranges,"",@progbits + .long 0x2c # Length of Address Ranges Info + .value 0x2 # DWARF aranges version + .long .Ldebug_info0 # Offset of Compilation Unit Info + .byte 0x8 # Size of Address + .byte 0 # Size of Segment Descriptor + .value 0 # Pad to 16 byte boundary + .value 0 + .quad .Ltext0 # Address + .quad .Letext0-.Ltext0 # Length + .quad 0 + .quad 0 + .section .debug_line,"",@progbits +.Ldebug_line0: + .section .debug_str,"MS",@progbits,1 +.LASF2: + .string "long long int" +.LASF14: + .string "value" +.LASF19: + .string "_ptwrite32" +.LASF8: + .string "unsigned int" +.LASF17: + .string "gdb/gdb/testsuite/gdb.btrace" +.LASF18: + .string "main" +.LASF16: + .string "ptwrite.c" +.LASF4: + .string "long unsigned int" +.LASF10: + .string "long long unsigned int" +.LASF15: + .string "GNU C17 10.3.1 20210422 (Red Hat 10.3.1-1) -mptwrite -mtune=generic -march=x86-64 -g" +.LASF13: + .string "ptwrite1" +.LASF12: + .string "ptwrite2" +.LASF6: + .string "unsigned char" +.LASF1: + .string "char" +.LASF5: + .string "long int" +.LASF11: + .string "double" +.LASF7: + .string "short unsigned int" +.LASF9: + .string "signed char" +.LASF3: + .string "float" +.LASF0: + .string "short int" + .ident "GCC: (GNU) 10.3.1 20210422 (Red Hat 10.3.1-1)" + .section .note.GNU-stack,"",@progbits diff --git a/gdb/testsuite/gdb.cp/anon-ns.exp b/gdb/testsuite/gdb.cp/anon-ns.exp index c01a3ab..2b2376d 100644 --- a/gdb/testsuite/gdb.cp/anon-ns.exp +++ b/gdb/testsuite/gdb.cp/anon-ns.exp @@ -55,12 +55,10 @@ foreach test $methods { gdb_test "list $test" $result gdb_test "list '$test'" $result - if {[gdb_breakpoint $test]} { - pass "break $test" - } - if {[gdb_breakpoint '$test']} { - pass "break '$test'" - } + gdb_assert { [gdb_breakpoint $test no-message] } \ + "break $test, unquoted" + gdb_assert { [gdb_breakpoint '$test' no-message] } \ + "break $test, single-quoted" } # PR c++/17976 diff --git a/gdb/testsuite/gdb.cp/classes.exp b/gdb/testsuite/gdb.cp/classes.exp index 97dca29..4d29bf5 100644 --- a/gdb/testsuite/gdb.cp/classes.exp +++ b/gdb/testsuite/gdb.cp/classes.exp @@ -502,7 +502,7 @@ proc test_enums {} { gdb_test "print obj_with_enum" \ "\\$\[0-9\]+ = \{priv_enum = (ClassWithEnum::)?green, x = 0\}" \ - "print obj_with_enum (2)" + "print obj_with_enum, 2" # print the enum member diff --git a/gdb/testsuite/gdb.cp/exception.exp b/gdb/testsuite/gdb.cp/exception.exp index 0cc97fe..5489d0c 100644 --- a/gdb/testsuite/gdb.cp/exception.exp +++ b/gdb/testsuite/gdb.cp/exception.exp @@ -86,7 +86,7 @@ if { !$ok } { return } -set name "info breakpoints (after inferior run)" +set name "info breakpoints, after inferior run" gdb_test_multiple "info breakpoints" $name { -re "$re_head${ws}$re_2_bp${ws}$re_3_bp${ws}$re_4_bp\r\n$gdb_prompt $" { pass $name diff --git a/gdb/testsuite/gdb.cp/m-static.exp b/gdb/testsuite/gdb.cp/m-static.exp index 45bc090..3d59a48 100644 --- a/gdb/testsuite/gdb.cp/m-static.exp +++ b/gdb/testsuite/gdb.cp/m-static.exp @@ -71,11 +71,18 @@ if { [is_aarch32_target] } { gdb_test "print test5.single_constructor" \ { = {single_constructor \*\(single_constructor \* const\)} 0x[0-9a-f]+ <single_constructor::single_constructor\(\)>} \ "simple object instance, print constructor" - gdb_test "ptype test5.single_constructor" \ - {type = class single_constructor {\r\n public:\r\n single_constructor\(void\);\r\n ~single_constructor\(\);\r\n} \*\(single_constructor \* const\)} \ + + set re \ + [multi_line_string_to_regexp \ + "type = class single_constructor {" \ + "" \ + " public:" \ + " single_constructor(void);" \ + " ~single_constructor(void);" \ + "} *(single_constructor * const)"] + gdb_test "ptype test5.single_constructor" $re \ "simple object instance, ptype constructor" - gdb_test "ptype single_constructor::single_constructor" \ - {type = class single_constructor {\r\n public:\r\n single_constructor\(void\);\r\n ~single_constructor\(\);\r\n} \*\(single_constructor \* const\)} \ + gdb_test "ptype single_constructor::single_constructor" $re \ "simple object class, ptype constructor" gdb_test "print test1.~gnu_obj_1" \ @@ -168,12 +175,12 @@ if {[test_compiler_info {gcc-[0-3]-*}] # and DW_AT_MIPS_linkage_name = _ZN9gnu_obj_47nowhereE . setup_xfail *-*-* } -gdb_test "print test4.nowhere" "<optimized out>" "static const int initialized nowhere (print field)" +gdb_test "print test4.nowhere" "<optimized out>" "static const int initialized nowhere, print field" gdb_test "ptype test4.nowhere" "type = const int" gdb_test "print test4.nowhere.nowhere" "Attempt to extract a component of a value that is not a structure." # Same, but print the whole struct. -gdb_test "print test4" "static nowhere = <optimized out>.*" "static const int initialized nowhere (whole struct)" +gdb_test "print test4" "static nowhere = <optimized out>.*" "static const int initialized nowhere, whole struct" # static const initialized in the class definition, PR gdb/11702. if { $non_dwarf } { setup_xfail *-*-* } diff --git a/gdb/testsuite/gdb.cp/member-ptr.exp b/gdb/testsuite/gdb.cp/member-ptr.exp index 838fe96..d02a1ea 100644 --- a/gdb/testsuite/gdb.cp/member-ptr.exp +++ b/gdb/testsuite/gdb.cp/member-ptr.exp @@ -43,7 +43,7 @@ gdb_continue_to_breakpoint "continue to pmi = NULL" # ptype on pointer to data member -set name "ptype pmi (A::j)" +set name "ptype pmi, A::j" gdb_test_multiple "ptype pmi" $name { -re "type = int A::\\*\r\n$gdb_prompt $" { pass $name @@ -52,7 +52,7 @@ gdb_test_multiple "ptype pmi" $name { # print pointer to data member -set name "print pmi (A::j) " +set name "print pmi, A::j" gdb_test_multiple "print pmi" $name { -re "$vhn = &A::j\r\n$gdb_prompt $" { pass $name @@ -77,7 +77,7 @@ gdb_test_multiple "print pmi" $name { # print dereferenced pointer to data member -set name "print a.*pmi (A::j)" +set name "print a.*pmi, A::j" gdb_test_multiple "print a.*pmi" $name { -re "$vhn = 121\r\n$gdb_prompt $" { pass $name @@ -97,7 +97,7 @@ gdb_test_multiple "print a.*pmi" $name { # print dereferenced pointer to data member # this time, dereferenced through a pointer -set name "print a_p->*pmi (A::j)" +set name "print a_p->*pmi, A::j" gdb_test_multiple "print a_p->*pmi" $name { -re "$vhn = 121\r\n$gdb_prompt $" { pass $name @@ -133,7 +133,7 @@ gdb_test_multiple "set var pmi = &A::jj" $name { # print the pointer again -set name "print pmi (A::jj)" +set name "print pmi, A::jj" gdb_test_multiple "print pmi" $name { -re "$vhn = &A::jj\r\n$gdb_prompt $" { pass $name @@ -150,7 +150,7 @@ gdb_test_multiple "print pmi" $name { # print dereferenced pointer to data member again -set name "print a.*pmi (A::jj)" +set name "print a.*pmi, A::jj" gdb_test_multiple "print a.*pmi" $name { -re "$vhn = 1331\r\n$gdb_prompt $" { pass $name @@ -181,7 +181,7 @@ gdb_test_multiple "set var pmi = &A::j" $name { # print dereferenced pointer to data member yet again (extra check, why not) -set name "print a.*pmi (A::j) (again)" +set name "print a.*pmi, A::j, again" gdb_test_multiple "print a.*pmi" $name { -re "$vhn = 121\r\n$gdb_prompt $" { pass $name @@ -209,7 +209,7 @@ gdb_test_multiple "print a.*pmi = 33" $name { # Now check that the data really was changed -set name "print a.*pmi (A::j) (33)" +set name "print a.*pmi, A::j, 33" gdb_test_multiple "print a.*pmi" $name { -re "$vhn = 33\r\n$gdb_prompt $" { pass $name @@ -223,7 +223,7 @@ gdb_test_multiple "print a.*pmi" $name { # Double-check by printing a. -set name "print a (j = 33)" +set name "print a, j = 33" gdb_test_multiple "print a" $name { -re "$vhn = \{c = 120 'x', j = 33, jj = 1331, (static|static int) s = 10, (_vptr.A|_vptr\\$) = ($hex|$hex <A virtual table>)\}\r\n$gdb_prompt $" { pass $name @@ -257,7 +257,7 @@ gdb_test_multiple "print a_p->*pmi = 44" $name { # Check that the data really was changed -set name "print a_p->*pmi (44)" +set name "print a_p->*pmi, 44" gdb_test_multiple "print a_p->*pmi" $name { -re "$vhn = 44\r\n$gdb_prompt $" { pass $name @@ -271,7 +271,7 @@ gdb_test_multiple "print a_p->*pmi" $name { # Double-check by printing a. -set name "print a (j = 44)" +set name "print a, j = 44" gdb_test_multiple "print a" $name { -re "$vhn = \{c = 120 'x', j = 44, jj = 1331, (static|static int) s = 10, (_vptr.A|_vptr\\$) = ($hex|$hex <A virtual table>)\}\r\n$gdb_prompt $" { pass $name diff --git a/gdb/testsuite/gdb.cp/meth-typedefs.exp b/gdb/testsuite/gdb.cp/meth-typedefs.exp index a1829a1..149f44c 100644 --- a/gdb/testsuite/gdb.cp/meth-typedefs.exp +++ b/gdb/testsuite/gdb.cp/meth-typedefs.exp @@ -152,12 +152,10 @@ foreach test $methods { gdb_test "list -qualified $func" $result gdb_test "list -qualified '$func'" $result - if {[gdb_breakpoint "-qualified $func"]} { - pass "break -qualified $func" - } - if {[gdb_breakpoint "-qualified '$func'"]} { - pass "break -qualified '$func'" - } + gdb_assert { [gdb_breakpoint "-qualified $func" no-message] } \ + "break -qualified $func, unquoted" + gdb_assert { [gdb_breakpoint "-qualified '$func'" no-message] } \ + "break -qualified $func, single-quoted" } # The tests above use -qualified to explicitly pick the one "test" diff --git a/gdb/testsuite/gdb.cp/method2.exp b/gdb/testsuite/gdb.cp/method2.exp index 9aa9bf0..0a07ff3 100644 --- a/gdb/testsuite/gdb.cp/method2.exp +++ b/gdb/testsuite/gdb.cp/method2.exp @@ -50,11 +50,11 @@ proc test_break { lang } { incr idx } set expect [join $menu_items {.*[\r\n]*}] - gdb_test_multiple "break A::method" "breaking in method ($lang)" { + gdb_test_multiple "break A::method" "breaking in method, $lang" { -re $expect { gdb_test "0" \ "canceled" \ - "breaking in method ($lang)" + $gdb_test_name } } } diff --git a/gdb/testsuite/gdb.cp/misc.exp b/gdb/testsuite/gdb.cp/misc.exp index bcb20f8..3f5532e 100644 --- a/gdb/testsuite/gdb.cp/misc.exp +++ b/gdb/testsuite/gdb.cp/misc.exp @@ -51,10 +51,10 @@ proc test_expr { args } { } set last_ent [expr [llength $args] - 1] set testname [lindex $args $last_ent] - gdb_test_no_output [lindex $args 0] "$testname (setup)" + gdb_test_no_output [lindex $args 0] "$testname, setup" for {set x 1} {$x < $last_ent} {set x [expr $x + 2]} { - gdb_test [lindex $args $x] [lindex $args [expr $x + 1]] "$testname ([lindex $args $x])" + gdb_test [lindex $args $x] [lindex $args [expr $x + 1]] "$testname, [lindex $args $x]" } } diff --git a/gdb/testsuite/gdb.cp/nested-types.exp b/gdb/testsuite/gdb.cp/nested-types.exp index 5621fff..294358c 100644 --- a/gdb/testsuite/gdb.cp/nested-types.exp +++ b/gdb/testsuite/gdb.cp/nested-types.exp @@ -269,7 +269,7 @@ proc test_nested_limit {limit log} { } gdb_test "show print type nested-type-limit" \ "Will print $lstr nested types defined in a class" \ - "show print type nested-type-limit ($limit)" + "show print type nested-type-limit, $limit" } else { send_log "Tree to $limit levels:\n" } @@ -283,7 +283,7 @@ proc test_nested_limit {limit log} { # the outermost node. set result [lindex $result 0] lassign $result type access key name children - cp_test_ptype_class $name "ptype $name (limit = $limit)" $key \ + cp_test_ptype_class $name "ptype $name, limit = $limit" $key \ $name $children } } diff --git a/gdb/testsuite/gdb.cp/ovldbreak.exp b/gdb/testsuite/gdb.cp/ovldbreak.exp index 882a83b..99d0a38 100644 --- a/gdb/testsuite/gdb.cp/ovldbreak.exp +++ b/gdb/testsuite/gdb.cp/ovldbreak.exp @@ -248,7 +248,7 @@ foreach ovld $overloads { append bptable [format "\r\n\[0-9\]+\[\t \]+breakpoint\[\t \]+keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(%s\\) at.*$srcfile:%d" $ovld \ $line($type_map("$ovld"))] } -gdb_test "info break" $bptable "breakpoint info (after setting one-by-one)" +gdb_test "info break" $bptable "breakpoint info, after setting one-by-one" # Test choice "cancel". # This is copy-and-paste from set_bp_overloaded. @@ -288,7 +288,7 @@ gdb_expect { } } -gdb_test "info break" $bptable "breakpoint info (after cancel)" +gdb_test "info break" $bptable "breakpoint info, after cancel" # Test that if the user selects multiple entries from the option list, # GDB creates one breakpoint per entry. @@ -325,7 +325,7 @@ gdb_expect { } } -gdb_test "info breakpoints" "No breakpoints, watchpoints, tracepoints, or catchpoints." "breakpoint info (after delete)" +gdb_test "info breakpoints" "No breakpoints, watchpoints, tracepoints, or catchpoints." "breakpoint info, after delete" @@ -375,7 +375,7 @@ foreach ovld {void char signed_char unsigned_char short_int \ $types($ovld) $line($ovld)] } -gdb_test "info break" $bptable "breakpoint info (after setting on all)" +gdb_test "info break" $bptable "breakpoint info, after setting on all" # Run through each breakpoint. proc continue_to_bp_overloaded {bpnumber might_fail line argtype argument} { diff --git a/gdb/testsuite/gdb.cp/pass-by-ref-2.exp b/gdb/testsuite/gdb.cp/pass-by-ref-2.exp index 3c7b19a..00141d8 100644 --- a/gdb/testsuite/gdb.cp/pass-by-ref-2.exp +++ b/gdb/testsuite/gdb.cp/pass-by-ref-2.exp @@ -72,22 +72,22 @@ gdb_test "print cbvDtorDel (*dtorDel)" \ # Test that GDB calls the correct copy ctor gdb_test "print cbvFourCCtor (fourCctor_c0v0)" "13" \ - "call cbvFourCCtor (c0v0)" + "call cbvFourCCtor, c0v0" gdb_test "print fourCctor_c0v0.x" "2" \ "cbv argument 'twoCctor_c0v0' should not change" gdb_test "print cbvFourCCtor (fourCctor_c1v0)" "14" \ - "call cbvFourCCtor (c1v0)" + "call cbvFourCCtor, c1v0" gdb_test "print fourCctor_c1v0.x" "2" \ "cbv argument 'twoCctor_c1v0' should not change" gdb_test "print cbvFourCCtor (fourCctor_c0v1)" "15" \ - "call cbvFourCCtor (c0v1)" + "call cbvFourCCtor, c0v1" gdb_test "print fourCctor_c0v1.x" "2" \ "cbv argument 'twoCctor_c0v1' should not change" gdb_test "print cbvFourCCtor (fourCctor_c1v1)" "16" \ - "call cbvFourCCtor (c1v1)" + "call cbvFourCCtor, c1v1" gdb_test "print fourCctor_c1v1.x" "2" \ "cbv argument 'twoCctor_c1v1' should not change" diff --git a/gdb/testsuite/gdb.cp/pass-by-ref.exp b/gdb/testsuite/gdb.cp/pass-by-ref.exp index 7b2a619..a1f1df4 100644 --- a/gdb/testsuite/gdb.cp/pass-by-ref.exp +++ b/gdb/testsuite/gdb.cp/pass-by-ref.exp @@ -396,12 +396,12 @@ proc test_for_class { prefix states cbvfun data_field length} { gdb_test "print ${cbvfun}<$name> (${name}_var)" " = $expected" \ "call '$cbvfun'" gdb_test "print ${name}_var.${data_field}\[0\]" " = $ORIGINAL" \ - "cbv argument should not change (item 0)" + "cbv argument should not change, item 0" if {$length > 1} { set last_index [expr $length - 1] gdb_test "print ${name}_var.${data_field}\[$last_index\]" \ " = $ORIGINAL" \ - "cbv argument should not change (item $last_index)" + "cbv argument should not change, item $last_index" } if {$dtor == "explicit"} { if {$cctor == "defaultedIn" diff --git a/gdb/testsuite/gdb.cp/templates.exp b/gdb/testsuite/gdb.cp/templates.exp index 52129d8..8dd0cdc 100644 --- a/gdb/testsuite/gdb.cp/templates.exp +++ b/gdb/testsuite/gdb.cp/templates.exp @@ -641,7 +641,8 @@ foreach t [list "int" "char" "Empty<int>"] { gdb_test "break Foozle::fogey<$t>" "Breakpoint.*at.* \\(3 locations\\)" foreach u [list "int" "char" "Empty<int>"] { gdb_breakpoint "Foozle<$t>::fogey<$u>" message - gdb_breakpoint "Foozle<$t>::fogey<$u> ($u)" message + gdb_assert { [gdb_breakpoint "Foozle<$t>::fogey<$u> ($u)" no-message] } \ + "break Foozle<$t>::fogey<$u> ($u), success" } } @@ -667,10 +668,14 @@ foreach t [list "Empty" "Foozle"] { # Try a specific instance, both with and without whitespace # after the template-template parameter. - gdb_breakpoint "operator< <$tt> ($tt&, $tt&)" message - gdb_breakpoint "operator< <$tt > ($tt&, $tt&)" message - gdb_breakpoint "operator<< <$tt> ($tt&, $tt&)" message - gdb_breakpoint "operator<< <$tt > ($tt&, $tt&)" message + set loc "operator< <$tt> ($tt&, $tt&)" + gdb_assert { [gdb_breakpoint $loc no-message] } "break $loc, success" + set loc "operator< <$tt > ($tt&, $tt&)" + gdb_assert { [gdb_breakpoint $loc no-message] } "break $loc, success" + set loc "operator<< <$tt> ($tt&, $tt&)" + gdb_assert { [gdb_breakpoint $loc no-message] } "break $loc, success" + set loc "operator<< <$tt > ($tt&, $tt&)" + gdb_assert { [gdb_breakpoint $loc no-message] } "break $loc, success" } # Test that "-qualified" finds no matching locations. diff --git a/gdb/testsuite/gdb.dap/catch-exception.exp b/gdb/testsuite/gdb.dap/catch-exception.exp index 166b862..a1ced06 100644 --- a/gdb/testsuite/gdb.dap/catch-exception.exp +++ b/gdb/testsuite/gdb.dap/catch-exception.exp @@ -57,6 +57,12 @@ foreach spec $bps { gdb_assert {[dict get $spec source path] != "null"} \ "breakpoint $i path" } + + # Breakpoint should be unverified and pending. + gdb_assert {[dict get $spec verified] == "false"} \ + "catchpoint $i is unverified" + gdb_assert {[dict get $spec reason] == "pending"} \ + "catchpoint $i is pending" } incr i } diff --git a/gdb/testsuite/gdb.dap/cxx-exception.exp b/gdb/testsuite/gdb.dap/cxx-exception.exp index b54b11a..1332043 100644 --- a/gdb/testsuite/gdb.dap/cxx-exception.exp +++ b/gdb/testsuite/gdb.dap/cxx-exception.exp @@ -37,6 +37,16 @@ set bps [dict get [lindex $obj 0] body breakpoints] # breakpoints. gdb_assert {[llength $bps] == 3} "three breakpoints" +# Each breakpoint should be unverified and pending. +foreach bp $bps { + with_test_prefix [dict get $bp id] { + gdb_assert {[dict get $bp verified] == "false"} \ + "catchpoint is unverified" + gdb_assert {[dict get $bp reason] == "pending"} \ + "catchpoint is pending" + } +} + dap_check_request_and_response "configurationDone" configurationDone if {[dap_launch $testfile] == ""} { diff --git a/gdb/testsuite/gdb.dap/global.c b/gdb/testsuite/gdb.dap/global.c new file mode 100644 index 0000000..d3b7085 --- /dev/null +++ b/gdb/testsuite/gdb.dap/global.c @@ -0,0 +1,31 @@ +/* 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/>. */ + +static struct { + int x; + struct { + int x2; + } y; +} global; + +int +main () +{ + global.x = 23; + global.y.x2 = 47; + return 0; /* BREAK */ +} diff --git a/gdb/testsuite/gdb.dap/global.exp b/gdb/testsuite/gdb.dap/global.exp new file mode 100644 index 0000000..79f7f2f --- /dev/null +++ b/gdb/testsuite/gdb.dap/global.exp @@ -0,0 +1,72 @@ +# 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 allow_dap_tests + +load_lib dap-support.exp + +standard_testfile + +if {[build_executable ${testfile}.exp $testfile $srcfile] == -1} { + return +} + +if {[dap_initialize] == ""} { + return +} + +set line [gdb_get_line_number "BREAK"] +set obj [dap_check_request_and_response "set breakpoint by line number" \ + setBreakpoints \ + [format {o source [o path [%s]] breakpoints [a [o line [i %d]]]} \ + [list s $srcfile] $line]] +set line_bpno [dap_get_breakpoint_number $obj] + +dap_check_request_and_response "configurationDone" configurationDone + +if {[dap_launch $testfile] == ""} { + return +} +dap_wait_for_event_and_check "inferior started" thread "body reason" started + +dap_wait_for_event_and_check "stopped at line breakpoint" stopped \ + "body reason" breakpoint \ + "body hitBreakpointIds" $line_bpno + +set bt [lindex [dap_check_request_and_response "backtrace" stackTrace \ + {o threadId [i 1]}] \ + 0] +set frame_id [dict get [lindex [dict get $bt body stackFrames] 0] id] + +set scopes [dap_check_request_and_response "get scopes" scopes \ + [format {o frameId [i %d]} $frame_id]] +set scopes [dict get [lindex $scopes 0] body scopes] + +gdb_assert {[llength $scopes] == 2} "two scopes" + +lassign $scopes reg_scope global_scope + +gdb_assert {[dict get $global_scope name] == "Globals"} "scope is globals" + +gdb_assert {[dict get $global_scope namedVariables] == 1} "one var in globals" + +set num [dict get $global_scope variablesReference] +set refs [lindex [dap_check_request_and_response "fetch variables" \ + "variables" \ + [format {o variablesReference [i %d] count [i 1]} \ + $num]] \ + 0] + +dap_shutdown diff --git a/gdb/testsuite/gdb.dap/insn-bp.exp b/gdb/testsuite/gdb.dap/insn-bp.exp new file mode 100644 index 0000000..4a4c144 --- /dev/null +++ b/gdb/testsuite/gdb.dap/insn-bp.exp @@ -0,0 +1,100 @@ +# 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/>. + +# Test instruction breakpoint resolution. + +require allow_dap_tests + +load_lib dap-support.exp + +standard_testfile basic-dap.c + +if {[build_executable ${testfile}.exp $testfile $srcfile] == -1} { + return +} + +# Get the address of a function. Make sure the inferior is running +# first -- on the ARM builder, the function address changed during +# startup, and we want to find the final relocated address. +clean_restart $testfile +if {![runto_main]} { + return +} +set addr [get_var_address address_breakpoint_here] +gdb_exit + +if {[dap_initialize] == ""} { + return +} + +set obj [dap_check_request_and_response "set breakpoint on main" \ + setFunctionBreakpoints \ + {o breakpoints [a [o name [s main]]]}] +set fn_bpno [dap_get_breakpoint_number $obj] + +set obj [dap_check_request_and_response "set breakpoint by address" \ + setInstructionBreakpoints \ + [format {o breakpoints [a [o instructionReference [s %s]]]} \ + $addr]] +set bpno [dap_get_breakpoint_number $obj] + +set bp [lindex [dict get [lindex $obj 0] body breakpoints] 0] +gdb_assert {[dict get $bp verified] == "false"} \ + "breakpoint is not verified" + +dap_check_request_and_response "configurationDone" configurationDone + +if {[dap_launch $testfile] == ""} { + return +} + +# The event we're looking for should occur during startup, but we want +# to leave open the possibility that it occurs when waiting for the +# stopped event. So, keep both event lists around and search them +# once below. +lassign [dap_wait_for_event_and_check "inferior started" \ + thread "body reason" started] \ + unused objs1 +lassign [dap_wait_for_event_and_check "stopped at breakpoint" stopped \ + "body reason" breakpoint \ + "body hitBreakpointIds" $fn_bpno] unused objs2 + +set found_bp_event 0 +foreach obj [concat $objs1 $objs2] { + if { [dict get $obj "type"] != "event" } { + continue + } + + if { [dict get $obj "event"] != "breakpoint" } { + continue + } + + set body [dict get $obj "body"] + + if { [dict get $body "reason"] != "changed" } { + continue + } + + set breakpoint [dict get $body breakpoint] + if {[dict get $breakpoint id] == $bpno} { + gdb_assert {[dict get $breakpoint source name] == "basic-dap.c"} \ + "breakpoint modification event has source" + set found_bp_event 1 + } +} + +gdb_assert {$found_bp_event} "found the breakpoint event" + +dap_shutdown diff --git a/gdb/testsuite/gdb.dap/rust-slices.exp b/gdb/testsuite/gdb.dap/rust-slices.exp index d3bd305..4af8c11 100644 --- a/gdb/testsuite/gdb.dap/rust-slices.exp +++ b/gdb/testsuite/gdb.dap/rust-slices.exp @@ -59,9 +59,9 @@ set scopes [dap_check_request_and_response "get scopes" scopes \ [format {o frameId [i %d]} $frame_id]] set scopes [dict get [lindex $scopes 0] body scopes] -# There are three scopes because an artificial symbol ends up in the -# DWARF. See https://github.com/rust-lang/rust/issues/125126. -gdb_assert {[llength $scopes] == 3} "three scopes" +# There may be three scopes instead of two if an artificial symbol ends up in +# the DWARF. See https://github.com/rust-lang/rust/issues/125126. +gdb_assert { [llength $scopes] == 2 || [llength $scopes] == 3 } "two scopes" lassign $scopes scope ignore gdb_assert {[dict get $scope name] == "Locals"} "scope is locals" diff --git a/gdb/testsuite/gdb.dap/step-out.exp b/gdb/testsuite/gdb.dap/step-out.exp index 31c50bb..193264f 100644 --- a/gdb/testsuite/gdb.dap/step-out.exp +++ b/gdb/testsuite/gdb.dap/step-out.exp @@ -59,15 +59,21 @@ set scopes [dap_check_request_and_response "get scopes" scopes \ [format {o frameId [i %d]} $frame_id]] set scopes [dict get [lindex $scopes 0] body scopes] -gdb_assert {[llength $scopes] == 2} "two scopes" +gdb_assert {[llength $scopes] == 3} "three scopes" -lassign $scopes scope reg_scope +lassign $scopes scope reg_scope return_scope gdb_assert {[dict get $scope name] == "Locals"} "scope is locals" gdb_assert {[dict get $scope presentationHint] == "locals"} \ "locals presentation hint" -gdb_assert {[dict get $scope namedVariables] == 2} "two vars in scope" +gdb_assert {[dict get $scope namedVariables] == 1} "one var in scope" -set num [dict get $scope variablesReference] +gdb_assert {[dict get $return_scope name] == "Return"} "scope is return" +gdb_assert {[dict get $return_scope presentationHint] == "returnValue"} \ + "returnValue presentation hint" +gdb_assert {[dict get $return_scope namedVariables] == 1} \ + "one var in return scope" + +set num [dict get $return_scope variablesReference] set refs [lindex [dap_check_request_and_response "fetch arguments" \ "variables" \ [format {o variablesReference [i %d]} $num]] \ diff --git a/gdb/testsuite/gdb.dwarf2/dw2-anon-mptr.exp b/gdb/testsuite/gdb.dwarf2/dw2-anon-mptr.exp index 5935ba6..fa98e41 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-anon-mptr.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-anon-mptr.exp @@ -36,5 +36,19 @@ gdb_test "show cp-abi" {The currently selected C\+\+ ABI is "gnu-v3".*} gdb_load $binfile +set re_address_class "@\[^\r\n\]+" + +set re_class_ptr_const \ + [string cat \ + [string_to_regexp "class {...} * const"] "( $re_address_class)?"] + gdb_test "ptype crash" \ - "type = class crash {\[\r\n \t\]*public:\[\r\n \t\]*crash\\(int \\(class {\\.\\.\\.}::\\*\\)\\(class {\\.\\.\\.} \\* const\\)\\);\[\r\n \t\]*}" + [multi_line \ + "type = class crash {" \ + "" \ + " public:" \ + [string cat \ + [string_to_regexp " crash(int (class {...}::*)("] \ + $re_class_ptr_const \ + [string_to_regexp "));"]] \ + "}"] diff --git a/gdb/testsuite/gdb.dwarf2/dw2-fixed-point.c b/gdb/testsuite/gdb.dwarf2/dw2-fixed-point.c index 58b97ca..2789e6a 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-fixed-point.c +++ b/gdb/testsuite/gdb.dwarf2/dw2-fixed-point.c @@ -46,11 +46,5 @@ int8_t pck__fp1_range_var = 16; int main (void) { - pck__fp1_var++; - pck__fp1_var2++; - pck__fp2_var++; - pck__fp3_var++; - pck__fp1_range_var++; - return 0; } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-lines.exp b/gdb/testsuite/gdb.dwarf2/dw2-lines.exp index af5b6b7..9617782 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-lines.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-lines.exp @@ -122,9 +122,9 @@ proc test_1 { _cv _cdw64 _lv _ldw64 {_string_form ""}} { gdb_breakpoint "bar_label" gdb_continue_to_breakpoint "foo \\(1\\)" - gdb_test "next" "foo \\(2\\).*" "next to foo (2)" - gdb_test "next" "foo \\(3\\).*" "next to foo (3)" - gdb_test "next" "foo \\(4\\).*" "next to foo (4)" + gdb_test "next" "foo \\(2\\).*" "next to foo(2)" + gdb_test "next" "foo \\(3\\).*" "next to foo(3)" + gdb_test "next" "foo \\(4\\).*" "next to foo(4)" } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-opt-structptr.exp b/gdb/testsuite/gdb.dwarf2/dw2-opt-structptr.exp index cebed1d..d73f4a8 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-opt-structptr.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-opt-structptr.exp @@ -126,6 +126,8 @@ proc build_test_program {} { } } +set re_address_class "@\[^\r\n\]+" + # Test access to an optimized-out pointer-to-struct using the # console interpreter. @@ -210,13 +212,18 @@ proc do_mi_test {} { # Test that -var-create for 'ptr' is successful. mi_create_varobj "var1" "ptr" "create varobj for ptr" + + set struct_foo_ptr \ + [string cat \ + [string_to_regexp "struct foo *"] "( $::re_address_class)?"] # Test that -var-list-children of 'ptr' is successful. - mi_list_varobj_children "var1" { \ - {var1.a a 0 integer} \ - {var1.x x 128 foo__array_type} \ - {var1.y y 3 "struct foo \\*"} \ - } "get children of var1 (ptr)" + mi_list_varobj_children "var1" \ + [list \ + {var1.a a 0 integer} \ + {var1.x x 128 foo__array_type} \ + [list "var1.y" "y" "3" $struct_foo_ptr]] \ + "get children of var1 (ptr)" # Test that dereferencing 'ptr' will throw an error. mi_gdb_test "-var-create var2 * &((ptr)->a)" \ diff --git a/gdb/testsuite/gdb.dwarf2/macro-complaints.exp b/gdb/testsuite/gdb.dwarf2/macro-complaints.exp new file mode 100644 index 0000000..01060b8 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/macro-complaints.exp @@ -0,0 +1,198 @@ +# 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/>. + +# Test complaints about .debug_macro section. + +load_lib dwarf.exp + +require dwarf2_support +require !readnow + +standard_testfile main.c .S + +lassign [function_range main $srcdir/$subdir/$srcfile] \ + main_start main_len + +set asm_file [standard_output_file $srcfile2] + +set line [gdb_get_line_number "return 0;"] + +Dwarf::assemble $asm_file { + declare_labels L cu_macro1 + + cu {} { + DW_TAG_compile_unit { + {DW_AT_name $::srcfile} + {DW_AT_macros $cu_macro1 DW_FORM_sec_offset} + {DW_AT_stmt_list $L DW_FORM_sec_offset} + } { + declare_labels int_type + + int_type: DW_TAG_base_type { + {DW_AT_byte_size 4 DW_FORM_sdata} + {DW_AT_encoding @DW_ATE_signed} + {DW_AT_name int} + } + DW_TAG_subprogram { + {MACRO_AT_func {main}} + {type :$int_type} + } + } + } + + lines {version 2} L { + file_name $::srcfile 1 + program { + DW_LNE_set_address $::main_start + line $::line + DW_LNS_copy + DW_LNE_set_address "$::main_start + $::main_len" + DW_LNE_end_sequence + } + } + + # Define the .debug_macro section. + macro { + cu_macro1: unit { + "debug-line-offset-label" $L + } { + define 0 "M1_01_BUILTIN_OK 1" + define 1 "M1_02_BUILTIN_BADLINE 1" + + start_file 0 1 + + define 1 "M1_03_OK 1" + define 0 "M1_04_BADLINE 1" + + start_file 1 1234 + define 1 "M1_05_BADFILE 1" + end_file + + define 1 "M1_06_OK " + define 1 "M1_07_MALFORMED" + define 1 "M1_08_OK() 1" + define 1 "M1_09_OK(ARG) (ARG)" + define 1 "M1_10_OK(ARG1,ARG2) (ARG1+ARG2)" + + define 1 "M1_11_MALFORMED(ARG" + define 1 "M1_12_MALFORMED(ARG," + define 1 "M1_13_MALFORMED(ARG,)" + define 1 "M1_14_MALFORMED()1" + + end_file + } + } +} + +if { [build_executable "failed to prepare" $testfile \ + [list $srcfile $asm_file] {nodebug}] } { + return +} + +clean_restart + +set re_complaint1 \ + "debug info gives command-line macro definition with non-zero line 1: M1_02_BUILTIN_BADLINE 1" + +set re_complaint2 \ + "debug info gives in-file macro definition with zero line 0: M1_04_BADLINE 1" + +set re_complaint3 \ + [string_to_regexp "bad file number in macro information (1234)"] + +set re_complaint4 \ + [multi_line \ + "macro debug info contains a malformed macro definition:" \ + "`M1_07_MALFORMED'"] + +set re_complaint5 \ + [multi_line \ + "macro debug info contains a malformed macro definition:" \ + [string_to_regexp "`M1_11_MALFORMED(ARG'"]] + +set re_complaint6 \ + [multi_line \ + "macro debug info contains a malformed macro definition:" \ + [string_to_regexp "`M1_12_MALFORMED(ARG,'"]] + +set re_complaint7 \ + [multi_line \ + "macro debug info contains a malformed macro definition:" \ + [string_to_regexp "`M1_13_MALFORMED(ARG,)'"]] + +set re_complaint8 \ + [multi_line \ + "macro debug info contains a malformed macro definition:" \ + [string_to_regexp "`M1_14_MALFORMED()1'"]] + +set prefix \ + "During symbol reading" + +set re \ + [multi_line \ + "$prefix: $re_complaint1" \ + "$prefix: $re_complaint2" \ + "$prefix: $re_complaint3" \ + "$prefix: $re_complaint4" \ + "$prefix: $re_complaint5" \ + "$prefix: $re_complaint6" \ + "$prefix: $re_complaint7" \ + "$prefix: $re_complaint8" \ + [string cat [string_to_regexp {$}] "$decimal = \[^\r\n\]+"]] + +with_complaints 10 { + gdb_load $binfile + gdb_test "p main" ^$re "complaints" +} + +set re_explicit \ + [multi_line \ + "Defined at $srcfile:0" \ + "-DM1_01_BUILTIN_OK=1" \ + "Defined at $srcfile:1" \ + "#define M1_02_BUILTIN_BADLINE 1" \ + "Defined at $srcfile:1" \ + "#define M1_03_OK 1" \ + "Defined at $srcfile:0" \ + "-DM1_04_BADLINE=1" \ + "Defined at <bad macro file number 1234>:1" \ + " included at $srcfile:1" \ + "#define M1_05_BADFILE 1" \ + "Defined at $srcfile:1" \ + "#define M1_06_OK " \ + "Defined at $srcfile:1" \ + "#define M1_07_MALFORMED " \ + "Defined at $srcfile:1" \ + [string_to_regexp "#define M1_08_OK() 1"] \ + "Defined at $srcfile:1" \ + [string_to_regexp "#define M1_09_OK(ARG) (ARG)"] \ + "Defined at $srcfile:1" \ + [string_to_regexp "#define M1_10_OK(ARG1, ARG2) (ARG1+ARG2)"] \ + "Defined at $srcfile:1" \ + [string_to_regexp "#define M1_13_MALFORMED(ARG) "]] + +set re_implicit \ + [multi_line \ + "Defined at $srcfile:-1" \ + "#define __FILE__ \"$srcfile\"" \ + "Defined at $srcfile:-1" \ + "#define __LINE__ $line"] + +gdb_test "info macros $line" \ + [multi_line \ + $re_explicit \ + $re_implicit] diff --git a/gdb/testsuite/gdb.dwarf2/member-ptr-forwardref.exp b/gdb/testsuite/gdb.dwarf2/member-ptr-forwardref.exp index c97c887..21ad111 100644 --- a/gdb/testsuite/gdb.dwarf2/member-ptr-forwardref.exp +++ b/gdb/testsuite/gdb.dwarf2/member-ptr-forwardref.exp @@ -34,5 +34,19 @@ gdb_test "show cp-abi" {The currently selected C\+\+ ABI is "gnu-v3".*} gdb_load ${binfile} +set re_address_class "@\[^\r\n\]+" + +set re_C_ptr \ + [string cat \ + [string_to_regexp "C *"] "( const)?( $re_address_class)?"] + gdb_test_no_output "set language c++" -gdb_test "ptype c" "type = struct C {\[\r\n \t\]*private:\[\r\n \t\]*int \\(C::\\*fp\\)\\(C \\*( const)?\\);\[\r\n \t\]*}" +gdb_test "ptype c" \ + [multi_line \ + "type = struct C {" \ + " private:" \ + [string cat \ + [string_to_regexp " int (C::*fp)("] \ + $re_C_ptr \ + [string_to_regexp ");"]] \ + "}"] diff --git a/gdb/testsuite/gdb.dwarf2/per-bfd-sharing.exp b/gdb/testsuite/gdb.dwarf2/per-bfd-sharing.exp index ef1ed19..7df68a9 100644 --- a/gdb/testsuite/gdb.dwarf2/per-bfd-sharing.exp +++ b/gdb/testsuite/gdb.dwarf2/per-bfd-sharing.exp @@ -19,7 +19,7 @@ standard_testfile if { [build_executable "failed to prepare" $testfile $srcfile \ - {debug ldflags=-Wl,--build-id}] == -1 } { + {debug build-id}] == -1 } { return } set host_binfile [gdb_remote_download host $binfile] diff --git a/gdb/testsuite/gdb.fortran/entry-point.exp b/gdb/testsuite/gdb.fortran/entry-point.exp index 4e4706d..51550ad 100644 --- a/gdb/testsuite/gdb.fortran/entry-point.exp +++ b/gdb/testsuite/gdb.fortran/entry-point.exp @@ -72,12 +72,12 @@ set entry_point_name "mod::mod_foo" # GCC moves subroutines with entry points out of the module scope into the # compile unit scope. -if {[test_compiler_info {gcc-*}]} { +if {[test_compiler_info {gcc-*}] || [test_compiler_info {clang-*}]} { setup_xfail "gcc/105272" "*-*-*" } gdb_breakpoint $entry_point_name -if {[test_compiler_info {gcc-*}]} { +if {[test_compiler_info {gcc-*}] || [test_compiler_info {clang-*}]} { setup_xfail "gcc/105272" "*-*-*" } gdb_continue_to_breakpoint "continue to breakpoint: $entry_point_name" \ diff --git a/gdb/testsuite/gdb.fortran/intrinsics.exp b/gdb/testsuite/gdb.fortran/intrinsics.exp index 60c79f9..060bb53 100644 --- a/gdb/testsuite/gdb.fortran/intrinsics.exp +++ b/gdb/testsuite/gdb.fortran/intrinsics.exp @@ -112,10 +112,14 @@ gdb_test "ptype cmplx (4,4)" "= complex\\*4" gdb_test "p cmplx (-14,-4)" "= \\(-14,-4\\)" gdb_test "p cmplx (4,4,4)" "\\(4,4\\)" gdb_test "p cmplx (4,4,8)" "\\(4,4\\)" -gdb_test "p cmplx (4,4,16)" "\\(4,4\\)" +set re_unsupported_kind_16 \ + [string_to_regexp "unsupported kind 16 for type complex*4"] +gdb_test "p cmplx (4,4,16)" \ + ([string_to_regexp " = (4,4)"]|$re_unsupported_kind_16) gdb_test "ptype cmplx (4,4,4)" "= complex\\*4" gdb_test "ptype cmplx (4,4,8)" "= complex\\*8" -gdb_test "ptype cmplx (4,4,16)" "= complex\\*16" +gdb_test "ptype cmplx (4,4,16)" \ + ([string_to_regexp " = complex*16"]|$re_unsupported_kind_16) gdb_test "p cmplx (4,4,1)" "unsupported kind 1 for type complex\\*4" gdb_test "p cmplx (4,4,-1)" "unsupported kind -1 for type complex\\*4" diff --git a/gdb/testsuite/gdb.fortran/multi-dim.exp b/gdb/testsuite/gdb.fortran/multi-dim.exp index 3325e52..eda2d6a 100644 --- a/gdb/testsuite/gdb.fortran/multi-dim.exp +++ b/gdb/testsuite/gdb.fortran/multi-dim.exp @@ -41,19 +41,19 @@ gdb_test "print foo(2,3,4)" \ gdb_test "print foo(0,0,0)" \ "no such vector element" \ - "print an invalid array index (0,0,0)" + "print an invalid array index @ 0,0,0" gdb_test "print foo(2,3,5)" \ "no such vector element" \ - "print an invalid array index (2,3,5)" + "print an invalid array index @ 2,3,5" gdb_test "print foo(2,4,4)" \ "no such vector element" \ - "print an invalid array index (2,4,4)" + "print an invalid array index @ 2,4,4" gdb_test "print foo(3,3,4)" \ "no such vector element" \ - "print an invalid array index (3,3,4)" + "print an invalid array index @ 3,3,4" gdb_test "print foo" \ { = \(\(\(10, 10\) \(10, 10\) \(10, 10\)\) \(\(10, 10\) \(10, 10\) \(10, 10\)\) \(\(10, 10\) \(10, 10\) \(10, 10\)\) \(\(10, 10\) \(10, 10\) \(10, 20\)\)\)} \ diff --git a/gdb/testsuite/gdb.fortran/size.exp b/gdb/testsuite/gdb.fortran/size.exp index 93fb444..925aeed 100644 --- a/gdb/testsuite/gdb.fortran/size.exp +++ b/gdb/testsuite/gdb.fortran/size.exp @@ -95,7 +95,7 @@ gdb_assert {$found_dealloc_breakpoint} "ran all compiled in tests" foreach var {array_1d_p array_2d_p allocatable_array_1d \ allocatable_array_2d} { - gdb_test_multiple "p size ($var, 3)" "p size ($var, 3)" { + gdb_test_multiple "p size ($var, 3)" "" { -re -wrap "DIM argument to SIZE must be between 1 and \[1-2\]" { pass $gdb_test_name } @@ -129,7 +129,7 @@ gdb_continue_to_breakpoint "Final Breakpoint" foreach var {array_1d_p array_2d_p allocatable_array_1d \ allocatable_array_2d} { - gdb_test_multiple "p size ($var)" "p size ($var)" { + gdb_test_multiple "p size ($var)" "" { -re -wrap "SIZE can only be used on allocated/associated arrays" { pass $gdb_test_name } diff --git a/gdb/testsuite/gdb.fortran/type-kinds.exp b/gdb/testsuite/gdb.fortran/type-kinds.exp index ab5f19f..a6f2aa4 100644 --- a/gdb/testsuite/gdb.fortran/type-kinds.exp +++ b/gdb/testsuite/gdb.fortran/type-kinds.exp @@ -43,12 +43,20 @@ proc test_basic_parsing_of_type_kinds {} { test_cast_1_to_type_kind "complex" "" "\\(1,0\\)" "8" test_cast_1_to_type_kind "complex" "4" "\\(1,0\\)" "8" test_cast_1_to_type_kind "complex" "8" "\\(1,0\\)" "16" - test_cast_1_to_type_kind "complex" "16" "\\(1,0\\)" "32" + set re_unsupported_kind \ + [string_to_regexp "unsupported kind 16 for type complex*4"] + test_cast_1_to_type_kind "complex" "16" \ + [string_to_regexp (1,0)]|$re_unsupported_kind \ + 32|$re_unsupported_kind test_cast_1_to_type_kind "real" "" "1" "4" test_cast_1_to_type_kind "real" "4" "1" "4" test_cast_1_to_type_kind "real" "8" "1" "8" - test_cast_1_to_type_kind "real" "16" "1" "16" + set re_unsupported_kind \ + [string_to_regexp "unsupported kind 16 for type real*4"] + test_cast_1_to_type_kind "real" "16" \ + 1|$re_unsupported_kind \ + 16|$re_unsupported_kind test_cast_1_to_type_kind "logical" "" "\\.TRUE\\." "4" test_cast_1_to_type_kind "logical" "1" "\\.TRUE\\." "1" @@ -83,11 +91,17 @@ proc test_old_star_type_sizes {} { gdb_test "p ((complex*4) 1)" " = \\(1,0\\)" gdb_test "p ((complex*8) 1)" " = \\(1,0\\)" - gdb_test "p ((complex*16) 1)" " = \\(1,0\\)" + set re_unsupported_kind \ + [string_to_regexp "unsupported kind 16 for type complex*4"] + gdb_test "p ((complex*16) 1)" \ + [string_to_regexp " = (1,0)"]|$re_unsupported_kind gdb_test "p ((real*4) 1)" " = 1" gdb_test "p ((real*8) 1)" " = 1" - gdb_test "p ((real*16) 1)" " = 1" + set re_unsupported_kind \ + [string_to_regexp "unsupported kind 16 for type real*4"] + gdb_test "p ((real*16) 1)" \ + "( = 1|$re_unsupported_kind)" gdb_test "p ((logical*1) 1)" " = \\.TRUE\\." gdb_test "p ((logical*4) 1)" " = \\.TRUE\\." diff --git a/gdb/testsuite/gdb.fortran/types.exp b/gdb/testsuite/gdb.fortran/types.exp index 83b1098..edbf5ab 100644 --- a/gdb/testsuite/gdb.fortran/types.exp +++ b/gdb/testsuite/gdb.fortran/types.exp @@ -94,7 +94,24 @@ proc test_primitive_types_known {} { # While TYPE_KIND is allowed as input, GDB will always return the # Fortran notation TYPE*KIND regsub -all "_" $type "\*" type_res - gdb_test "ptype $type" [string_to_regexp "type = $type_res"] + set re [string_to_regexp "type = $type_res"] + switch $type { + real*16 - complex*16 { + regexp {^[^*_]*} $type base + set re_unsupported \ + [string_to_regexp \ + "unsupported kind 16 for type $base*4"] + set re ($re|$re_unsupported) + } + real_16 - complex_16 { + set re_unsupported \ + [string_to_regexp \ + "unsupported type $type_res"] + set re ($re|$re_unsupported) + } + } + + gdb_test "ptype $type" $re } } diff --git a/gdb/testsuite/gdb.fortran/vla-alloc-assoc.exp b/gdb/testsuite/gdb.fortran/vla-alloc-assoc.exp index 5e6c3f8..01717b0 100644 --- a/gdb/testsuite/gdb.fortran/vla-alloc-assoc.exp +++ b/gdb/testsuite/gdb.fortran/vla-alloc-assoc.exp @@ -32,32 +32,32 @@ if ![fortran_runto_main] { gdb_breakpoint [gdb_get_line_number "vla1-allocated"] gdb_continue_to_breakpoint "vla1-allocated" gdb_test "print l" " = \\.TRUE\\." \ - "print vla1 allocation status (allocated)" + "print vla1 allocation status, allocated" gdb_breakpoint [gdb_get_line_number "vla2-allocated"] gdb_continue_to_breakpoint "vla2-allocated" gdb_test "print l" " = \\.TRUE\\." \ - "print vla2 allocation status (allocated)" + "print vla2 allocation status, allocated" gdb_breakpoint [gdb_get_line_number "pvla-associated"] gdb_continue_to_breakpoint "pvla-associated" gdb_test "print l" " = \\.TRUE\\." \ - "print pvla associated status (associated)" + "print pvla associated status, associated" gdb_breakpoint [gdb_get_line_number "pvla-re-associated"] gdb_continue_to_breakpoint "pvla-re-associated" gdb_test "print l" " = \\.TRUE\\." \ - "print pvla associated status (re-associated)" + "print pvla associated status, re-associated" gdb_breakpoint [gdb_get_line_number "pvla-deassociated"] gdb_continue_to_breakpoint "pvla-deassociated" gdb_test "print l" " = \\.FALSE\\." \ - "print pvla allocation status (deassociated)" + "print pvla allocation status, deassociated" gdb_breakpoint [gdb_get_line_number "vla1-deallocated"] gdb_continue_to_breakpoint "vla1-deallocated" gdb_test "print l" " = \\.FALSE\\." \ - "print vla1 allocation status (deallocated)" + "print vla1 allocation status, deallocated" gdb_test "print vla1" " = <not allocated>" \ "print deallocated vla1" diff --git a/gdb/testsuite/gdb.fortran/vla-datatypes.exp b/gdb/testsuite/gdb.fortran/vla-datatypes.exp index ed3b0f1..8227f23 100644 --- a/gdb/testsuite/gdb.fortran/vla-datatypes.exp +++ b/gdb/testsuite/gdb.fortran/vla-datatypes.exp @@ -74,12 +74,12 @@ gdb_test "print charactervla(5,5,5)" " = 'K'" \ gdb_breakpoint [gdb_get_line_number "vlas-modified"] gdb_continue_to_breakpoint "vlas-modified" -gdb_test "print intvla(5,5,5)" " = 42" "print intvla(5,5,5) (2nd)" +gdb_test "print intvla(5,5,5)" " = 42" "print intvla(5,5,5), 2nd" gdb_test "print realvla(5,5,5)" " = 4.13\\d+" \ - "print realvla(5,5,5) (2nd)" + "print realvla(5,5,5), 2nd" gdb_test "print complexvla(5,5,5)" " = \\\(-3,2\\\)" \ - "print complexvla(5,5,5) (2nd)" + "print complexvla(5,5,5), 2nd" gdb_test "print logicalvla(5,5,5)" " = \\.FALSE\\." \ - "print logicalvla(5,5,5) (2nd)" + "print logicalvla(5,5,5), 2nd" gdb_test "print charactervla(5,5,5)" " = 'X'" \ - "print charactervla(5,5,5) (2nd)" + "print charactervla(5,5,5), 2nd" diff --git a/gdb/testsuite/gdb.fortran/vla-ptype-sub.exp b/gdb/testsuite/gdb.fortran/vla-ptype-sub.exp index cf3fcfe..78b711b 100644 --- a/gdb/testsuite/gdb.fortran/vla-ptype-sub.exp +++ b/gdb/testsuite/gdb.fortran/vla-ptype-sub.exp @@ -33,7 +33,7 @@ set real [fortran_real4] # Pass fixed array to function and handle them as vla in function. gdb_breakpoint [gdb_get_line_number "not-filled"] -gdb_continue_to_breakpoint "not-filled (1st)" +gdb_continue_to_breakpoint "not-filled, 1st" gdb_test "ptype array1" "type = $int \\\(42,42\\\)" \ "ptype array1 (passed fixed)" gdb_test "ptype array2" "type = $real \\\(42,42,42\\\)" \ @@ -44,15 +44,15 @@ gdb_test "ptype array2(13, 11, 5)" "type = $real" \ "ptype array2(13, 11, 5) (passed fixed)" # Pass sub arrays to function and handle them as vla in function. -gdb_continue_to_breakpoint "not-filled (2nd)" +gdb_continue_to_breakpoint "not-filled, 2nd" gdb_test "ptype array1" "type = $int \\\(6,6\\\)" \ - "ptype array1 (passed sub-array)" + "ptype array1, passed sub-array" gdb_test "ptype array2" "type = $real \\\(6,6,6\\\)" \ - "ptype array2 (passed sub-array)" + "ptype array2, passed sub-array" gdb_test "ptype array1(3, 3)" "type = $int" \ - "ptype array1(3, 3) (passed sub-array)" + "ptype array1(3, 3), passed sub-array" gdb_test "ptype array2(4, 4, 4)" "type = $real" \ - "ptype array2(4, 4, 4) (passed sub-array)" + "ptype array2(4, 4, 4), passed sub-array" # Check ptype outside of bounds. This should not crash GDB. gdb_test "ptype array1(100, 100)" "no such vector element" \ @@ -61,15 +61,15 @@ gdb_test "ptype array2(100, 100, 100)" "no such vector element" \ "ptype array2(100, 100, 100) subarray do not crash (passed sub-array)" # Pass vla to function. -gdb_continue_to_breakpoint "not-filled (3rd)" +gdb_continue_to_breakpoint "not-filled, 3rd" gdb_test "ptype array1" "type = $int \\\(20,20\\\)" \ - "ptype array1 (passed vla)" + "ptype array1, passed vla" gdb_test "ptype array2" "type = $real \\\(10,10,10\\\)" \ - "ptype array2 (passed vla)" + "ptype array2, passed vla" gdb_test "ptype array1(3, 3)" "type = $int" \ - "ptype array1(3, 3) (passed vla)" + "ptype array1(3, 3), passed vla" gdb_test "ptype array2(4, 4, 4)" "type = $real" \ - "ptype array2(4, 4, 4) (passed vla)" + "ptype array2(4, 4, 4), passed vla" # Check ptype outside of bounds. This should not crash GDB. gdb_test "ptype array1(100, 100)" "no such vector element" \ @@ -83,11 +83,11 @@ gdb_breakpoint [gdb_get_line_number "end-of-bar"] gdb_continue_to_breakpoint "end-of-bar" gdb_test "ptype array1" \ "type = (PTR TO -> \\( )?$int \\(\\*\\)\\)?" \ - "ptype array1 (arbitrary length)" + "ptype array1, arbitrary length" gdb_test "ptype array2" \ "type = (PTR TO -> \\( )?$int \\(4:9,10:\\*\\)\\)?" \ - "ptype array2 (arbitrary length)" + "ptype array2, arbitrary length" gdb_test "ptype array1(100)" "type = $int" \ - "ptype array1(100) (arbitrary length)" + "ptype array1(100), arbitrary length" gdb_test "ptype array2(4,100)" "type = $int" \ - "ptype array2(4,100) (arbitrary length)" + "ptype array2(4,100), arbitrary length" diff --git a/gdb/testsuite/gdb.fortran/vla-value-sub.exp b/gdb/testsuite/gdb.fortran/vla-value-sub.exp index cbeec34..23ee539 100644 --- a/gdb/testsuite/gdb.fortran/vla-value-sub.exp +++ b/gdb/testsuite/gdb.fortran/vla-value-sub.exp @@ -45,7 +45,7 @@ gdb_test "print array1(1, 1)" " = 30" \ "print array1(1, 1) after filled in foo (passed fixed array)" gdb_breakpoint [gdb_get_line_number "array2-almost-filled"] -gdb_continue_to_breakpoint "array2-almost-filled (1st)" +gdb_continue_to_breakpoint "array2-almost-filled, 1st" # array2 size is 296352 bytes. gdb_test_no_output "set max-value-size 1024*1024" gdb_test "print array2" " = \\( *\\( *\\( *30, *3, *3,\[()3, .\]*\\)" \ @@ -57,40 +57,40 @@ gdb_test "print array2" " = \\( *\\( *\\( *30, *20, *3,\[()3, .\]*\\)" \ # Try to access values from a fixed sub-array handled as VLA in subroutine. -gdb_continue_to_breakpoint "not-filled (2nd)" +gdb_continue_to_breakpoint "not-filled, 2nd" gdb_test "print array1" " = \\(\[()5, .\]*\\)" \ - "print passed array1 in foo (passed sub-array)" + "print passed array1 in foo, passed sub-array" -gdb_continue_to_breakpoint "array1-filled (2nd)" +gdb_continue_to_breakpoint "array1-filled, 2nd" gdb_test "print array1(5, 5)" " = 5" \ - "print array1(5, 5) after filled in foo (passed sub-array)" + "print array1(5, 5) after filled in foo, passed sub-array" gdb_test "print array1(1, 1)" " = 30" \ - "print array1(1, 1) after filled in foo (passed sub-array)" + "print array1(1, 1) after filled in foo, passed sub-array" -gdb_continue_to_breakpoint "array2-almost-filled (2nd)" +gdb_continue_to_breakpoint "array2-almost-filled, 2nd" gdb_test "print array2" " = \\( *\\( *\\( *30, *3, *3,\[()3, .\]*\\)" \ - "print array2 in foo after it was filled (passed sub-array)" + "print array2 in foo after it was filled, passed sub-array" gdb_test "print array2(2,1,1)=20" " = 20" \ - "set array(2,2,2) to 20 in subroutine (passed sub-array)" + "set array(2,2,2) to 20 in subroutine, passed sub-array" gdb_test "print array2" " = \\( *\\( *\\( *30, *20, *3,\[()3, .\]*\\)" \ - "print array2 in foo after it was mofified in debugger (passed sub-array)" + "print array2 in foo after it was mofified in debugger, passed sub-array" # Try to access values from a VLA passed to subroutine. -gdb_continue_to_breakpoint "not-filled (3rd)" +gdb_continue_to_breakpoint "not-filled, 3rd" gdb_test "print array1" " = \\(\[()42, .\]*\\)" \ - "print passed array1 in foo (passed vla)" + "print passed array1 in foo, passed vla" -gdb_continue_to_breakpoint "array1-filled (3rd)" +gdb_continue_to_breakpoint "array1-filled, 3rd" gdb_test "print array1(5, 5)" " = 5" \ - "print array1(5, 5) after filled in foo (passed vla)" + "print array1(5, 5) after filled in foo, passed vla" gdb_test "print array1(1, 1)" " = 30" \ - "print array1(1, 1) after filled in foo (passed vla)" + "print array1(1, 1) after filled in foo, passed vla" -gdb_continue_to_breakpoint "array2-almost-filled (3rd)" +gdb_continue_to_breakpoint "array2-almost-filled, 3rd" gdb_test "print array2" " = \\( *\\( *\\( *30, *3, *3,\[()3, .\]*\\)" \ - "print array2 in foo after it was filled (passed vla)" + "print array2 in foo after it was filled, passed vla" gdb_test "print array2(2,1,1)=20" " = 20" \ - "set array(2,2,2) to 20 in subroutine (passed vla)" + "set array(2,2,2) to 20 in subroutine, passed vla" gdb_test "print array2" " = \\( *\\( *\\( *30, *20, *3,\[()3, .\]*\\)" \ - "print array2 in foo after it was mofified in debugger (passed vla)" + "print array2 in foo after it was mofified in debugger, passed vla" diff --git a/gdb/testsuite/gdb.fortran/vla-value.exp b/gdb/testsuite/gdb.fortran/vla-value.exp index 587a491..a3f50d1 100644 --- a/gdb/testsuite/gdb.fortran/vla-value.exp +++ b/gdb/testsuite/gdb.fortran/vla-value.exp @@ -39,10 +39,10 @@ gdb_test "print &vla1" \ " = \\\(PTR TO -> \\\( $real, allocatable \\\(:,:,:\\\) \\\)\\\) $hex" \ "print non-allocated &vla1" gdb_test "print vla1(1,1,1)" "no such vector element \\\(vector not allocated\\\)" \ - "print member in non-allocated vla1 (1)" + "print member in non-allocated vla1, 1" gdb_test "print vla1(101,202,303)" \ "no such vector element \\\(vector not allocated\\\)" \ - "print member in non-allocated vla1 (2)" + "print member in non-allocated vla1, 2" gdb_test "print vla1(5,2,18)=1" "no such vector element \\\(vector not allocated\\\)" \ "set member in non-allocated vla1" @@ -68,11 +68,11 @@ gdb_test "print vla1(9, 9, 9) = 999" " = 999" \ gdb_breakpoint [gdb_get_line_number "vla1-filled"] gdb_continue_to_breakpoint "vla1-filled" gdb_test "print vla1(3, 6, 9)" " = 42" \ - "print allocated vla1(3,6,9) after specific assignment (filled)" + "print allocated vla1(3,6,9) after specific assignment, filled" gdb_test "print vla1(1, 3, 8)" " = 1001" \ - "print allocated vla1(1,3,8) after specific assignment (filled)" + "print allocated vla1(1,3,8) after specific assignment, filled" gdb_test "print vla1(9, 9, 9)" " = 999" \ - "print allocated vla1(9,9,9) after assignment in debugger (filled)" + "print allocated vla1(9,9,9) after assignment in debugger, filled" # Try to access values in undefined pointer to VLA (dangling) gdb_test "print pvla" " = <not associated>" "print undefined pvla" @@ -120,11 +120,11 @@ gdb_test "print pvla" " = <not associated>" \ gdb_breakpoint [gdb_get_line_number "vla1-deallocated"] gdb_continue_to_breakpoint "vla1-deallocated" gdb_test "print vla1(3, 6, 9)" "no such vector element \\\(vector not allocated\\\)" \ - "print allocated vla1(3,6,9) after specific assignment (deallocated)" + "print allocated vla1(3,6,9) after specific assignment, deallocated" gdb_test "print vla1(1, 3, 8)" "no such vector element \\\(vector not allocated\\\)" \ - "print allocated vla1(1,3,8) after specific assignment (deallocated)" + "print allocated vla1(1,3,8) after specific assignment, deallocated" gdb_test "print vla1(9, 9, 9)" "no such vector element \\\(vector not allocated\\\)" \ - "print allocated vla1(9,9,9) after assignment in debugger (deallocated)" + "print allocated vla1(9,9,9) after assignment in debugger, deallocated" # Try to assign VLA to user variable @@ -147,7 +147,7 @@ gdb_test "print \$myvar" \ " = \\( *\\( *\\( *1311, *1311, *1311,\[()1311, .\]*\\)" \ "print \$myvar set to vla1" -gdb_test "next" "\\d+.*vla1\\(1, 3, 8\\) = 1001" "next (2)" +gdb_test "next" "\\d+.*vla1\\(1, 3, 8\\) = 1001" "next, 2" gdb_test "print \$myvar(3,6,9)" " = 1311" gdb_breakpoint [gdb_get_line_number "pvla-associated"] diff --git a/gdb/testsuite/gdb.gdb/index-file.exp b/gdb/testsuite/gdb.gdb/index-file.exp index 72088ca..c30f417 100644 --- a/gdb/testsuite/gdb.gdb/index-file.exp +++ b/gdb/testsuite/gdb.gdb/index-file.exp @@ -38,12 +38,28 @@ with_timeout_factor $timeout_factor { # Record how many worker threads GDB is using. set worker_threads [gdb_get_worker_threads] +if { $worker_threads eq "UNKNOWN" } { + unresolved "unable to get worker thread count" + return -1 +} + # Generate an index file. set dir1 [standard_output_file "index_1"] remote_exec host "mkdir -p ${dir1}" with_timeout_factor $timeout_factor { - gdb_test_no_output "save gdb-index $dir1" \ - "create gdb-index file" + set ok 0 + gdb_test_multiple "save gdb-index $dir1" "create gdb-index file" { + -re -wrap "Error while writing index for \[^\r\n\]*: No debugging symbols" { + unsupported $gdb_test_name + } + -re -wrap "^" { + pass $gdb_test_name + set ok 1 + } + } + if { ! $ok } { + return -1 + } gdb_test_no_output "save gdb-index -dwarf-5 $dir1" \ "create dwarf-index files" diff --git a/gdb/testsuite/gdb.gdb/python-helper.exp b/gdb/testsuite/gdb.gdb/python-helper.exp index 8a8afb1..4589edc 100644 --- a/gdb/testsuite/gdb.gdb/python-helper.exp +++ b/gdb/testsuite/gdb.gdb/python-helper.exp @@ -111,6 +111,16 @@ proc test_python_helper {} { } } + # Add a second inferior, useful to the intrusive_list pretty-printer test + # below. + send_inferior "add-inferior\n" + gdb_test_multiple "" "add second inferior in inner GDB" { + -i "$inferior_spawn_id" + -re "Added inferior 2\r\n$gdb_prompt $" { + pass $gdb_test_name + } + } + # Send Ctrl-C to the inner GDB, this should kick us back to the # prompt of the outer GDB. send_inferior "\003" @@ -253,6 +263,11 @@ proc test_python_helper {} { # Test the htab_t pretty-printer. gdb_test -prompt $outer_prompt_re "print all_bfds" "htab_t with ${::decimal} elements = \\{${::hex}.*\\}" + # Test the intrusive_list pretty-printer. A bug occured in the + # pretty-printer for lists with more than one element. Verify that + # we see both elements of the inferior_list list being printed. + gdb_test -prompt $outer_prompt_re "print inferior_list" "intrusive list of inferior = {.*, num = 1,.*, num = 2,.*}" + return 0 } diff --git a/gdb/testsuite/gdb.guile/scm-frame.exp b/gdb/testsuite/gdb.guile/scm-frame.exp index 34c9f8c..bd54e63 100644 --- a/gdb/testsuite/gdb.guile/scm-frame.exp +++ b/gdb/testsuite/gdb.guile/scm-frame.exp @@ -91,9 +91,9 @@ gdb_test "guile (print (eq? bframe (newest-frame)))" \ #t "newest frame -vs- newest frame" gdb_test "guile (print (eq? f0 f1))" \ - "#f" "test equality comparison (false)" + "#f" "test equality comparison, false" gdb_test "guile (print (eq? f0 f0))" \ - "#t" "test equality comparison (true)" + "#t" "test equality comparison, true" gdb_test "guile (print (frame-valid? f0))" \ "#t" "test frame-valid?" gdb_test "guile (print (frame-name f0))" \ diff --git a/gdb/testsuite/gdb.guile/scm-parameter.exp b/gdb/testsuite/gdb.guile/scm-parameter.exp index 20c601e..d10e9d2 100644 --- a/gdb/testsuite/gdb.guile/scm-parameter.exp +++ b/gdb/testsuite/gdb.guile/scm-parameter.exp @@ -62,11 +62,11 @@ gdb_test_multiline "Simple gdb boolean parameter" \ "end" with_test_prefix "test-param" { - gdb_test "guile (print (parameter-value test-param))" "= #t" "parameter value (true)" + gdb_test "guile (print (parameter-value test-param))" "= #t" "parameter value, true" gdb_test "show print test-param" "The state of the Test Parameter is on." "show parameter on" gdb_test_no_output "set print test-param off" gdb_test "show print test-param" "The state of the Test Parameter is off." "show parameter off" - gdb_test "guile (print (parameter-value test-param))" "= #f" "parameter value (false)" + gdb_test "guile (print (parameter-value test-param))" "= #f" "parameter value, false" gdb_test "help show print test-param" "Show the state of the boolean test-param.*" "show help" gdb_test "help set print test-param" "Set the state of the boolean test-param.*" "set help" gdb_test "help set print" "set print test-param -- Set the state of the boolean test-param.*" "general help" @@ -94,11 +94,11 @@ gdb_test_multiline "enum gdb parameter" \ "end" with_test_prefix "test-enum-param" { - gdb_test "guile (print (parameter-value test-enum-param))" "one" "enum parameter value (one)" + gdb_test "guile (print (parameter-value test-enum-param))" "one" "enum parameter value, one" gdb_test "show print test-enum-param" "The state of the enum is one." "show initial value" gdb_test_no_output "set print test-enum-param two" gdb_test "show print test-enum-param" "The state of the enum is two." "show new value" - gdb_test "guile (print (parameter-value test-enum-param))" "two" "enum parameter value (two)" + gdb_test "guile (print (parameter-value test-enum-param))" "two" "enum parameter value, two" gdb_test "set print test-enum-param three" "Undefined item: \"three\".*" "set invalid enum parameter" } @@ -241,14 +241,14 @@ foreach_with_prefix kind { with_test_prefix "test-$kind-param" { gdb_test "guile (print (parameter-value test-$kind-param))" \ - 3 "$kind parameter value (3)" + 3 "$kind parameter value, 3" gdb_test "show print test-$kind-param" \ "The state of $kind is 3." "show initial value" gdb_test_no_output "set print test-$kind-param 2" gdb_test "show print test-$kind-param" \ "The state of $kind is 2." "show new value" gdb_test "guile (print (parameter-value test-$kind-param))" \ - 2 "$kind parameter value (2)" + 2 "$kind parameter value, 2" scm_param_test_maybe_no_output \ "guile (set-parameter-value! test-$kind-param #:unlimited)" \ $param_set_unlimited @@ -257,18 +257,18 @@ foreach_with_prefix kind { "show unlimited value" gdb_test_no_output "guile (set-parameter-value! test-$kind-param 1)" gdb_test "guile (print (parameter-value test-$kind-param))" \ - 1 "$kind parameter value (1)" + 1 "$kind parameter value, 1" gdb_test_no_output "guile (set-parameter-value! test-$kind-param 0)" gdb_test "guile (print (parameter-value test-$kind-param))" \ - $param_get_zero "$kind parameter value (0)" + $param_get_zero "$kind parameter value, 0" scm_param_test_maybe_no_output "set print test-$kind-param -1" \ $param_set_minus_one gdb_test "guile (print (parameter-value test-$kind-param))" \ - $param_get_minus_one "$kind parameter value (-1)" + $param_get_minus_one "$kind parameter value, -1" scm_param_test_maybe_no_output "set print test-$kind-param -2" \ $param_set_minus_two gdb_test "guile (print (parameter-value test-$kind-param))" \ - $param_get_minus_two "$kind parameter value (-2)" + $param_get_minus_two "$kind parameter value, -2" } } @@ -378,11 +378,11 @@ gdb_test_multiline "previously ambiguously named boolean parameter" \ gdb_test_no_output "guile (register-parameter! prev-ambig)" with_test_prefix "previously-ambiguous" { - gdb_test "guile (print (parameter-value prev-ambig))" "= #f" "parameter value (false)" + gdb_test "guile (print (parameter-value prev-ambig))" "= #f" "parameter value, false" gdb_test "show print s" "Command is not documented is off." "show parameter off" gdb_test_no_output "set print s on" gdb_test "show print s" "Command is not documented is on." "show parameter on" - gdb_test "guile (print (parameter-value prev-ambig))" "= #t" "parameter value (true)" + gdb_test "guile (print (parameter-value prev-ambig))" "= #t" "parameter value, true" gdb_test "help show print s" "This command is not documented." "show help" gdb_test "help set print s" "This command is not documented." "set help" gdb_test "help set print" "set print s -- This command is not documented.*" "general help" diff --git a/gdb/testsuite/gdb.guile/scm-symbol.exp b/gdb/testsuite/gdb.guile/scm-symbol.exp index 0b85848..ad22a8b 100644 --- a/gdb/testsuite/gdb.guile/scm-symbol.exp +++ b/gdb/testsuite/gdb.guile/scm-symbol.exp @@ -37,9 +37,9 @@ gdb_install_guile_module gdb_scm_test_silent_cmd "guile (define main-func (lookup-global-symbol \"main\"))" \ "lookup main" gdb_test "guile (print (symbol-function? main-func))" \ - "= #t" "test (symbol-function? main)" + "= #t" "test, symbol-function? main" gdb_test "guile (print (lookup-global-symbol \"junk\"))" \ - "= #f" "test (lookup-global-symbol junk)" + "= #f" "test, lookup-global-symbol junk" gdb_test "guile (print (symbol-value main-func))" \ "= {int \\(int, char \[*\]\[*\]\\)} $hex \\<main\\>" "print value of main" diff --git a/gdb/testsuite/gdb.guile/scm-type.exp b/gdb/testsuite/gdb.guile/scm-type.exp index 71fbe5b..3a4f2d0 100644 --- a/gdb/testsuite/gdb.guile/scm-type.exp +++ b/gdb/testsuite/gdb.guile/scm-type.exp @@ -70,7 +70,7 @@ proc test_fields {lang} { if {$lang == "c++"} { # Test usage with a class. - gdb_scm_test_silent_cmd "print c" "print value (c)" + gdb_scm_test_silent_cmd "print c" "print value, c" gdb_scm_test_silent_cmd "guile (define c (history-ref 0))" \ "get value (c) from history" gdb_scm_test_silent_cmd "guile (define fields (type-fields (value-type c)))" \ @@ -84,7 +84,7 @@ proc test_fields {lang} { } # Test normal fields usage in structs. - gdb_scm_test_silent_cmd "print st" "print value (st)" + gdb_scm_test_silent_cmd "print st" "print value, st" gdb_scm_test_silent_cmd "guile (define st (history-ref 0))" \ "get value (st) from history" gdb_scm_test_silent_cmd "guile (define st-type (value-type st))" \ @@ -120,7 +120,7 @@ proc test_fields {lang} { "check field iterator on bad type" # Test type-array. - gdb_scm_test_silent_cmd "print ar" "print value (ar)" + gdb_scm_test_silent_cmd "print ar" "print value, ar" gdb_scm_test_silent_cmd "guile (define ar (history-ref 0))" \ "get value (ar) from history" gdb_scm_test_silent_cmd "guile (define ar0 (value-subscript ar 0))" \ @@ -133,11 +133,11 @@ proc test_fields {lang} { # Test type-vector. # Note: vectors cast differently than arrays. Here ar[0] is replicated # for the size of the vector. - gdb_scm_test_silent_cmd "print vec_data_1" "print value (vec_data_1)" + gdb_scm_test_silent_cmd "print vec_data_1" "print value, vec_data_1" gdb_scm_test_silent_cmd "guile (define vec_data_1 (history-ref 0))" \ "get value (vec_data_1) from history" - gdb_scm_test_silent_cmd "print vec_data_2" "print value (vec_data_2)" + gdb_scm_test_silent_cmd "print vec_data_2" "print value, vec_data_2" gdb_scm_test_silent_cmd "guile (define vec_data_2 (history-ref 0))" \ "get value (vec_data_2) from history" @@ -192,7 +192,7 @@ proc test_equality {lang} { proc test_enums {} { with_test_prefix "test_enum" { - gdb_scm_test_silent_cmd "print e" "print value (e)" + gdb_scm_test_silent_cmd "print e" "print value, e" gdb_scm_test_silent_cmd "guile (define e (history-ref 0))" \ "get value (e) from history" gdb_scm_test_silent_cmd "guile (define fields (type-fields (value-type e)))" \ @@ -208,9 +208,9 @@ proc test_enums {} { gdb_test "guile (print (type-num-fields (value-type e)))" \ "= 3" "check the number of enum values" gdb_test "guile (print (field-name (type-field (value-type e) \"v1\")))" \ - "= v1" "check enum field lookup by name (v1)" + "= v1" "check enum field lookup by name, v1" gdb_test "guile (print (field-name (type-field (value-type e) \"v3\")))" \ - "= v3" "check enum field lookup by name (v3)" + "= v3" "check enum field lookup by name, v3" gdb_test "guile (print (iterator-map field-enumval (make-field-iterator (value-type e))))" \ "\\(0 1 2\\)" "check enum fields iteration" } @@ -218,7 +218,7 @@ proc test_enums {} { proc test_base_class {} { with_test_prefix "test_base_class" { - gdb_scm_test_silent_cmd "print d" "print value (d)" + gdb_scm_test_silent_cmd "print d" "print value, d" gdb_scm_test_silent_cmd "guile (define d (history-ref 0))" \ "get value (d) from history" gdb_scm_test_silent_cmd "guile (define fields (type-fields (value-type d)))" \ @@ -226,9 +226,9 @@ proc test_base_class {} { gdb_test "guile (print (length fields))" \ "= 3" "check the number of fields" gdb_test "guile (print (field-baseclass? (car fields)))" \ - "= #t" "check base class (fields\[0\])" + "= #t" {check base class, fields[0]} gdb_test "guile (print (field-baseclass? (cadr fields)))" \ - "= #f" "check base class (fields\[1\])" + "= #f" {check base class, fields[1]} } } @@ -236,7 +236,7 @@ proc test_range {} { with_test_prefix "test_range" { with_test_prefix "on ranged value" { # Test a valid range request. - gdb_scm_test_silent_cmd "print ar" "print value (ar)" + gdb_scm_test_silent_cmd "print ar" "print value, ar" gdb_scm_test_silent_cmd "guile (define ar (history-ref 0))" \ "get value (ar) from history" gdb_test "guile (print (length (type-range (value-type ar))))" \ @@ -247,7 +247,7 @@ proc test_range {} { with_test_prefix "on unranged value" { # Test where a range does not exist. - gdb_scm_test_silent_cmd "print st" "print value (st)" + gdb_scm_test_silent_cmd "print st" "print value, st" gdb_scm_test_silent_cmd "guile (define st (history-ref 0))" \ "get value (st) from history" gdb_test "guile (print (type-range (value-type st)))" \ @@ -256,7 +256,7 @@ proc test_range {} { } with_test_prefix "on flexible array member" { - gdb_scm_test_silent_cmd "print f" "print value (f)" + gdb_scm_test_silent_cmd "print f" "print value, f" gdb_scm_test_silent_cmd "guile (define f (history-ref 0))" \ "get value (f) from history" gdb_test "guile (print (type-range (field-type (type-field (value-type (value-dereference f)) \"items\"))))" \ diff --git a/gdb/testsuite/gdb.mi/mi-file.exp b/gdb/testsuite/gdb.mi/mi-file.exp index 8e404f9..00d2888 100644 --- a/gdb/testsuite/gdb.mi/mi-file.exp +++ b/gdb/testsuite/gdb.mi/mi-file.exp @@ -42,16 +42,10 @@ proc test_file_list_exec_source_file {} { } # get the path and absolute path to the current executable - # - # In gdb 6.2 (at least), the default line number is set by - # select_source_symtab to the first line of "main" minus - # the value of "lines_to_list" (which defaults to 10) plus one. - # --chastain 2004-08-13 set line_main_head [gdb_get_line_number "main ("] - set line_main_body [expr $line_main_head + 2] - set gdb_lines_to_list 10 - set line_default [expr $line_main_body - $gdb_lines_to_list + 1] + set line_main_prologue [expr $line_main_head + 1] + set line_default $line_main_prologue mi_gdb_test "111-file-list-exec-source-file" \ "111\\\^done,line=\"$line_default\",file=\"${srcfilepath}\",fullname=\"$fullname_syntax${srcfile}\",macro-info=\"0\"" \ diff --git a/gdb/testsuite/gdb.mi/mi-stepi.exp b/gdb/testsuite/gdb.mi/mi-stepi.exp index 3f4fc03..28aa293 100644 --- a/gdb/testsuite/gdb.mi/mi-stepi.exp +++ b/gdb/testsuite/gdb.mi/mi-stepi.exp @@ -41,25 +41,25 @@ proc test_stepi_nexti {} { set line [mi_execute_to "exec-step-instruction" "end-stepping-range" "main" "" \ ".*basics.c" "\[0-9\]+" "" "step-instruction at main"] if { $line >= $line_main_body && $line <= $line_main_hello } { - pass "step-instruction at main (line check)" + pass "step-instruction at main, line check" } else { - fail "step-instruction at main (line check)" + fail "step-instruction at main, line check" } set line [mi_execute_to "exec-next-instruction" "end-stepping-range" "main" "" \ ".*basics.c" "\[0-9\]+" "" "next-instruction at main"] if { $line >= $line_main_body && $line <= $line_main_hello } { - pass "next-instruction at main (line check)" + pass "next-instruction at main, line check" } else { - fail "next-instruction at main (line check)" + fail "next-instruction at main, line check" } set line [mi_execute_to "exec-next-instruction" "end-stepping-range" "main" "" \ ".*basics.c" "\[0-9\]+" "" "next-instruction at main 2"] if { $line >= $line_main_body && $line <= $line_main_hello } { - pass "next-instruction at main 2 (line check)" + pass "next-instruction at main 2, line check" } else { - fail "next-instruction at main 2 (line check)" + fail "next-instruction at main 2, line check" } } diff --git a/gdb/testsuite/gdb.mi/mi-var-cmd.exp b/gdb/testsuite/gdb.mi/mi-var-cmd.exp index a4789e5..1f97200 100644 --- a/gdb/testsuite/gdb.mi/mi-var-cmd.exp +++ b/gdb/testsuite/gdb.mi/mi-var-cmd.exp @@ -150,7 +150,7 @@ mi_gdb_test "-var-update *" \ "update all vars: linteger changed" # Step over "lpinteger = &linteger;" -mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 1] "step at do_locals_tests (2)" +mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 1] "step at do_locals_tests, 2" # Test: c_variable-2.3 # Desc: check whether only lpinteger changed @@ -159,7 +159,7 @@ mi_gdb_test "-var-update *" \ "update all vars: lpinteger changed" # Step over "lcharacter = 'a';" -mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 2] "step at do_locals_tests (3)" +mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 2] "step at do_locals_tests, 3" # Test: c_variable-2.4 # Desc: check whether only lcharacter changed @@ -168,7 +168,7 @@ mi_gdb_test "-var-update *" \ "update all vars: lcharacter changed" # Step over "lpcharacter = &lcharacter;" -mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 3] "step at do_locals_tests (4)" +mi_step_to "do_locals_tests" "" "var-cmd.c" [expr $line_dlt_linteger + 3] "step at do_locals_tests, 4" # Test: c_variable-2.5 # Desc: check whether only lpcharacter changed @@ -189,7 +189,7 @@ mi_gdb_test "-var-update *" \ # lsimple.character = 'a'; mi_execute_to "exec-step 9" "end-stepping-range" "do_locals_tests" "" \ - "var-cmd.c" [expr $line_dlt_linteger + 12] "" "step at do_locals_tests (5)" + "var-cmd.c" [expr $line_dlt_linteger + 12] "" "step at do_locals_tests, 5" # Test: c_variable-2.6 # Desc: check whether llong, lplong, lfloat, lpfloat, ldouble, lpdouble, lsimple.integer, @@ -207,7 +207,7 @@ mi_gdb_test "-var-update *" \ set line_dlt_4321 [gdb_get_line_number "linteger = 4321;"] mi_execute_to "exec-step 4" "end-stepping-range" "do_locals_tests" "" \ - "var-cmd.c" $line_dlt_4321 "" "step at do_locals_tests (6)" + "var-cmd.c" $line_dlt_4321 "" "step at do_locals_tests, 6" # Test: c_variable-2.7 # Desc: check whether (lsimple.signed_character, lsimple.char_ptr) lpsimple, func changed @@ -226,7 +226,7 @@ mi_gdb_test "-var-update *" \ # lsimple.character = 'b'; mi_execute_to "exec-step 8" "end-stepping-range" "do_locals_tests" "" \ - "var-cmd.c" [expr $line_dlt_4321 + 8] "" "step at do_locals_tests (7)" + "var-cmd.c" [expr $line_dlt_4321 + 8] "" "step at do_locals_tests, 7" # Test: c_variable-2.8 # Desc: check whether linteger, lcharacter, llong, lfoat, ldouble, lsimple.integer, @@ -374,7 +374,7 @@ mi_gdb_test "-var-assign func do_block_tests" \ mi_gdb_test "-var-update *" \ "\\^done,changelist=\\\[\\\]" \ - "assign same value to func (update)" + "assign same value to func, update" mi_gdb_test "-var-create array_ptr * array_ptr" \ "\\^done,name=\"array_ptr\",numchild=\"1\",value=\"$hex <array>\",type=\"int \\*\",has_more=\"0\"" \ @@ -386,7 +386,7 @@ mi_gdb_test "-var-assign array_ptr array2" \ mi_gdb_test "-var-update *" \ "\\^done,changelist=\\\[\{name=\"array_ptr\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\\\]" \ - "assign array to pointer (update)" + "assign array to pointer, update" mi_gdb_test "-var-assign array_ptr array2" \ "\\^done,value=\"$hex <array2>\"" \ @@ -394,7 +394,7 @@ mi_gdb_test "-var-assign array_ptr array2" \ mi_gdb_test "-var-update *" \ "\\^done,changelist=\\\[\\\]" \ - "assign same array to pointer (update)" + "assign same array to pointer, update" ###### @@ -434,7 +434,7 @@ mi_gdb_test "-var-update *" \ clear_xfail *-*-* mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}" \ - "var-cmd.c" [expr $line_subroutine1_body + 2] "step at subroutine1 (2)" + "var-cmd.c" [expr $line_subroutine1_body + 2] "step at subroutine1, 2" # Test: c_variable-2.13 # Desc: change subroutine1 local i @@ -443,7 +443,7 @@ mi_gdb_test "-var-update *" \ "update all vars: i changed" mi_step_to "subroutine1" "\{name=\"i\",value=\".*\"\},\{name=\"l\",value=\".*\"\}" \ - "var-cmd.c" [expr $line_subroutine1_body + 3] "step at subroutine1 (3)" + "var-cmd.c" [expr $line_subroutine1_body + 3] "step at subroutine1, 3" # Test: c_variable-2.14 # Desc: change do_locals_tests local llong diff --git a/gdb/testsuite/gdb.mi/mi-var-cp.cc b/gdb/testsuite/gdb.mi/mi-var-cp.cc index 4befab9..e8dd325 100644 --- a/gdb/testsuite/gdb.mi/mi-var-cp.cc +++ b/gdb/testsuite/gdb.mi/mi-var-cp.cc @@ -19,15 +19,15 @@ void reference_update_tests () int x = 167; /*: mi_create_varobj "RX" "rx" "create varobj for rx" :*/ int& rx = x; - /*: mi_varobj_update RX {RX} "update RX (1)" + /*: mi_varobj_update RX {RX} "update RX, 1" mi_check_varobj_value RX 167 "check RX: expect 167" :*/ x = 567; - /*: mi_varobj_update RX {RX} "update RX (2)" + /*: mi_varobj_update RX {RX} "update RX, 2" mi_check_varobj_value RX 567 "check RX: expect 567" :*/ x = 567; - /*: mi_varobj_update RX {} "update RX (3)" + /*: mi_varobj_update RX {} "update RX, 3" mi_delete_varobj RX "delete RX" :*/ /* Dummy assignment to keep 'x' in scope. */ diff --git a/gdb/testsuite/gdb.mi/mi-var-display.exp b/gdb/testsuite/gdb.mi/mi-var-display.exp index 560a871..b420d12 100644 --- a/gdb/testsuite/gdb.mi/mi-var-display.exp +++ b/gdb/testsuite/gdb.mi/mi-var-display.exp @@ -237,11 +237,11 @@ mi_list_varobj_children weird { # Desc: change format of weird.func_ptr and weird.func_ptr_ptr mi_gdb_test "-var-set-format weird.func_ptr hexadecimal" \ "\\^done,format=\"hexadecimal\",value=\"$hex\"" \ - "set format variable weird.func_ptr in hex (1)" + "set format variable weird.func_ptr in hex, 1" mi_gdb_test "-var-show-format weird.func_ptr" \ "\\^done,format=\"hexadecimal\"" \ - "show format variable weird.func_ptr (hex)" + "show format variable weird.func_ptr, hex" mi_gdb_test "-var-set-format weird.func_ptr_ptr hexadecimal" \ "\\^done,format=\"hexadecimal\",value=\"$hex\"" \ @@ -249,7 +249,7 @@ mi_gdb_test "-var-set-format weird.func_ptr_ptr hexadecimal" \ mi_gdb_test "-var-show-format weird.func_ptr_ptr" \ "\\^done,format=\"hexadecimal\"" \ - "show format variable weird.func_ptr_ptr (hex)" + "show format variable weird.func_ptr_ptr, hex" mi_gdb_test "-var-set-format weird.func_ptr zero-hexadecimal" \ "\\^done,format=\"zero-hexadecimal\",value=\"$hex\"" \ @@ -257,7 +257,7 @@ mi_gdb_test "-var-set-format weird.func_ptr zero-hexadecimal" \ mi_gdb_test "-var-show-format weird.func_ptr" \ "\\^done,format=\"zero-hexadecimal\"" \ - "show format variable weird.func_ptr (zhex)" + "show format variable weird.func_ptr, zhex" mi_gdb_test "-var-set-format weird.func_ptr_ptr zero-hexadecimal" \ "\\^done,format=\"zero-hexadecimal\",value=\"$hex\"" \ @@ -265,7 +265,7 @@ mi_gdb_test "-var-set-format weird.func_ptr_ptr zero-hexadecimal" \ mi_gdb_test "-var-show-format weird.func_ptr_ptr" \ "\\^done,format=\"zero-hexadecimal\"" \ - "show format variable weird.func_ptr_ptr (zhex)" + "show format variable weird.func_ptr_ptr, zhex" # Test: c_variable-6.24 # Desc: format of weird and children @@ -299,7 +299,7 @@ mi_gdb_test "-var-set-format weird.long_array natural" \ mi_gdb_test "-var-set-format weird.func_ptr hexadecimal" \ "\\^done,format=\"hexadecimal\",value=\"$hex\"" \ - "set format variable weird.func_ptr in hex (2)" + "set format variable weird.func_ptr in hex, 2" mi_gdb_test "-var-set-format weird.func_ptr_struct hexadecimal" \ "\\^done,format=\"hexadecimal\",value=\"$hex\"" \ diff --git a/gdb/testsuite/gdb.mi/mi-var-invalidate.exp b/gdb/testsuite/gdb.mi/mi-var-invalidate.exp index 7ea2d17..60e29a9 100644 --- a/gdb/testsuite/gdb.mi/mi-var-invalidate.exp +++ b/gdb/testsuite/gdb.mi/mi-var-invalidate.exp @@ -80,7 +80,7 @@ mi_gdb_test "-var-update linteger" \ mi_gdb_test "-var-info-type linteger" \ "\\^done,type=\"\"" \ - "no type for invalid variable linteger (1)" + "no type for invalid variable linteger, 1" # Check global variable is still correct. mi_gdb_test "-var-update global_simple" \ @@ -105,7 +105,7 @@ mi_gdb_test "-var-update linteger" \ mi_gdb_test "-var-info-type linteger" \ "\\^done,type=\"\"" \ - "no type for invalid variable linteger (2)" + "no type for invalid variable linteger, 2" # Check global variable are still correct. mi_gdb_test "-var-update global_simple" \ diff --git a/gdb/testsuite/gdb.mi/var-cmd.c b/gdb/testsuite/gdb.mi/var-cmd.c index 963bcd4..3aa5126 100644 --- a/gdb/testsuite/gdb.mi/var-cmd.c +++ b/gdb/testsuite/gdb.mi/var-cmd.c @@ -485,15 +485,15 @@ void do_at_tests () :*/ i++; /*: - mi_varobj_update F {F} "update F (1)" - mi_check_varobj_value F 11 "check F (1)" + mi_varobj_update F {F} "update F, 1" + mi_check_varobj_value F 11 "check F, 1" :*/ i++; { double i = 15; /*: - mi_varobj_update_with_type_change F "double" "0" "update F (2)" - mi_check_varobj_value F 15 "check F (2)" + mi_varobj_update_with_type_change F "double" "0" "update F, 2" + mi_check_varobj_value F 15 "check F, 2" :*/ i += 2.0; } @@ -506,8 +506,8 @@ void do_at_tests () } i++; /*: - mi_varobj_update_with_type_change F "int" "0" "update F (3)" - mi_check_varobj_value F 13 "check F (3)" + mi_varobj_update_with_type_change F "int" "0" "update F, 3" + mi_check_varobj_value F 13 "check F, 3" :*/ i++; do_at_tests_callee (); diff --git a/gdb/testsuite/gdb.multi/base.exp b/gdb/testsuite/gdb.multi/base.exp index db11bcd..834d961 100644 --- a/gdb/testsuite/gdb.multi/base.exp +++ b/gdb/testsuite/gdb.multi/base.exp @@ -139,14 +139,14 @@ gdb_test "list commonfun" "from hello.*" "list commonfun in hello" gdb_test "print hglob" "1" -gdb_test "print glob" "92" "print glob (${exec1})" +gdb_test "print glob" "92" "print glob, ${exec1}" gdb_test "inferior 3" ".*" "switch to inferior 3 to print globals" gdb_test "print gglob" "2" -gdb_test "print glob" "45" "print glob (${exec3})" +gdb_test "print glob" "45" "print glob, ${exec3}" gdb_test "list commonfun" "from goodbye.*" "list commonfun in goodbye" diff --git a/gdb/testsuite/gdb.multi/dummy-frame-restore.exp b/gdb/testsuite/gdb.multi/dummy-frame-restore.exp index 31d05e3..0bc5e6a 100644 --- a/gdb/testsuite/gdb.multi/dummy-frame-restore.exp +++ b/gdb/testsuite/gdb.multi/dummy-frame-restore.exp @@ -62,12 +62,12 @@ proc test { inf1 inf2 } { with_test_prefix "inf $inf1 first" { gdb_test "inferior 2" "witching to inferior 2 .*" \ - "switch to inferior 2 (1)" + "switch to inferior 2, 1" check_bt 2 "before infcall" gdb_test "p commonfun()" "Breakpoint .*The program being debugged stopped while in a function called from GDB.*" "infcall in inferior 2" gdb_test "inferior 1" "witching to inferior 1 .*" \ - "switch to inferior 1 (1)" + "switch to inferior 1, 1" check_bt 1 "before infcall" gdb_test "p commonfun()" "Breakpoint .*The program being debugged stopped while in a function called from GDB.*" "infcall in inferior 1" @@ -75,13 +75,13 @@ proc test { inf1 inf2 } { "two dummy frames" gdb_test "inferior $inf1" "witching to inferior $inf1 .*" \ - "switch to inferior $inf1 (2)" + "switch to inferior $inf1, 2" gdb_test "finish" "Run till exit from #0 commonfun .*" \ "finish in inferior $inf1" check_bt $inf1 "after infcall" gdb_test "inferior $inf2" "witching to inferior $inf2 .*" \ - "switch to inferior $inf2 (2)" + "switch to inferior $inf2, 2" gdb_test "finish" "Run till exit from #0 commonfun .*" \ "finish in inferior $inf2" check_bt $inf2 "after infcall" diff --git a/gdb/testsuite/gdb.multi/pending-bp-lib.c b/gdb/testsuite/gdb.multi/pending-bp-lib.c new file mode 100644 index 0000000..c48e7f2 --- /dev/null +++ b/gdb/testsuite/gdb.multi/pending-bp-lib.c @@ -0,0 +1,22 @@ +/* Copyright 2023-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/>. */ + +int global_var = 0; + +void +foo (int arg) +{ + global_var = arg; +} diff --git a/gdb/testsuite/gdb.multi/pending-bp.c b/gdb/testsuite/gdb.multi/pending-bp.c new file mode 100644 index 0000000..17d9181 --- /dev/null +++ b/gdb/testsuite/gdb.multi/pending-bp.c @@ -0,0 +1,66 @@ +/* Copyright 2023-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/>. */ + +#include <dlfcn.h> +#include <stdlib.h> + +void +breakpt (void) +{ + /* Nothing. */ +} + +volatile int global_counter = 0; + +volatile int call_count = 1; + +int +main (void) +{ + void *handle; + void (*func)(int); + + /* Some filler work so that we don't initially stop on the breakpt call + below. */ + ++global_counter; + + breakpt (); /* Break before open. */ + + /* Now load the shared library. */ + handle = dlopen (SHLIB_NAME, RTLD_LAZY); + if (handle == NULL) + abort (); + + breakpt (); /* Break after open. */ + + /* Find the function symbol. */ + func = (void (*)(int)) dlsym (handle, "foo"); + + for (; call_count > 0; --call_count) + { + /* Call the library function. */ + func (1); + } + + breakpt (); /* Break before close. */ + + /* Unload the shared library. */ + if (dlclose (handle) != 0) + abort (); + + breakpt (); /* Break after close. */ + + return 0; +} diff --git a/gdb/testsuite/gdb.multi/pending-bp.exp b/gdb/testsuite/gdb.multi/pending-bp.exp new file mode 100644 index 0000000..13f76f4 --- /dev/null +++ b/gdb/testsuite/gdb.multi/pending-bp.exp @@ -0,0 +1,126 @@ +# Copyright 2023-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/>. + +# Tests related to pending breakpoints in a multi-inferior environment. + +require allow_shlib_tests !use_gdb_stub + +standard_testfile + +set libname $testfile-lib +set srcfile_lib $srcdir/$subdir/$libname.c +set binfile_lib [standard_output_file $libname.so] + +if { [gdb_compile_shlib $srcfile_lib $binfile_lib {}] != "" } { + untested "failed to compile shared library 1" + return -1 +} + +set binfile_lib_target [gdb_download_shlib $binfile_lib] + +if { [build_executable "failed to prepare" $testfile $srcfile \ + [list debug \ + additional_flags=-DSHLIB_NAME=\"$binfile_lib_target\" \ + shlib_load]] } { + return -1 +} + +# Start two inferiors, both running the same test binary. The arguments +# INF_1_STOP and INF_2_STOP are source code patterns that are passed to +# gdb_get_line_number to figure out where each inferior should be stopped. +# +# This proc does a clean_restart and leaves inferior 2 selected. Also the +# 'breakpoint pending' flag is enabled, so pending breakpoints can be created +# without GDB prompting the user. +proc do_test_setup { inf_1_stop inf_2_stop } { + clean_restart ${::binfile} + + gdb_locate_shlib $::binfile_lib + + if {![runto_main]} { + return false + } + + gdb_breakpoint [gdb_get_line_number ${inf_1_stop}] temporary + gdb_continue_to_breakpoint "move inferior 1 into position" + + gdb_test "add-inferior -exec ${::binfile}" \ + "Added inferior 2.*" "add inferior 2" + gdb_test "inferior 2" "Switching to inferior 2 .*" "switch to inferior 2" + + if {![runto_main]} { + return false + } + + gdb_breakpoint [gdb_get_line_number ${inf_2_stop}] temporary + gdb_continue_to_breakpoint "move inferior 2 into position" + + gdb_test_no_output "set breakpoint pending on" + + return true +} + +# Check that when a breakpoint is in the pending state, but that breakpoint +# does have some locations (those locations themselves are pending), GDB +# doesn't display the inferior list in the 'info breakpoints' output. +proc_with_prefix test_no_inf_display {} { + do_test_setup "Break before open" "Break before open" + + # Create a breakpoint on 'foo'. As the shared library (that + # contains foo) has not been loaded into any inferior yet, then + # there will be no locations and the breakpoint will be created + # pending. Pass the 'allow-pending' flag so the gdb_breakpoint + # correctly expects the new breakpoint to be pending. + gdb_breakpoint "foo" allow-pending + set bpnum [get_integer_valueof "\$bpnum" "*INVALID*" \ + "get foo breakpoint number"] + + # Check the 'info breakpoints' output; the breakpoint is pending with + # no 'inf X' appearing at the end of the line. + gdb_test "info breakpoint $bpnum" \ + "$bpnum\\s+breakpoint\\s+keep\\s+y\\s+<PENDING>\\s+foo" \ + "check info bp before locations have been created" + + # Now select inferior 1 and allow the inferior to run forward to the + # point where a breakpoint location for foo will have been created. + gdb_test "inferior 1" "Switching to inferior 1 .*" + gdb_breakpoint [gdb_get_line_number "Break after open"] temporary + gdb_continue_to_breakpoint \ + "move inferior 1 until a location has been added" + + # Check the 'info breakpoints' output. Notice we display the inferior + # list at the end of the breakpoint line. + gdb_test "info breakpoint $bpnum" \ + "$bpnum\\s+breakpoint\\s+keep\\s+y\\s+$::hex\\s+<foo\[^>\]*>\\s+inf 1" \ + "check info breakpoints while breakpoint is inserted" + + # Continue inferior 1 until the shared library has been unloaded. The + # breakpoint on 'foo' will return to the pending state. We will need to + # 'continue' twice as the first time will hit the 'foo' breakpoint. + gdb_breakpoint [gdb_get_line_number "Break after close"] temporary + gdb_continue_to_breakpoint "hit the breakpoint in foo" + gdb_continue_to_breakpoint "after close library" + + # Check the 'info breakpoints' output, check there is no 'inf 1' at the + # end of the breakpoint line. + gdb_test "info breakpoint $bpnum" \ + [multi_line \ + "$bpnum\\s+breakpoint\\s+keep\\s+y\\s+<PENDING>\\s+foo" \ + "\\s+breakpoint already hit 1 time"] \ + "check info breakpoints while breakpoint is pending" +} + +# Run all the tests. +test_no_inf_display diff --git a/gdb/testsuite/gdb.opt/inline-bt.exp b/gdb/testsuite/gdb.opt/inline-bt.exp index 7220ec7..9e1fb19 100644 --- a/gdb/testsuite/gdb.opt/inline-bt.exp +++ b/gdb/testsuite/gdb.opt/inline-bt.exp @@ -32,23 +32,23 @@ if { [skip_inline_frame_tests] } { set line1 [gdb_get_line_number "set breakpoint 1 here" ${srcfile2}] gdb_breakpoint $srcfile2:$line1 -gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (1)" -gdb_test "backtrace" "#0 bar.*#1 .*main.*" "backtrace from bar (1)" +gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar, 1" +gdb_test "backtrace" "#0 bar.*#1 .*main.*" "backtrace from bar, 1" gdb_test "info frame" ".*called by frame.*" "bar not inlined" -gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (2)" +gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar, 2" gdb_test "backtrace" "#0 bar.*#1 .*func1.*#2 .*main.*" \ - "backtrace from bar (2)" -gdb_test "up" "#1 .*func1.*" "up from bar (2)" -gdb_test "info frame" ".*inlined into frame.*" "func1 inlined (2)" + "backtrace from bar, 2" +gdb_test "up" "#1 .*func1.*" "up from bar, 2" +gdb_test "info frame" ".*inlined into frame.*" "func1 inlined, 2" -gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (3)" +gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar, 3" gdb_test "backtrace" "#0 bar.*#1 .*func1.*#2 .*func2.*#3 .*main.*" \ - "backtrace from bar (3)" -gdb_test "up" "#1 .*func1.*" "up from bar (3)" -gdb_test "info frame" ".*inlined into frame.*" "func1 inlined (3)" -gdb_test "up" "#2 .*func2.*" "up from func1 (3)" -gdb_test "info frame" ".*inlined into frame.*" "func2 inlined (3)" + "backtrace from bar, 3" +gdb_test "up" "#1 .*func1.*" "up from bar, 3" +gdb_test "info frame" ".*inlined into frame.*" "func1 inlined, 3" +gdb_test "up" "#2 .*func2.*" "up from func1, 3" +gdb_test "info frame" ".*inlined into frame.*" "func2 inlined, 3" # A regression test for having a backtrace limit that forces unwinding # to stop after an inline frame. GDB needs to compute the frame_id of @@ -61,7 +61,7 @@ gdb_test "info frame" ".*inlined into frame.*" "func2 inlined (3)" gdb_test_no_output "set backtrace limit 2" # Force flushing the frame cache. gdb_test "maint flush register-cache" "Register cache flushed." -gdb_test "up" "#1 .*func1.*" "up from bar (4)" +gdb_test "up" "#1 .*func1.*" "up from bar, 4" gdb_test "info frame" ".*in func1.*" "info frame still works" # Verify the user visible limit works as expected. gdb_test "up" "Initial frame selected; you cannot go up." "up hits limit" diff --git a/gdb/testsuite/gdb.opt/inline-cmds.exp b/gdb/testsuite/gdb.opt/inline-cmds.exp index bd645e5..7a9f2e0 100644 --- a/gdb/testsuite/gdb.opt/inline-cmds.exp +++ b/gdb/testsuite/gdb.opt/inline-cmds.exp @@ -40,19 +40,19 @@ gdb_breakpoint $srcfile2:$line1 set line2 [gdb_get_line_number "set breakpoint 2 here" ${srcfile2}] gdb_breakpoint $srcfile2:$line2 -gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (1)" +gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar, 1" gdb_test "backtrace" "#0 bar.*#1 .*func1.*#2 .*main.*" \ - "backtrace from bar (1)" -gdb_test "up" "#1 .*func1.*" "up from bar (1)" -gdb_test "info frame" ".*inlined into frame.*" "func1 inlined (1)" + "backtrace from bar, 1" +gdb_test "up" "#1 .*func1.*" "up from bar, 1" +gdb_test "info frame" ".*inlined into frame.*" "func1 inlined, 1" -gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (2)" +gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar, 2" gdb_test "backtrace" "#0 bar.*#1 .*func1.*#2 .*func2.*#3 .*main.*" \ "backtrace from bar (2)" -gdb_test "up" "#1 .*func1.*" "up from bar (2)" -gdb_test "info frame" ".*inlined into frame.*" "func1 inlined (2)" -gdb_test "up" "#2 .*func2.*" "up from func1 (2)" -gdb_test "info frame" ".*inlined into frame.*" "func2 inlined (2)" +gdb_test "up" "#1 .*func1.*" "up from bar, 2" +gdb_test "info frame" ".*inlined into frame.*" "func1 inlined, 2" +gdb_test "up" "#2 .*func2.*" "up from func1, 2" +gdb_test "info frame" ".*inlined into frame.*" "func2 inlined, 2" gdb_test "continue" ".*set breakpoint 2 here.*" "continue to marker" gdb_test "backtrace" "#0 marker.*#1 .*main.*" "backtrace from marker" diff --git a/gdb/testsuite/gdb.python/py-cmd.exp b/gdb/testsuite/gdb.python/py-cmd.exp index 82cb4cb..b083a80 100644 --- a/gdb/testsuite/gdb.python/py-cmd.exp +++ b/gdb/testsuite/gdb.python/py-cmd.exp @@ -128,19 +128,19 @@ gdb_test "test_error_cmd ugh" "you lose!" "call error command" gdb_test "python print (gdb.string_to_argv (\"1 2 3\"))" \ {\['1', '2', '3'\]} \ - "string_to_argv (\"1 2 3\")" + "string_to_argv (\"1 2 3\"), case 1" gdb_test "python print (gdb.string_to_argv (\"'1 2' 3\"))" \ {\['1 2', '3'\]} \ - "string_to_argv (\"'1 2' 3\")" + "string_to_argv (\"'1 2' 3\"), case 2" gdb_test "python print (gdb.string_to_argv ('\"1 2\" 3'))" \ {\['1 2', '3'\]} \ - "string_to_argv ('\"1 2\" 3')" + "string_to_argv ('\"1 2\" 3'), case 3" gdb_test "python print (gdb.string_to_argv ('1\\ 2 3'))" \ {\['1 2', '3'\]} \ - "string_to_argv ('1\\ 2 3')" + "string_to_argv ('1\\ 2 3'), case 4" # Test user-defined python commands. gdb_test_multiline "input simple user-defined command" \ diff --git a/gdb/testsuite/gdb.python/py-disasm-exec.exp b/gdb/testsuite/gdb.python/py-disasm-exec.exp new file mode 100644 index 0000000..546c4b8 --- /dev/null +++ b/gdb/testsuite/gdb.python/py-disasm-exec.exp @@ -0,0 +1,21 @@ +# Copyright (C) 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/>. + +# This file is part of the GDB testsuite. It validates the Python +# disassembler API. + +set kind exec + +source $srcdir/$subdir/py-disasm.exp.tcl diff --git a/gdb/testsuite/gdb.python/py-disasm-obj.exp b/gdb/testsuite/gdb.python/py-disasm-obj.exp new file mode 100644 index 0000000..37ff965 --- /dev/null +++ b/gdb/testsuite/gdb.python/py-disasm-obj.exp @@ -0,0 +1,21 @@ +# Copyright (C) 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/>. + +# This file is part of the GDB testsuite. It validates the Python +# disassembler API. + +set kind obj + +source $srcdir/$subdir/py-disasm.exp.tcl diff --git a/gdb/testsuite/gdb.python/py-disasm.exp b/gdb/testsuite/gdb.python/py-disasm.exp.tcl index 5d7d922..8ed634e 100644 --- a/gdb/testsuite/gdb.python/py-disasm.exp +++ b/gdb/testsuite/gdb.python/py-disasm.exp.tcl @@ -20,26 +20,54 @@ load_lib gdb-python.exp require allow_python_tests -standard_testfile +standard_testfile py-disasm.c -if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} "debug"] } { - return -1 -} +if { $kind == "obj" } { + + set obj [standard_output_file ${gdb_test_file_name}.o] + + if { [gdb_compile "$srcdir/$subdir/$srcfile" $obj object "debug"] != "" } { + untested "failed to compile object file [file tail $obj]" + return -1 + } + + clean_restart $obj + +} else { + + if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } { + return -1 + } + + if { ![runto_main] } { + fail "can't run to main" + return 0 + } -if {![runto_main]} { - fail "can't run to main" - return 0 } -set pyfile [gdb_remote_download host ${srcdir}/${subdir}/${testfile}.py] +set pyfile [gdb_remote_download host ${srcdir}/${subdir}/py-disasm.py] gdb_test "source ${pyfile}" "Python script imported" \ "import python scripts" -gdb_breakpoint [gdb_get_line_number "Break here."] -gdb_continue_to_breakpoint "Break here." +set line [gdb_get_line_number "Break here."] -set curr_pc [get_valueof "/x" "\$pc" "*unknown*"] +if { $kind == "obj" } { + set curr_pc "*unknown*" + set line [gdb_get_line_number "Break here."] + gdb_test_multiple "info line $line" "" { + -re -wrap "starts at address ($hex) \[^\r\n\]*" { + set curr_pc $expect_out(1,string) + pass $gdb_test_name + } + } +} else { + gdb_breakpoint $line + gdb_continue_to_breakpoint "Break here." + + set curr_pc [get_valueof "/x" "\$pc" "*unknown*"] +} gdb_test_no_output "python current_pc = ${curr_pc}" @@ -67,7 +95,11 @@ proc py_remove_all_disassemblers {} { # Python disassembler API. set nop "(nop|nop\t0|[string_to_regexp nop\t{0}])" set unknown_error_pattern "unknown disassembler error \\(error = -1\\)" -set addr_pattern "\r\n=> ${curr_pc_pattern} <\[^>\]+>:\\s+" +if { $kind == "obj" } { + set addr_pattern "\r\n ${curr_pc_pattern} <\[^>\]+>:\\s+" +} else { + set addr_pattern "\r\n=> ${curr_pc_pattern} <\[^>\]+>:\\s+" +} set base_pattern "${addr_pattern}${nop}" # Helper proc to format a Python exception of TYPE with MSG. diff --git a/gdb/testsuite/gdb.python/py-disasm.py b/gdb/testsuite/gdb.python/py-disasm.py index 2741fdb..f105657 100644 --- a/gdb/testsuite/gdb.python/py-disasm.py +++ b/gdb/testsuite/gdb.python/py-disasm.py @@ -252,7 +252,7 @@ class MemoryErrorEarlyDisassembler(TestDisassembler): def disassemble(self, info): tag = "## FAIL" try: - info.read_memory(1, -info.address + 2) + info.read_memory(1, -info.address - 1) except gdb.MemoryError: tag = "## AFTER ERROR" result = builtin_disassemble_wrapper(info) @@ -267,7 +267,7 @@ class MemoryErrorLateDisassembler(TestDisassembler): def disassemble(self, info): result = builtin_disassemble_wrapper(info) # The following read will throw an error. - info.read_memory(1, -info.address + 2) + info.read_memory(1, -info.address - 1) return DisassemblerResult(1, "BAD") @@ -276,9 +276,9 @@ class RethrowMemoryErrorDisassembler(TestDisassembler): def disassemble(self, info): try: - info.read_memory(1, -info.address + 2) + info.read_memory(1, -info.address - 1) except gdb.MemoryError as e: - raise gdb.MemoryError("cannot read code at address 0x2") + raise gdb.MemoryError("cannot read code at address -1") return DisassemblerResult(1, "BAD") diff --git a/gdb/testsuite/gdb.python/py-format-string.exp b/gdb/testsuite/gdb.python/py-format-string.exp index 0c70ad5..9209213 100644 --- a/gdb/testsuite/gdb.python/py-format-string.exp +++ b/gdb/testsuite/gdb.python/py-format-string.exp @@ -1104,10 +1104,16 @@ proc_with_prefix test_invalid_args {} { "12" \ "TypeError.*: format_string\\(\\) takes 0 positional arguments but 1 were given.*" + # For python <= 3.12. + set re1 \ + "TypeError.*: 'invalid' is an invalid keyword argument for this function" + # For python >= 3.13. + set re2 \ + "TypeError.*: this function got an unexpected keyword argument 'invalid'" check_format_string \ "a_point_t" \ "invalid=True" \ - "TypeError.*: 'invalid' is an invalid keyword argument for this function.*" + "($re1|$re2).*" check_format_string \ "a_point_t" \ diff --git a/gdb/testsuite/gdb.python/py-frame.exp b/gdb/testsuite/gdb.python/py-frame.exp index 8f776eb..0f1528e 100644 --- a/gdb/testsuite/gdb.python/py-frame.exp +++ b/gdb/testsuite/gdb.python/py-frame.exp @@ -127,10 +127,10 @@ gdb_test "python print (f1 == gdb.newest_frame())" False \ gdb_test "python print (bframe == gdb.newest_frame())" True \ "newest frame -vs- newest frame" -gdb_test "python print ('result = %s' % (f0 == f1))" " = False" "test equality comparison (false)" -gdb_test "python print ('result = %s' % (f0 == f0))" " = True" "test equality comparison (true)" -gdb_test "python print ('result = %s' % (f0 != f1))" " = True" "test inequality comparison (true)" -gdb_test "python print ('result = %s' % (f0 != f0))" " = False" "test inequality comparison (false)" +gdb_test "python print ('result = %s' % (f0 == f1))" " = False" "test equality comparison, false" +gdb_test "python print ('result = %s' % (f0 == f0))" " = True" "test equality comparison, true" +gdb_test "python print ('result = %s' % (f0 != f1))" " = True" "test inequality comparison, true" +gdb_test "python print ('result = %s' % (f0 != f0))" " = False" "test inequality comparison, false" gdb_test "python print ('result = %s' % f0.is_valid ())" " = True" "test Frame.is_valid" gdb_test "python print ('result = %s' % f0.name ())" " = f2" "test Frame.name" gdb_test "python print ('result = %s' % (f0.type () == gdb.NORMAL_FRAME))" " = True" "test Frame.type" diff --git a/gdb/testsuite/gdb.python/py-framefilter-invalidarg.exp b/gdb/testsuite/gdb.python/py-framefilter-invalidarg.exp index 481eead..0e78f8d 100644 --- a/gdb/testsuite/gdb.python/py-framefilter-invalidarg.exp +++ b/gdb/testsuite/gdb.python/py-framefilter-invalidarg.exp @@ -58,4 +58,4 @@ set remote_python_file [gdb_remote_download host \ ${srcdir}/${subdir}/${testfile}.py] gdb_test_no_output "source ${remote_python_file}" "load python file" -gdb_test "bt" "niam \\(argc=<error reading variable: dwarf expression stack underflow>, argv=0x\[0-9a-f\]+\\) at py-framefilter-invalidarg.c:\[0-9\]+" "bt full with filters" +gdb_test "bt" "niam \\(argc=<error reading variable: dwarf expression stack underflow>, argv=0x\[0-9a-f\]+\\) at \[^\r\n\]*py-framefilter-invalidarg.c:\[0-9\]+" "bt full with filters" diff --git a/gdb/testsuite/gdb.python/py-missing-debug.exp b/gdb/testsuite/gdb.python/py-missing-debug.exp index d1eef34..dfc0a46 100644 --- a/gdb/testsuite/gdb.python/py-missing-debug.exp +++ b/gdb/testsuite/gdb.python/py-missing-debug.exp @@ -19,7 +19,8 @@ require allow_python_tests standard_testfile -if {[build_executable "failed to prepare" ${testfile} ${srcfile}]} { +if {[build_executable "failed to prepare" ${testfile} ${srcfile} \ + {debug build-id}]} { return -1 } diff --git a/gdb/testsuite/gdb.python/py-progspace-events.exp b/gdb/testsuite/gdb.python/py-progspace-events.exp index 95e4ca8..9dfc757 100644 --- a/gdb/testsuite/gdb.python/py-progspace-events.exp +++ b/gdb/testsuite/gdb.python/py-progspace-events.exp @@ -79,37 +79,16 @@ gdb_test "continue" \ "\\\[Inferior $decimal \[^\r\n\]+ exited normally\\\]"] \ "continue until inferior 2 exits" -gdb_test "inferior 1" "\\\[Switching to inferior 1 .*" - -# Step the inferior. During this process GDB will prune the now +# Switch to inferior 1. During this process GDB will prune the now # defunct inferior, which deletes its program space, which should # trigger the FreeProgspaceEvent. # -# However, there is a slight problem. When the target is remote, and -# GDB is accessing files using remote fileio, then GDB will attempt to -# prune the inferior at a point in time when the remote target is -# waiting for a stop reply. Pruning an inferior causes GDB to close -# files associated with that inferior. -# -# In non-async mode we can't send fileio packets while waiting for a -# stop reply, so the attempts to close files fails, and this shows up -# as an error. -# -# As this error has nothing to do with the feature being tested here, -# we just accept the error message, the important part is the -# 'FreeProgspaceEvent' string, so long as that appears (just once) -# then the test is a success. -set warning_msg \ - [multi_line \ - "warning: cannot close \"\[^\r\n\]+\": Cannot execute this command while the target is running\\." \ - "Use the \"interrupt\" command to stop the target" \ - "and then try again\\."] -gdb_test "step" \ +gdb_test "inferior 1" \ [multi_line \ - "^FreeProgspaceEvent.*: <gdb.Progspace object at $hex>(?:\r\n$warning_msg)*" \ - "do_parent_stuff \\(\\) at \[^\r\n\]+" \ - "$decimal\\s+\[^\r\n\]+"] + "\\\[Switching to inferior 1 .*" \ + ".*" \ + "FreeProgspaceEvent.*: <gdb.Progspace object at $hex>"] # Let this inferior run to completion. gdb_continue_to_end diff --git a/gdb/testsuite/gdb.python/py-progspace.exp b/gdb/testsuite/gdb.python/py-progspace.exp index 0ae5b56..fe46537 100644 --- a/gdb/testsuite/gdb.python/py-progspace.exp +++ b/gdb/testsuite/gdb.python/py-progspace.exp @@ -42,7 +42,7 @@ gdb_py_test_silent_cmd "python progspace = gdb.current_progspace()" \ "Get current progspace" 1 gdb_test "python print (progspace.filename)" "py-progspace" \ - "current progspace filename (py-progspace)" + "current progspace filename, py-progspace" gdb_test "python print (gdb.current_progspace().symbol_file)" \ "<gdb.Objfile filename=.*/py-progspace>" \ diff --git a/gdb/testsuite/gdb.python/py-record-btrace.exp b/gdb/testsuite/gdb.python/py-record-btrace.exp index fba0b98..b035e14 100644 --- a/gdb/testsuite/gdb.python/py-record-btrace.exp +++ b/gdb/testsuite/gdb.python/py-record-btrace.exp @@ -198,3 +198,14 @@ with_test_prefix "level" { gdb_test "python print(gdb.current_recording().function_call_history\[0\].level)" "1" gdb_test "python print(gdb.current_recording().function_call_history\[1\].level)" "0" } + +# Note: GDB can incrementally add to the recording from the raw trace data. +# After a clear(), GDB might not have all the raw trace data available in its +# buffer to recreate the full recording it had before the clear(). +# So, do this testing last to avoid disturbing subsequent tests. +with_test_prefix "clear" { + gdb_test_no_output "python r.clear()" + gdb_test "python insn = r.instruction_history" + gdb_test_no_output "python i = insn\[0\]" + gdb_test "python print(i.size)" "$decimal" +} diff --git a/gdb/testsuite/gdb.python/py-type.exp b/gdb/testsuite/gdb.python/py-type.exp index e524959..7e469c9 100644 --- a/gdb/testsuite/gdb.python/py-type.exp +++ b/gdb/testsuite/gdb.python/py-type.exp @@ -57,10 +57,10 @@ proc test_fields {lang} { if {$lang == "c++"} { # Test usage with a class - gdb_py_test_silent_cmd "print (c)" "print value (c)" 1 + gdb_py_test_silent_cmd "print (c)" "print value(c)" 1 gdb_py_test_silent_cmd "python c = gdb.history (0)" "get value (c) from history" 1 gdb_py_test_silent_cmd "python fields = c.type.fields()" "get fields from c.type" 1 - gdb_test "python print (len(fields))" "2" "check number of fields (c)" + gdb_test "python print (len(fields))" "2" "check number of fields, c" gdb_test "python print (fields\[0\].name)" "c" "check class field c name" gdb_test "python print (fields\[1\].name)" "d" "check class field d name" @@ -94,12 +94,12 @@ proc test_fields {lang} { } # Test normal fields usage in structs. - gdb_py_test_silent_cmd "print (st)" "print value (st)" 1 + gdb_py_test_silent_cmd "print (st)" "print value(st)" 1 gdb_py_test_silent_cmd "python st = gdb.history (0)" "get value (st) from history" 1 gdb_py_test_silent_cmd "python fields = st.type.fields()" "get fields from st.type" 1 gdb_test "python print (st.type.objfile.filename == gdb.current_progspace ().filename)" "True" \ "check type.objfile" - gdb_test "python print (len(fields))" "2" "check number of fields (st)" + gdb_test "python print (len(fields))" "2" "check number of fields, st" gdb_test "python print (fields\[0\].name)" "a" "check structure field a name" gdb_test "python print (fields\[1\].name)" "b" "check structure field b name" @@ -118,7 +118,7 @@ proc test_fields {lang} { "Check that dir includes name" # Test Python mapping behavior of gdb.Type for structs/classes - gdb_test "python print (len(st.type))" "2" "check number of fields (st.type)" + gdb_test "python print (len(st.type))" "2" "check number of fields, st.type" gdb_test "python print (st.type\['a'\].name)" "a" "check fields lookup by name" gdb_test "python print (\[v.bitpos for v in st.type.itervalues()\])" {\[0L?, 32L?\]} "Check fields iteration over values" gdb_test "python print (\[(n, v.bitpos) for (n, v) in st.type.items()\])" {\[\('a', 0L?\), \('b', 32L?\)\]} "Check fields items list" @@ -136,7 +136,7 @@ proc test_fields {lang} { gdb_test "python print (not not st.type\['a'\].type)" "True" # Test regression PR python/10805 - gdb_py_test_silent_cmd "print (ar)" "print value (ar)" 1 + gdb_py_test_silent_cmd "print (ar)" "print value(ar)" 1 gdb_py_test_silent_cmd "python ar = gdb.history (0)" "get value (ar) from history" 1 gdb_test "python fields = ar.type.fields()" gdb_test "python print (len(fields))" "1" "check the number of fields" @@ -153,10 +153,10 @@ proc test_fields {lang} { # Test gdb.Type.vector. # Note: vectors cast differently than arrays. Here ar[0] is replicated # for the size of the vector. - gdb_py_test_silent_cmd "print (vec_data_1)" "print value (vec_data_1)" 1 + gdb_py_test_silent_cmd "print (vec_data_1)" "print value(vec_data_1)" 1 gdb_py_test_silent_cmd "python vec_data_1 = gdb.history (0)" "get value (vec_data_1) from history" 1 - gdb_py_test_silent_cmd "print (vec_data_2)" "print value (vec_data_2)" 1 + gdb_py_test_silent_cmd "print (vec_data_2)" "print value(vec_data_2)" 1 gdb_py_test_silent_cmd "python vec_data_2 = gdb.history (0)" "get value (vec_data_2) from history" 1 gdb_py_test_silent_cmd "python vec1 = vec_data_1.cast(ar\[0\].type.vector(1))" "set vec1" 1 @@ -179,7 +179,7 @@ proc test_fields {lang} { proc test_enums {} { with_test_prefix "test_enum" { - gdb_py_test_silent_cmd "print (e)" "print value (e)" 1 + gdb_py_test_silent_cmd "print (e)" "print value(e)" 1 gdb_py_test_silent_cmd "python (e) = gdb.history (0)" "get value (e) from history" 1 gdb_py_test_silent_cmd "python fields = e.type.fields()" "extract type fields from e" 1 gdb_test "python print (len(fields))" "3" "check the number of enum fields" @@ -188,8 +188,8 @@ proc test_enums {} { # Ditto but by mapping operations gdb_test "python print (len(e.type))" "3" "check the number of type fields" - gdb_test "python print (e.type\['v1'\].name)" "v1" "check enum field lookup by name (v1)" - gdb_test "python print (e.type\['v3'\].name)" "v3" "check enum field lookup by name (v3)" + gdb_test "python print (e.type\['v1'\].name)" "v1" "check enum field lookup by name, v1" + gdb_test "python print (e.type\['v3'\].name)" "v3" "check enum field lookup by name, v3" gdb_test "python print (\[v.enumval for v in e.type.itervalues()\])" {\[0L?, 1L?, 2L?\]} "Check num fields iteration over values" gdb_test "python print (\[(n, v.enumval) for (n, v) in e.type.items()\])" {\[\('v1', 0L?\), \('v2', 1L?\), \('v3', 2L?\)\]} "Check enum fields items list" } @@ -197,12 +197,12 @@ proc test_enums {} { proc test_base_class {} { with_test_prefix "test_base_class" { - gdb_py_test_silent_cmd "print (d)" "print value (d)" 1 + gdb_py_test_silent_cmd "print (d)" "print value(d)" 1 gdb_py_test_silent_cmd "python d = gdb.history (0)" "get value (d) from history" 1 gdb_py_test_silent_cmd "python fields = d.type.fields()" "extract type fields from d" 1 gdb_test "python print (len(fields))" "3" "check the number of fields" - gdb_test "python print (fields\[0\].is_base_class)" "True" "check base class (fields\[0\])" - gdb_test "python print (fields\[1\].is_base_class)" "False" "check base class (fields\[1\])" + gdb_test "python print (fields\[0\].is_base_class)" "True" {check base class, fields[0]} + gdb_test "python print (fields\[1\].is_base_class)" "False" {check base class, fields[1]} } } @@ -210,7 +210,7 @@ proc test_range {} { with_test_prefix "test_range" { with_test_prefix "on ranged value" { # Test a valid range request. - gdb_py_test_silent_cmd "print (ar)" "print value (ar)" 1 + gdb_py_test_silent_cmd "print (ar)" "print value(ar)" 1 gdb_py_test_silent_cmd "python ar = gdb.history (0)" "get value (ar) from history" 1 gdb_test "python print (len(ar.type.range()))" "2" "check correct tuple length" gdb_test "python print (ar.type.range()\[0\])" "0" "check range low bound" @@ -219,7 +219,7 @@ proc test_range {} { with_test_prefix "on ranged type" { # Test a range request on a ranged type. - gdb_py_test_silent_cmd "print (ar)" "print value (ar)" 1 + gdb_py_test_silent_cmd "print (ar)" "print value(ar)" 1 gdb_py_test_silent_cmd "python ar = gdb.history (0)" "get value (ar) from history" 1 gdb_py_test_silent_cmd "python fields = ar.type.fields()" "get fields" 1 gdb_test "python print (fields\[0\].type.range()\[0\])" "0" "check range low bound" @@ -228,7 +228,7 @@ proc test_range {} { with_test_prefix "on unranged value" { # Test where a range does not exist. - gdb_py_test_silent_cmd "print (st)" "print value (st)" 1 + gdb_py_test_silent_cmd "print (st)" "print value(st)" 1 gdb_py_test_silent_cmd "python st = gdb.history (0)" "get value (st) from history" 1 gdb_test "python print (st.type.range())" "RuntimeError.*: This type does not have a range.*" "check range for non ranged type." } diff --git a/gdb/testsuite/gdb.python/py-xmethods.exp b/gdb/testsuite/gdb.python/py-xmethods.exp index 1ff7067..55ec66c 100644 --- a/gdb/testsuite/gdb.python/py-xmethods.exp +++ b/gdb/testsuite/gdb.python/py-xmethods.exp @@ -179,8 +179,8 @@ gdb_test_no_output "python gdb.set_parameter('max-value-size', 16)" gdb_test "p a1.getarray()" \ "From Python <A_getarray>.*value requires $decimal bytes,\ which is more than max-value-size" \ - "after: a1.getarray (max-value-size)" + "after: a1.getarray, max-value-size" gdb_test "p b1.getarray()" \ "From Python <B_getarray>.*value requires $decimal bytes,\ which is more than max-value-size" \ - "after: b1.getarray (max-value-size)" + "after: b1.getarray, max-value-size" diff --git a/gdb/testsuite/gdb.reverse/step-precsave.exp b/gdb/testsuite/gdb.reverse/step-precsave.exp index d937763..9ae67b3 100644 --- a/gdb/testsuite/gdb.reverse/step-precsave.exp +++ b/gdb/testsuite/gdb.reverse/step-precsave.exp @@ -69,6 +69,8 @@ with_timeout_factor 10 { gdb_test "kill" "" "kill process, prepare to debug log file" \ "Kill the program being debugged\\? \\(y or n\\) " "y" +clean_restart ${binfile} + gdb_test "record restore $precsave" \ "Restored records from core file .*" \ "reload core file" diff --git a/gdb/testsuite/gdb.server/build-id-seqno.c b/gdb/testsuite/gdb.server/build-id-seqno.c new file mode 100644 index 0000000..e2119ba7 --- /dev/null +++ b/gdb/testsuite/gdb.server/build-id-seqno.c @@ -0,0 +1,22 @@ +/* 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/>. */ + +int +main (void) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.server/build-id-seqno.exp b/gdb/testsuite/gdb.server/build-id-seqno.exp new file mode 100644 index 0000000..7db1f11 --- /dev/null +++ b/gdb/testsuite/gdb.server/build-id-seqno.exp @@ -0,0 +1,200 @@ +# 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/>. + +# Setup a .build-id/ based debug directory containing multiple entries +# for the same build-id, with each entry given a different sequence +# number. +# +# Ensure that GDB will scan over broken symlinks for the same build-id +# (but different sequence number) to find later working symlinks. +# +# This test places the build-id files within a directory next to where +# gdbserver is started, and places a relative address in the +# debug-file-directory, in this way we require GDB to find the debug +# information via gdbserver. + +require {!is_remote host} + +load_lib gdbserver-support.exp + +require allow_gdbserver_tests + +standard_testfile + +if {[build_executable "failed to prepare" $testfile $srcfile] == -1} { + return -1 +} + +# Split out BINFILE.debug. Remove debug from BINFILE. +if {[gdb_gnu_strip_debug $binfile] != 0} { + return -1 +} + +# Get the '.build-id/xx/xxx...xxx' part of the filename. +set build_id_filename [build_id_debug_filename_get $binfile] + +# Hide (rename) BINFILE.debug, this should ensure GDB can't find it +# directly but needs to look for the build-id based file in the debug +# directory. +set hidden_debuginfo [standard_output_file "hidden_$testfile.debug"] +remote_exec build "mv ${binfile}.debug $hidden_debuginfo" + +# A filename that doesn't exist. Some symlinks will point at this +# file. +set missing_debuginfo "missing_debuginfo" + +# Helper called from gdb_finish when the 'target' is remote. Ensure the +# debug directory we create is deleted. +proc cleanup_remote_target {} { + remote_exec target "rm -fr debug/" +} + +if { ![is_remote target] } { + set gdbserver_dir [standard_output_file "gdbserver-dir"]/ +} else { + lappend gdb_finish_hooks cleanup_remote_target + set gdbserver_dir "" +} + +# Copy files to the target (if needed). +set target_binfile [gdb_remote_download target $binfile] +set target_debuginfo [gdb_remote_download target $hidden_debuginfo] + +# Setup the debug information on the target. +set debugdir "${gdbserver_dir}debug" +remote_exec target \ + "mkdir -p $debugdir/[file dirname $build_id_filename]" +remote_exec target \ + "ln -sf $target_debuginfo $debugdir/$build_id_filename" + +# Start GDB and load global BINFILE. If DEBUGINFO_FILE is not the +# empty string then this contains the '.build-id/xx/xxx....xxxx' part +# of the filename which we expect GDB to read from the remote target. +# If DEBUGINFO_FILE is the empty string then we don't expect GDB to +# find any debug information. +proc load_binfile_check_debug_is_found { debuginfo_file testname } { + with_test_prefix "$testname" { + with_timeout_factor 5 { + # Probing for .build-id based debug files on remote + # targets uses the vFile:stat packet by default, though + # there is a work around that avoids this which can be + # used if GDB is connected to an older gdbserver without + # 'stat' support. + # + # Check the work around works by disabling use of the + # vFile:stat packet. + foreach_with_prefix stat_pkt {auto off} { + clean_restart + + gdb_test_no_output "set debug-file-directory debug" \ + "set debug-file-directory" + + gdb_test_no_output "set sysroot target:" + + gdb_test "set remote hostio-stat-packet $stat_pkt" + + # Make sure we're disconnected, in case we're testing with an + # extended-remote board, therefore already connected. + gdb_test "disconnect" ".*" + + # Start gdbserver. This needs to be done after starting GDB. When + # gdbserver is running local to GDB, start gdbserver in a sub-directory, + # this prevents GDB from finding the debug information itself. + if { ![is_remote target] } { + with_cwd $::gdbserver_dir { + set res [gdbserver_start "" $::target_binfile] + } + } else { + set res [gdbserver_start "" $::target_binfile] + } + set gdbserver_protocol [lindex $res 0] + set gdbserver_gdbport [lindex $res 1] + + # Connect to gdbserver. The output will be placed into the global + # GDB_TARGET_REMOTE_CMD_MSG, and we'll match against this below. + gdb_assert {[gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport] == 0} \ + "connect to gdbserver" + + if { $debuginfo_file ne "" } { + gdb_assert { [regexp "Reading symbols from target:debug/[string_to_regexp $debuginfo_file]\\.\\.\\." \ + $::gdb_target_remote_cmd_msg] } \ + "debuginfo was read via build-id" + gdb_assert { [regexp "Reading debug/[string_to_regexp $debuginfo_file] from remote target\\.\\.\\." \ + $::gdb_target_remote_cmd_msg] } \ + "debuginfo was read from remote target" + } else { + gdb_assert { [regexp "\\(No debugging symbols found in \[^\r\n\]+/$::testfile\\)" \ + $::gdb_target_remote_cmd_msg] } + } + } + } + } +} + +# Return a copy of FILENAME, which should end '.debug', with NUMBER +# added, e.g. add_seqno 1 "foo.debug" --> "foo.1.debug". +proc add_seqno { number filename } { + return [regsub "\.debug\$" $filename ".${number}.debug"] +} + +# Precompute sequence numbered build-id filenames. +set build_id_1_filename [add_seqno 1 $build_id_filename] +set build_id_2_filename [add_seqno 2 $build_id_filename] +set build_id_3_filename [add_seqno 3 $build_id_filename] + +load_binfile_check_debug_is_found $build_id_filename \ + "find debuginfo with a single build-id file" + +remote_exec target "ln -fs $target_debuginfo \ + $debugdir/$build_id_1_filename" +remote_exec target "ln -fs $target_debuginfo \ + $debugdir/$build_id_2_filename" +remote_exec target "ln -fs $target_debuginfo \ + $debugdir/$build_id_3_filename" + +load_binfile_check_debug_is_found $build_id_filename \ + "find debuginfo with 4 build-id files" + +remote_exec target "ln -fs $missing_debuginfo $debugdir/$build_id_filename" + +load_binfile_check_debug_is_found $build_id_1_filename \ + "find debuginfo, first build-id file is bad" + +remote_exec target "ln -fs $missing_debuginfo \ + $debugdir/$build_id_1_filename" +remote_exec target "ln -fs $missing_debuginfo \ + $debugdir/$build_id_3_filename" + +load_binfile_check_debug_is_found $build_id_2_filename \ + "find debuginfo, first 2 build-id files are bad" + +remote_exec target "ln -fs $missing_debuginfo \ + $debugdir/$build_id_2_filename" + +load_binfile_check_debug_is_found "" \ + "cannot find debuginfo, all build-id files are bad" + +remote_exec target "ln -fs $target_debuginfo \ + $debugdir/$build_id_3_filename" + +load_binfile_check_debug_is_found $build_id_3_filename \ + "find debuginfo, last build-id file is good" + +remote_exec target "rm -f $debugdir/$build_id_1_filename" + +load_binfile_check_debug_is_found "" \ + "cannot find debuginfo, file with seqno 1 is missing" diff --git a/gdb/testsuite/gdb.server/remote-read-msgs.exp b/gdb/testsuite/gdb.server/remote-read-msgs.exp index d2d659a..e204655 100644 --- a/gdb/testsuite/gdb.server/remote-read-msgs.exp +++ b/gdb/testsuite/gdb.server/remote-read-msgs.exp @@ -30,7 +30,8 @@ require {!is_remote host} standard_testfile -if {[build_executable "failed to prepare" $testfile $srcfile] == -1} { +if {[build_executable "failed to prepare" $testfile $srcfile \ + {debug build-id}] == -1} { return -1 } diff --git a/gdb/testsuite/gdb.server/solib-list.exp b/gdb/testsuite/gdb.server/solib-list.exp index b9cc6c8..bbc5df4 100644 --- a/gdb/testsuite/gdb.server/solib-list.exp +++ b/gdb/testsuite/gdb.server/solib-list.exp @@ -30,7 +30,7 @@ set srclibfile ${testfile}-lib.c set binlibfile [standard_output_file ${testfile}.so] if { [gdb_compile_shlib "${srcdir}/${subdir}/${srclibfile}" "${binlibfile}" {debug}] != "" - || [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "shlib=${binlibfile}"] != "" } { + || [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "shlib=${binlibfile} build-id"] != "" } { untested "failed to compile" return -1 } diff --git a/gdb/testsuite/gdb.threads/leader-exit-attach.exp b/gdb/testsuite/gdb.threads/leader-exit-attach.exp index c1ed1ba..5334de2 100644 --- a/gdb/testsuite/gdb.threads/leader-exit-attach.exp +++ b/gdb/testsuite/gdb.threads/leader-exit-attach.exp @@ -41,32 +41,24 @@ set is_gdbserver [target_is_gdbserver] set attached 0 gdb_test_multiple "attach $testpid" "attach" { - -re "Attaching to process $testpid failed.*" { + -re -wrap "Attaching to process $testpid failed.*" { # GNU/Linux gdbserver. Linux ptrace does not let you attach # to zombie threads. setup_kfail "gdb/31555" *-*-linux* fail $gdb_test_name } - -re "warning: process $testpid is a zombie - the process has already terminated.*" { + -re -wrap "warning: process $testpid is a zombie - the process has already terminated.*" { # Native GNU/Linux. Linux ptrace does not let you attach to # zombie threads. setup_kfail "gdb/31555" *-*-linux* fail $gdb_test_name } - -re "Attaching to program: $escapedbinfile, process $testpid.*$gdb_prompt $" { + -re -wrap "Attaching to program: $escapedbinfile, process $testpid.*" { pass $gdb_test_name set attached 1 } } -# With gdbserver, after we failed to attach, we hit PR server/31554: -# print $_inferior_thread_count -# Remote connection closed -# (gdb) KFAIL: gdb.threads/leader-exit-attach.exp: get valueof "$_inferior_thread_count" -if {!$attached && $is_gdbserver} { - setup_kfail "server/31554" "*-*-*" -} - set thread_count [get_valueof "" "\$_inferior_thread_count" -1] if {$thread_count == -1} { diff --git a/gdb/testsuite/gdb.threads/print-threads.exp b/gdb/testsuite/gdb.threads/print-threads.exp index e2be48b..6fae36a 100644 --- a/gdb/testsuite/gdb.threads/print-threads.exp +++ b/gdb/testsuite/gdb.threads/print-threads.exp @@ -93,7 +93,7 @@ gdb_test_no_output "set var slow = 0" test_all_threads "fast" 0 runto_main -gdb_test "break thread_function" "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*print-threads.c, line \[0-9\]*\\." "break thread_function (2)" +gdb_test "break thread_function" "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*print-threads.c, line \[0-9\]*\\." "break thread_function, 2" gdb_test_no_output "set var slow = 1" # Extend the timeout for slower tests. set timeout [expr $oldtimeout + 120] @@ -101,8 +101,8 @@ test_all_threads "slow" 0 set timeout $oldtimeout runto_main -gdb_test "break thread_function" "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*print-threads.c, line \[0-9\]*\\." "break thread_function (3)" -gdb_test_no_output "set var slow = 1" "set var slow = 1 (2)" +gdb_test "break thread_function" "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*print-threads.c, line \[0-9\]*\\." "break thread_function, 3" +gdb_test_no_output "set var slow = 1" "set var slow = 1, 2" gdb_breakpoint "kill" # Extend the timeout for slower tests. set timeout [expr $oldtimeout + 120] diff --git a/gdb/testsuite/gdb.threads/schedlock.exp b/gdb/testsuite/gdb.threads/schedlock.exp index bd5d5d2..4e99961 100644 --- a/gdb/testsuite/gdb.threads/schedlock.exp +++ b/gdb/testsuite/gdb.threads/schedlock.exp @@ -45,7 +45,7 @@ proc get_args { description } { append pattern ", (\[0-9\]+)" } - set test "listed args ($description)" + set test "listed args, $description" gdb_test_multiple "print args" $test { -re "\\\$\[0-9\]+ = {$pattern}.*$gdb_prompt $" { pass $test @@ -80,7 +80,7 @@ proc stop_process { description } { proc get_current_thread { description } { global gdb_prompt - set test "find current thread ($description)" + set test "find current thread, $description" gdb_test_multiple "bt" $test { -re "thread_function \\(arg=0x(\[0-9\])\\).*$gdb_prompt $" { @@ -124,7 +124,7 @@ proc step_ten_loops { cmd } { for {set i 0} {[expr $i < 10]} {set i [expr $i + 1]} { set other_step 0 - set test "$cmd to increment ($i)" + set test "$cmd to increment, $i" gdb_test_multiple $cmd $test { -re ".*myp\\) \\+\\+;\[\r\n\]+$gdb_prompt $" { pass $test diff --git a/gdb/testsuite/gdb.trace/entry-values.exp b/gdb/testsuite/gdb.trace/entry-values.exp index 0711100..3b358cc 100644 --- a/gdb/testsuite/gdb.trace/entry-values.exp +++ b/gdb/testsuite/gdb.trace/entry-values.exp @@ -171,7 +171,7 @@ gdb_continue_to_breakpoint "foo" gdb_test_no_output "set print entry-values both" -gdb_test_sequence "bt" "bt (1)" { +gdb_test_sequence "bt" "bt, 1" { "\[\r\n\]#0 .* foo \\(i=[-]?[0-9]+, i@entry=2, j=[-]?[0-9]+, j@entry=3\\)" "\[\r\n\]#1 .* bar \\(i=<optimized out>, i@entry=<optimized out>\\)" "\[\r\n\]#2 .* \.?main \\(\\)" @@ -183,7 +183,7 @@ gdb_test_sequence "bt" "bt (1)" { gdb_test_no_output "set var *(int *) &global1=10" gdb_test_no_output "set var *(int *) &global2=11" -gdb_test_sequence "bt" "bt (2)" { +gdb_test_sequence "bt" "bt, 2" { "\[\r\n\]#0 .* foo \\(i=[-]?[0-9]+, i@entry=10, j=[-]?[0-9]+, j@entry=11\\)" "\[\r\n\]#1 .* bar \\(i=<optimized out>, i@entry=<optimized out>\\)" "\[\r\n\]#2 .* \.?main \\(\\)" diff --git a/gdb/testsuite/gdb.tui/wrap-line.exp b/gdb/testsuite/gdb.tui/wrap-line.exp index 9cddcf1..d3020bf 100644 --- a/gdb/testsuite/gdb.tui/wrap-line.exp +++ b/gdb/testsuite/gdb.tui/wrap-line.exp @@ -50,7 +50,7 @@ proc fill_line { width } { } # Test wrapping. -proc test_wrap { wrap_width } { +proc test_wrap { wrap_width tui } { # Generate a prompt and parse it. send_gdb "\003" gdb_assert { [Term::wait_for "(^|$::gdb_prompt )$::re_control_c"] } "start line" @@ -65,12 +65,31 @@ proc test_wrap { wrap_width } { send_gdb "W" # Check that the wrap occurred at the expected location. - gdb_assert { [Term::wait_for_region_contents 0 0 $::cols $::lines \ - "$::gdb_prompt $str$space\r\nW"] } "wrap" + set re_wrap \ + [multi_line \ + "$::gdb_prompt $str$space" \ + "W"] + set re_no_wrap \ + [multi_line \ + "" \ + "<.*W"] + if { $tui } { + set re $re_wrap + } else { + set re ($re_wrap|$re_no_wrap) + } + gdb_assert { [Term::wait_for_region_contents 0 0 $::cols $::lines $re] } "wrap" # Generate a prompt and parse it. send_gdb "\003" - gdb_assert { [Term::wait_for "^W$::re_control_c"] } "prompt after wrap" + set re_wrap W$::re_control_c + set re_no_wrap <.*W$::re_control_c + if { $tui } { + set re $re_wrap + } else { + set re ($re_wrap|$re_no_wrap) + } + gdb_assert { [Term::wait_for ^$re] } "prompt after wrap" } # Test wrapping in both CLI and TUI. @@ -107,7 +126,7 @@ proc test_wrap_cli_tui { auto_detected_width } { with_test_prefix cli { set wrap_width $readline_width - test_wrap $wrap_width + test_wrap $wrap_width 0 } with_test_prefix tui { @@ -126,7 +145,7 @@ proc test_wrap_cli_tui { auto_detected_width } { # for wrapping from curses. set wrap_width $::cols - test_wrap $wrap_width + test_wrap $wrap_width 1 } } diff --git a/gdb/testsuite/gdb.xml/tdesc-arch.exp b/gdb/testsuite/gdb.xml/tdesc-arch.exp index f9b037f..6c8c592 100644 --- a/gdb/testsuite/gdb.xml/tdesc-arch.exp +++ b/gdb/testsuite/gdb.xml/tdesc-arch.exp @@ -73,7 +73,7 @@ proc set_arch { arch which trans_mode } { # Anchor the test output, so that error messages are detected. set cmd "set tdesc filename $filename" - set msg "set tdesc filename tdesc-arch.xml ($which architecture)" + set msg "set tdesc filename tdesc-arch.xml, $which architecture" set cmd_regex [string_to_regexp $cmd] gdb_test_multiple $cmd $msg { -re "^$cmd_regex\r\n$gdb_prompt $" { @@ -87,7 +87,7 @@ proc set_arch { arch which trans_mode } { set cmd "show architecture" gdb_test $cmd \ "The target architecture is set to \"auto\" \\(currently \"$arch\"\\)\\." \ - "$cmd ($which architecture)" + "$cmd, $which architecture" remote_file host delete $filename } @@ -115,11 +115,11 @@ if {[is_remote host]} { set cmd "set tdesc filename $filename" gdb_test $cmd \ "warning:.*Target description specified unknown architecture.*" \ - "set tdesc filename tdesc-arch.xml (invalid architecture)" + "set tdesc filename tdesc-arch.xml, invalid architecture" set cmd "show architecture" gdb_test $cmd \ "The target architecture is set to \"auto\" \\(currently \"$default_arch\"\\)\\." \ - "$cmd (invalid architecture)" + "$cmd, invalid architecture" remote_file host delete $filename diff --git a/gdb/testsuite/lib/cache.exp b/gdb/testsuite/lib/cache.exp index 8066734..092b7f1 100644 --- a/gdb/testsuite/lib/cache.exp +++ b/gdb/testsuite/lib/cache.exp @@ -46,6 +46,40 @@ proc gdb_do_cache_wrap {real_name args} { return $result } +# Global written to by gdb_exit_called proc. Is set to true to +# indicate that a caching proc has called gdb_exit. + +set gdb_exit_called false + +# This proc is called via TCL's trace mechanism whenever gdb_exit is +# called during the execution of a caching proc. This sets the global +# flag to indicate that gdb_exit has been called. + +proc gdb_exit_called { args } { + set ::gdb_exit_called true +} + +# If DO_EXIT is false then this proc does nothing. If DO_EXIT is true +# then call gdb_exit the first time this proc is called for each +# unique value of NAME within a single test. Every subsequent time +# this proc is called within a single test (for a given value of +# NAME), don't call gdb_exit. + +proc gdb_cache_maybe_gdb_exit { name do_exit } { + if { !$do_exit } { + return + } + + # To track if this proc has been called for NAME we create a + # global variable. In gdb_cleanup_globals (see gdb.exp) this + # global will be deleted when the test has finished. + set global_name __${name}__cached_gdb_exit_called + if { ![info exists ::${global_name}] } { + gdb_exit + set ::${global_name} true + } +} + # A helper for gdb_caching_proc that handles the caching. proc gdb_do_cache {name args} { @@ -70,11 +104,13 @@ proc gdb_do_cache {name args} { set cache_name [file join [target_info name] $name {*}$args] set is_cached 0 - if {[info exists gdb_data_cache($cache_name)]} { - set cached $gdb_data_cache($cache_name) - verbose "$name: returning '$cached' from cache" 2 + if {[info exists gdb_data_cache(${cache_name},value)]} { + set cached_value $gdb_data_cache(${cache_name},value) + set cached_exit $gdb_data_cache(${cache_name},exit) + verbose "$name: returning '$cached_value' from cache" 2 if { $cache_verify == 0 } { - return $cached + gdb_cache_maybe_gdb_exit $name $cached_exit + return $cached_value } set is_cached 1 } @@ -83,37 +119,105 @@ proc gdb_do_cache {name args} { set cache_filename [make_gdb_parallel_path cache $cache_name] if {[file exists $cache_filename]} { set fd [open $cache_filename] - set gdb_data_cache($cache_name) [read -nonewline $fd] + set content [split [read -nonewline $fd] \n] close $fd - set cached $gdb_data_cache($cache_name) - verbose "$name: returning '$cached' from file cache" 2 + set gdb_data_cache(${cache_name},value) [lindex $content 0] + set gdb_data_cache(${cache_name},exit) [lindex $content 1] + set cached_value $gdb_data_cache(${cache_name},value) + set cached_exit $gdb_data_cache(${cache_name},exit) + verbose "$name: returning '$cached_value' from file cache" 2 if { $cache_verify == 0 } { - return $cached + gdb_cache_maybe_gdb_exit $name $cached_exit + return $cached_value } set is_cached 1 } } + # Add a trace hook to gdb_exit. In the case of recursive calls to + # gdb_do_cache we only want to install the trace hook once, so we + # set a global to indicate that the trace is in place. + # + # We also set a local flag to indicate that this is the scope in + # which the debug trace needs to be removed. + if { ![info exists ::gdb_exit_trace_in_place] } { + trace add execution gdb_exit enter gdb_exit_called + set ::gdb_exit_trace_in_place true + set gdb_exit_trace_created true + } else { + set gdb_exit_trace_created false + } + + # As above, we need to consider recursive calls into gdb_do_cache. + # Store the old value of gdb_exit_called global and then set the + # flag to false. Initially gdb_exit_called is always false, but + # for recursive calls to gdb_do_cache we can't know the state of + # gdb_exit_called. + # + # Before starting a recursive gdb_do_cache call we need + # gdb_exit_called to be false, that way the inner call can know if + # it invoked gdb_exit or not. + # + # Once the recursive call completes, if it did call gdb_exit then + # the outer, parent call to gdb_do_cache should also be considered + # as having called gdb_exit. + set old_gdb_exit_called $::gdb_exit_called + set ::gdb_exit_called false + set real_name gdb_real__$name - set gdb_data_cache($cache_name) [gdb_do_cache_wrap $real_name {*}$args] + set gdb_data_cache(${cache_name},value) [gdb_do_cache_wrap $real_name {*}$args] + set gdb_data_cache(${cache_name},exit) $::gdb_exit_called + + # See comment above where OLD_GDB_EXIT_CALLED is set: if + # GDB_EXIT_CALLED was previously true then this is a recursive + # call and the outer caching proc set the global true, so restore + # the true value now. + if { $old_gdb_exit_called } { + set ::gdb_exit_called true + } + + # See comment above where GDB_EXIT_TRACE_CREATED is set: this is + # the frame in which the trace was installed. This must be the + # outer caching proc call (if an recursion occurred). + if { $gdb_exit_trace_created } { + trace remove execution gdb_exit enter gdb_exit_called + unset ::gdb_exit_trace_in_place + set ::gdb_exit_called false + } + + # If a value being stored in the cache contains a newline then + # when we try to read the value back from an on-disk cache file + # we'll interpret the second line of the value as the ',exit' value. + if { [regexp "\[\r\n\]" $gdb_data_cache(${cache_name},value)] } { + set computed_value $gdb_data_cache(${cache_name},value) + error "Newline found in value for $cache_name: $computed_value" + } + if { $cache_verify == 1 && $is_cached == 1 } { - set computed $gdb_data_cache($cache_name) - if { $cached != $computed } { - error [join [list "Inconsistent results for $cache_name:" - "cached: $cached vs. computed: $computed"]] + set computed_value $gdb_data_cache(${cache_name},value) + set computed_exit $gdb_data_cache(${cache_name},exit) + if { $cached_value != $computed_value } { + error [join [list "Inconsistent value results for $cache_name:" + "cached: $cached_value vs. computed: $computed_value"]] + } + if { $cached_exit != $computed_exit } { + error [join [list "Inconsistent exit results for $cache_name:" + "cached: $cached_exit vs. computed: $computed_exit"]] } } if {[info exists GDB_PARALLEL]} { - verbose "$name: returning '$gdb_data_cache($cache_name)' and writing file" 2 + verbose "$name: returning '$gdb_data_cache(${cache_name},value)' and writing file" 2 file mkdir [file dirname $cache_filename] # Make sure to write the results file atomically. set fd [open $cache_filename.[pid] w] - puts $fd $gdb_data_cache($cache_name) + puts $fd $gdb_data_cache(${cache_name},value) + puts $fd $gdb_data_cache(${cache_name},exit) close $fd file rename -force -- $cache_filename.[pid] $cache_filename } - return $gdb_data_cache($cache_name) + gdb_cache_maybe_gdb_exit $name $gdb_data_cache(${cache_name},exit) + return $gdb_data_cache(${cache_name},value) } # Define a new proc named NAME, with optional args ARGS. BODY is the body of diff --git a/gdb/testsuite/lib/check-test-names.exp b/gdb/testsuite/lib/check-test-names.exp index 8f86f31..11aed63 100644 --- a/gdb/testsuite/lib/check-test-names.exp +++ b/gdb/testsuite/lib/check-test-names.exp @@ -64,6 +64,16 @@ namespace eval ::CheckTestNames { proc _check_duplicates { message } { variable all_test_names + # Remove test-case prefix, including the space separator. + set prefix [string_to_regexp "$::subdir/$::gdb_test_file_name.exp: "] + set message [regsub ^$prefix $message ""] + + # Remove the "extra information" part. + set message [regsub { \([^()]*\)$} $message ""] + + # Add back the test-case prefix. + set message "${prefix}$message" + # Initialise a count, or increment the count for this test name. if {![info exists all_test_names($message)]} { set all_test_names($message) 0 diff --git a/gdb/testsuite/lib/gdb-utils.exp b/gdb/testsuite/lib/gdb-utils.exp index 95c53d0..41989da 100644 --- a/gdb/testsuite/lib/gdb-utils.exp +++ b/gdb/testsuite/lib/gdb-utils.exp @@ -38,6 +38,14 @@ proc string_to_regexp {str} { return $result } +# Convenience function that calls string_to_regexp for each arg, and +# joins the results using "\r\n". + +proc multi_line_string_to_regexp { args } { + set res [lmap arg $args {string_to_regexp $arg}] + return [multi_line {*}$res] +} + # Given a list of strings, adds backslashes as needed to each string to # create a regexp that will match the string, and join the result. diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index dfe19c9..1c49b6a 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -158,6 +158,23 @@ load_lib gdb-utils.exp load_lib memory.exp load_lib check-test-names.exp +# The path to the GCORE script to test. +global GCORE +if {![info exists GCORE]} { + set GCORE [findfile $base_dir/../../gdb/gcore] +} +verbose "using GCORE = $GCORE" 2 + +# Return 0 if the gcore scipt is missing. +proc has_gcore_script {} { + global GCORE + if {$GCORE == ""} { + return 0 + } else { + return 1 + } +} + # The path to the GDB binary to test. global GDB @@ -965,6 +982,31 @@ proc fill_in_default_prompt {prompt_regexp with_anchor} { return $prompt_regexp } +# Generate message from COMMAND. +# +# This is not trivial in the case that the command contains parentheses. +# Trailing text between parentheses prefixed with a space is interpreted as +# extra information, and not as part of the test name [1]. Consequently, +# "PASS: print (1)" and "PASS: print (2)" count as duplicates. +# +# We fix this here by using "PASS: gdb-command<print (1)>" and +# "PASS: gdb-command<print (2)>". +# +# A trivial way to fix this in a test-case is by using gdb_test "print(1)", +# which produces the nicer-looking "PASS: print(1)". +# +# [1] https://sourceware.org/gdb/wiki/GDBTestcaseCookbook#Do_not_use_.22tail_parentheses.22_on_test_messages + +proc command_to_message { command } { + set message $command + + if { [regexp { \(([^()]*)\)$} $message] } { + set message gdb-command<$message> + } + + return $message +} + # gdb_test_multiple COMMAND MESSAGE [ -prompt PROMPT_REGEXP] [ -lbl ] # EXPECT_ARGUMENTS # Send a command to gdb; test the result. @@ -1095,7 +1137,7 @@ proc gdb_test_multiple { command message args } { set prompt_regexp [fill_in_default_prompt $prompt_regexp true] if { $message == "" } { - set message $command + set message [command_to_message $command] } if [string match "*\[\r\n\]" $command] { @@ -1471,7 +1513,6 @@ proc gdb_test_multiline { name args } { return 0 } - # gdb_test [-prompt PROMPT_REGEXP] [-lbl] # COMMAND [PATTERN] [MESSAGE] [QUESTION RESPONSE] # Send a command to gdb; test the result. @@ -1529,7 +1570,7 @@ proc gdb_test { args } { } if { $message == "" } { - set message $command + set message [command_to_message $command] } set prompt [fill_in_default_prompt $prompt [expr !${no-prompt-anchor}]] @@ -1795,7 +1836,7 @@ proc gdb_test_lines { command message re args } { } if { $message == ""} { - set message $command + set message [command_to_message $command] } set lines "" @@ -2012,7 +2053,7 @@ proc gdb_test_stdio {command inferior_pattern {gdb_pattern ""} {message ""}} { global gdb_prompt if {$message == ""} { - set message $command + set message [command_to_message $command] } set inferior_matched 0 @@ -4258,6 +4299,79 @@ gdb_caching_proc allow_btrace_pt_tests {} { return $allow_btrace_pt_tests } +# Run a test on the target to see if it supports ptwrite instructions and +# if GDB can decode ptwrite events. Return 1 if so, 0 if it does not. + +gdb_caching_proc allow_btrace_ptw_tests {} { + global srcdir subdir gdb_prompt inferior_exited_re decimal + + require allow_btrace_pt_tests + set me "allow_btrace_ptw_tests" + + set src { + #include <immintrin.h> + + int + main () + { + _ptwrite32 (0x42); + return 0; + } + } + + set compile_flags "additional_flags=-mptwrite" + if {![gdb_simple_compile $me $src executable $compile_flags]} { + return 0 + } + + gdb_exit + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_load "$obj" + if ![runto_main] { + return 1 + } + + gdb_test_no_output "record btrace pt" "$me: record btrace pt" + + set allow_btrace_ptw_tests 0 + gdb_test_multiple "next" "$me: next" { + -re -wrap ".*Illegal instruction.*" { + verbose -log "$me: ptwrite instruction support not detected." + } + -re -wrap ".*$inferior_exited_re normally.*" { + verbose -log "$me: ptwrite support not detected." + } + -re -wrap "$decimal.*(at|in|return 0).*" { + set allow_btrace_ptw_tests 1 + } + } + + if { $allow_btrace_ptw_tests == 1 } { + # Show the func-call-history to get the packet trace. + gdb_test "record function-call-history" ".*" + + gdb_test_multiple "maintenance btrace packet-history 0,1000" \ + "$me: check decoding support" { + -re "ptw" { + verbose -log "$me: ptwrite decoding support detected." + set allow_btrace_ptw_tests 1 + } + -re -wrap "" { + verbose -log "$me: ptwrite decoding support not detected." + set allow_btrace_ptw_tests 0 + } + } + } + + gdb_exit + remote_file build delete $obj + + verbose "$me: returning $allow_btrace_ptw_tests" 2 + return $allow_btrace_ptw_tests +} + + # Run a test on the target to see if it supports Aarch64 SVE hardware. # Return 1 if so, 0 if it does not. Note this causes a restart of GDB. @@ -5469,12 +5583,12 @@ proc gdb_compile {source dest type options} { # enable it now. if {[lsearch -exact $options build-id] > 0 && [test_compiler_info "clang-*"]} { - lappend new_options "additional_flags=-Wl,--build-id" + lappend new_options "ldflags=-Wl,--build-id" } # If the 'no-build-id' option is used then disable the build-id. if {[lsearch -exact $options no-build-id] > 0} { - lappend new_options "additional_flags=-Wl,--build-id=none" + lappend new_options "ldflags=-Wl,--build-id=none" } # Sanity check. If both 'build-id' and 'no-build-id' are used @@ -6321,14 +6435,23 @@ proc gdb_exit { } { catch default_gdb_exit } -# Helper function for can_spawn_for_attach. Try to spawn and attach, and -# return 0 only if we cannot attach because it's unsupported. +# Return true if we can spawn a program on the target and attach to +# it. + +gdb_caching_proc can_spawn_for_attach {} { + # We use exp_pid to get the inferior's pid, assuming that gives + # back the pid of the program. On remote boards, that would give + # us instead the PID of e.g., the ssh client, etc. + if {[is_remote target]} { + verbose -log "can't spawn for attach (target is remote)" + return 0 + } -gdb_caching_proc can_spawn_for_attach_1 {} { - # For the benefit of gdb-caching-proc-consistency.exp, which - # calls can_spawn_for_attach_1 directly. Keep in sync with - # can_spawn_for_attach. - if { [is_remote target] || [target_info exists use_gdb_stub] } { + # The "attach" command doesn't make sense when the target is + # stub-like, where GDB finds the program already started on + # initial connection. + if {[target_info exists use_gdb_stub]} { + verbose -log "can't spawn for attach (target is stub)" return 0 } @@ -6353,6 +6476,9 @@ gdb_caching_proc can_spawn_for_attach_1 {} { set test_spawn_id [spawn_wait_for_attach_1 $obj] remote_file build delete $obj + # In case GDB is already running. + gdb_exit + gdb_start set test_pid [spawn_id_get_pid $test_spawn_id] @@ -6374,61 +6500,6 @@ gdb_caching_proc can_spawn_for_attach_1 {} { return $res } -# Return true if we can spawn a program on the target and attach to -# it. Calls gdb_exit for the first call in a test-case. - -proc can_spawn_for_attach { } { - # We use exp_pid to get the inferior's pid, assuming that gives - # back the pid of the program. On remote boards, that would give - # us instead the PID of e.g., the ssh client, etc. - if {[is_remote target]} { - verbose -log "can't spawn for attach (target is remote)" - return 0 - } - - # The "attach" command doesn't make sense when the target is - # stub-like, where GDB finds the program already started on - # initial connection. - if {[target_info exists use_gdb_stub]} { - verbose -log "can't spawn for attach (target is stub)" - return 0 - } - - # The normal sequence to use for a runtime test like - # can_spawn_for_attach_1 is: - # - gdb_exit (don't use a running gdb, we don't know what state it is in), - # - gdb_start (start a new gdb), and - # - gdb_exit (cleanup). - # - # By making can_spawn_for_attach_1 a gdb_caching_proc, we make it - # unpredictable which test-case will call it first, and consequently a - # test-case may pass in say a full test run, but fail when run - # individually, due to a can_spawn_for_attach call in a location where a - # gdb_exit (as can_spawn_for_attach_1 does) breaks things. - # To avoid this, we move the initial gdb_exit out of - # can_spawn_for_attach_1, guaranteeing that we end up in the same state - # regardless of whether can_spawn_for_attach_1 is called. However, that - # is only necessary for the first call in a test-case, so cache the result - # in a global (which should be reset after each test-case) to keep track - # of that. - # - # In summary, we distinguish between three cases: - # - first call in first test-case. Executes can_spawn_for_attach_1. - # Calls gdb_exit, gdb_start, gdb_exit. - # - first call in following test-cases. Uses cached result of - # can_spawn_for_attach_1. Calls gdb_exit. - # - rest. Use cached result in cache_can_spawn_for_attach_1. Calls no - # gdb_start or gdb_exit. - global cache_can_spawn_for_attach_1 - if { [info exists cache_can_spawn_for_attach_1] } { - return $cache_can_spawn_for_attach_1 - } - gdb_exit - - set cache_can_spawn_for_attach_1 [can_spawn_for_attach_1] - return $cache_can_spawn_for_attach_1 -} - # Centralize the failure checking of "attach" command. # Return 0 if attach failed, otherwise return 1. @@ -8115,7 +8186,6 @@ gdb_caching_proc gdb_has_argv0 {} { || [istarget *-wince-pe] || [istarget *-*-mingw32ce*] || [istarget *-*-osf*] || [istarget *-*-dicos*] - || [istarget *-*-nto*] || [istarget *-*-*vms*] || [istarget *-*-lynx*178]) } { fail "argv\[0\] should be available on this target" diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp index aa0f9df..a79b133 100644 --- a/gdb/testsuite/lib/mi-support.exp +++ b/gdb/testsuite/lib/mi-support.exp @@ -1989,14 +1989,13 @@ proc get_mi_thread_list {name} { return $thread_list } -# Check that MI and the console know of the same threads. -# Appends NAME to all test names. -proc check_mi_and_console_threads {name} { +# Helper function for check_mi_and_console_threads. +proc check_mi_and_console_threads_1 { name } { global expect_out mi_gdb_test "-thread-list-ids" \ {.*\^done,thread-ids={(thread-id="[0-9]+"(,)*)+},current-thread-id="[0-9]+",number-of-threads="[0-9]+"} \ - "-thread-list-ids ($name)" + "-thread-list-ids" set mi_output {} if {[info exists expect_out(buffer)]} { set mi_output $expect_out(buffer) @@ -2013,7 +2012,7 @@ proc check_mi_and_console_threads {name} { # FIXME: kseitz/2002-09-05: Don't use the hack-cli method. mi_gdb_test "info threads" \ {.*(~".*"[\r\n]*)+.*} \ - "info threads ($name)" + "info threads" set console_output {} if {[info exists expect_out(buffer)]} { set console_output $expect_out(buffer) @@ -2039,29 +2038,29 @@ proc check_mi_and_console_threads {name} { } } if {$mi_result == ""} { - fail "finding MI result string ($name)" + fail "finding MI result string" } else { - pass "finding MI result string ($name)" + pass "finding MI result string" } # Finally, extract the thread ids and compare them to the console set num_mi_threads_str "" if {![regexp {number-of-threads="[0-9]+"} $mi_result num_mi_threads_str]} { - fail "finding number of threads in MI output ($name)" + fail "finding number of threads in MI output" } else { - pass "finding number of threads in MI output ($name)" + pass "finding number of threads in MI output" # Extract the number of threads from the MI result if {![scan $num_mi_threads_str {number-of-threads="%d"} num_mi_threads]} { - fail "got number of threads from MI ($name)" + fail "got number of threads from MI" } else { - pass "got number of threads from MI ($name)" + pass "got number of threads from MI" # Check if MI and console have same number of threads if {$num_mi_threads != [llength $console_thread_list]} { - fail "console and MI have same number of threads ($name)" + fail "console and MI have same number of threads" } else { - pass "console and MI have same number of threads ($name)" + pass "console and MI have same number of threads" # Get MI thread list set mi_thread_list [get_mi_thread_list $name] @@ -2074,19 +2073,27 @@ proc check_mi_and_console_threads {name} { } } if {$fails > 0} { - fail "MI and console have same threads ($name)" + fail "MI and console have same threads" # Send a list of failures to the log send_log "Console has thread ids: $console_thread_list\n" send_log "MI has thread ids: $mi_thread_list\n" } else { - pass "MI and console have same threads ($name)" + pass "MI and console have same threads" } } } } } +# Check that MI and the console know of the same threads. +# Appends NAME to all test names. +proc check_mi_and_console_threads { name } { + with_test_prefix $name { + check_mi_and_console_threads_1 $name + } +} + # Set solib-search-path to allow gdb to locate shlib FILE. proc mi_locate_shlib { file } { global mi_spawn_id diff --git a/gdb/tid-parse.c b/gdb/tid-parse.c index 623f55e..1b8f343 100644 --- a/gdb/tid-parse.c +++ b/gdb/tid-parse.c @@ -24,7 +24,7 @@ /* See tid-parse.h. */ -void ATTRIBUTE_NORETURN +[[noreturn]] void invalid_thread_id_error (const char *string) { error (_("Invalid thread ID: %s"), string); diff --git a/gdb/tid-parse.h b/gdb/tid-parse.h index b7bd920..7bbdeab 100644 --- a/gdb/tid-parse.h +++ b/gdb/tid-parse.h @@ -26,7 +26,7 @@ struct thread_info; /* Issue an invalid thread ID error, pointing at STRING, the invalid ID. */ -extern void ATTRIBUTE_NORETURN invalid_thread_id_error (const char *string); +[[noreturn]] extern void invalid_thread_id_error (const char *string); /* Parse TIDSTR as a per-inferior thread ID, in either INF_NUM.THR_NUM or THR_NUM form. In the latter case, the missing INF_NUM is filled @@ -42,7 +42,7 @@ extern void read_command_file (FILE *); extern void init_history (void); extern void command_loop (void); extern int quit_confirm (void); -extern void quit_force (int *, int) ATTRIBUTE_NORETURN; +[[noreturn]] extern void quit_force (int *, int); extern void quit_command (const char *, int); extern void quit_cover (void); extern void execute_command (const char *, int); diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index e9bcbfd..a5a2e69 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -2455,7 +2455,6 @@ tfind_outside_command (const char *args, int from_tty) static void info_scope_command (const char *args_in, int from_tty) { - struct bound_minimal_symbol msym; const struct block *block; const char *symname; const char *save_args = args_in; @@ -2579,17 +2578,20 @@ info_scope_command (const char *args_in, int from_tty) sym->value_block ()->entry_pc ())); break; case LOC_UNRESOLVED: - msym = lookup_minimal_symbol (sym->linkage_name (), - NULL, NULL); - if (msym.minsym == NULL) - gdb_printf ("Unresolved Static"); - else - { - gdb_printf ("static storage at address "); - gdb_printf ("%s", - paddress (gdbarch, msym.value_address ())); - } - break; + { + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, + sym->linkage_name ()); + if (msym.minsym == NULL) + gdb_printf ("Unresolved Static"); + else + { + gdb_printf ("static storage at address "); + gdb_printf ("%s", + paddress (gdbarch, msym.value_address ())); + } + break; + } case LOC_OPTIMIZED_OUT: gdb_printf ("optimized out.\n"); continue; diff --git a/gdb/trad-frame.c b/gdb/trad-frame.c index e64374a..35bf02e 100644 --- a/gdb/trad-frame.c +++ b/gdb/trad-frame.c @@ -154,12 +154,14 @@ trad_frame_set_reg_regmap (struct trad_frame_cache *this_trad_cache, else { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - gdb_byte buf[slot_size]; + gdb::byte_vector buf (slot_size); - if (target_read_memory (addr + offs, buf, sizeof buf) == 0) + if (target_read_memory (addr + offs, buf.data (), buf.size ()) + == 0) { LONGEST val - = extract_unsigned_integer (buf, sizeof buf, byte_order); + = extract_unsigned_integer (buf.data (), buf.size (), + byte_order); trad_frame_set_reg_value (this_trad_cache, regno, val); } } diff --git a/gdb/tui/tui-disasm.c b/gdb/tui/tui-disasm.c index 0727d3a..cd82853 100644 --- a/gdb/tui/tui-disasm.c +++ b/gdb/tui/tui-disasm.c @@ -157,11 +157,11 @@ tui_disassemble (struct gdbarch *gdbarch, static CORE_ADDR tui_find_backward_disassembly_start_address (CORE_ADDR addr) { - struct bound_minimal_symbol msym, msym_prev; - - msym = lookup_minimal_symbol_by_pc_section (addr - 1, nullptr, - lookup_msym_prefer::TEXT, - &msym_prev); + bound_minimal_symbol msym_prev; + bound_minimal_symbol msym + = lookup_minimal_symbol_by_pc_section (addr - 1, nullptr, + lookup_msym_prefer::TEXT, + &msym_prev); if (msym.minsym != nullptr) return msym.value_address (); else if (msym_prev.minsym != nullptr) @@ -389,10 +389,12 @@ tui_get_begin_asm_address (struct gdbarch **gdbarch_p, CORE_ADDR *addr_p) if (tui_location.addr () == 0) { - if (have_full_symbols () || have_partial_symbols ()) + if (have_full_symbols (current_program_space) + || have_partial_symbols (current_program_space)) { set_default_source_symtab_and_line (); - struct symtab_and_line sal = get_current_source_symtab_and_line (); + symtab_and_line sal + = get_current_source_symtab_and_line (current_program_space); if (sal.symtab != nullptr) find_line_pc (sal.symtab, sal.line, &addr); @@ -400,8 +402,8 @@ tui_get_begin_asm_address (struct gdbarch **gdbarch_p, CORE_ADDR *addr_p) if (addr == 0) { - struct bound_minimal_symbol main_symbol - = lookup_minimal_symbol (main_name (), nullptr, nullptr); + bound_minimal_symbol main_symbol + = lookup_minimal_symbol (current_program_space, main_name ()); if (main_symbol.minsym != nullptr) addr = main_symbol.value_address (); } diff --git a/gdb/tui/tui-hooks.c b/gdb/tui/tui-hooks.c index e6673ab..25358d0 100644 --- a/gdb/tui/tui-hooks.c +++ b/gdb/tui/tui-hooks.c @@ -127,7 +127,8 @@ tui_refresh_frame_and_register_information () /* Make sure that the source window is displayed. */ tui_add_win_to_layout (SRC_WIN); - struct symtab_and_line sal = get_current_source_symtab_and_line (); + symtab_and_line sal + = get_current_source_symtab_and_line (current_program_space); tui_update_source_windows_with_line (sal); } } diff --git a/gdb/tui/tui-source.c b/gdb/tui/tui-source.c index 444c0f7..ee64e41 100644 --- a/gdb/tui/tui-source.c +++ b/gdb/tui/tui-source.c @@ -136,7 +136,8 @@ tui_source_window::do_scroll_vertical (int num_to_scroll) if (!m_content.empty ()) { struct symtab *s; - struct symtab_and_line cursal = get_current_source_symtab_and_line (); + symtab_and_line cursal + = get_current_source_symtab_and_line (current_program_space); struct gdbarch *arch = m_gdbarch; if (cursal.symtab == NULL) @@ -220,7 +221,7 @@ void tui_source_window::display_start_addr (struct gdbarch **gdbarch_p, CORE_ADDR *addr_p) { - struct symtab_and_line cursal = get_current_source_symtab_and_line (); + symtab_and_line cursal = get_current_source_symtab_and_line (current_program_space); *gdbarch_p = m_gdbarch; find_line_pc (cursal.symtab, m_start_line_or_addr.u.line_no, addr_p); diff --git a/gdb/tui/tui-winsource.c b/gdb/tui/tui-winsource.c index 80297e5..b08fca7 100644 --- a/gdb/tui/tui-winsource.c +++ b/gdb/tui/tui-winsource.c @@ -440,8 +440,8 @@ tui_source_window_base::rerender () if (!m_content.empty ()) { - struct symtab_and_line cursal - = get_current_source_symtab_and_line (); + symtab_and_line cursal + = get_current_source_symtab_and_line (current_program_space); if (m_start_line_or_addr.loa == LOA_LINE) cursal.line = m_start_line_or_addr.u.line_no; @@ -451,8 +451,8 @@ tui_source_window_base::rerender () } else if (deprecated_safe_get_selected_frame () != NULL) { - struct symtab_and_line cursal - = get_current_source_symtab_and_line (); + symtab_and_line cursal + = get_current_source_symtab_and_line (current_program_space); frame_info_ptr frame = deprecated_safe_get_selected_frame (); struct gdbarch *gdbarch = get_frame_arch (frame); @@ -492,7 +492,7 @@ tui_source_window_base::refill () if (this == tui_src_win ()) { - sal = get_current_source_symtab_and_line (); + sal = get_current_source_symtab_and_line (current_program_space); if (sal.symtab == NULL) { frame_info_ptr fi = deprecated_safe_get_selected_frame (); diff --git a/gdb/unittests/enum-flags-selftests.c b/gdb/unittests/enum-flags-selftests.c index b55d8c3..dddb1e2 100644 --- a/gdb/unittests/enum-flags-selftests.c +++ b/gdb/unittests/enum-flags-selftests.c @@ -29,49 +29,49 @@ namespace enum_flags_tests { make it simpler to use. They could be named differently. */ /* A "real enum". */ -enum RE - { - RE_FLAG1 = 1 << 1, - RE_FLAG2 = 1 << 2, - }; +enum RawEnum +{ + RawEnum_Flag1 = 1 << 1, + RawEnum_Flag2 = 1 << 2, +}; /* Another "real enum". */ -enum RE2 - { - RE2_FLAG1 = 1 << 1, - RE2_FLAG2 = 1 << 2, - }; +enum RawEnum2 +{ + RawEnum2_Flag1 = 1 << 1, + RawEnum2_Flag2 = 1 << 2, +}; /* An unsigned "real enum". */ -enum URE : unsigned - { - URE_FLAG1 = 1 << 1, - URE_FLAG2 = 1 << 2, - URE_FLAG3 = 0xffffffff, - }; +enum UnsignedRawEnum : unsigned +{ + UnsignedRawEnum_Flag1 = 1 << 1, + UnsignedRawEnum_Flag2 = 1 << 2, + UnsignedRawEnum_Flag3 = 0xffffffff, +}; /* A non-flags enum. */ -enum NF - { - NF_FLAG1 = 1 << 1, - NF_FLAG2 = 1 << 2, - }; +enum NonFlagsEnum +{ + NonFlagsEnum_Flag1 = 1 << 1, + NonFlagsEnum_Flag2 = 1 << 2, +}; /* The corresponding "enum flags" types. */ -DEF_ENUM_FLAGS_TYPE (RE, EF); -DEF_ENUM_FLAGS_TYPE (RE2, EF2); -DEF_ENUM_FLAGS_TYPE (URE, UEF); +DEF_ENUM_FLAGS_TYPE (RawEnum, EnumFlag); +DEF_ENUM_FLAGS_TYPE (RawEnum2, EnumFlag2); +DEF_ENUM_FLAGS_TYPE (UnsignedRawEnum, UnsignedEnumFlag); /* So that std::vectors of types that have enum_flags fields can reallocate efficiently memcpy. */ -static_assert (std::is_trivially_copyable<EF>::value); +static_assert (std::is_trivially_copyable<EnumFlag>::value); /* A couple globals used as lvalues in the CHECK_VALID expressions below. Their names (and types) match the uppercase type names exposed by CHECK_VALID just to make the expressions easier to follow. */ -static RE re ATTRIBUTE_UNUSED; -static EF ef ATTRIBUTE_UNUSED; +static RawEnum re ATTRIBUTE_UNUSED; +static EnumFlag ef ATTRIBUTE_UNUSED; /* First, compile-time tests that: @@ -82,30 +82,32 @@ static EF ef ATTRIBUTE_UNUSED; types do compile and that they return the correct type. */ -#define CHECK_VALID(VALID, EXPR_TYPE, EXPR) \ - CHECK_VALID_EXPR_6 (EF, RE, EF2, RE2, UEF, URE, VALID, EXPR_TYPE, EXPR) +#define CHECK_VALID(VALID, EXPR_TYPE, EXPR) \ + CHECK_VALID_EXPR_6 (EnumFlag, RawEnum, EnumFlag2, RawEnum2, \ + UnsignedEnumFlag, UnsignedRawEnum, VALID, EXPR_TYPE, \ + EXPR) -typedef std::underlying_type<RE>::type und; +using und = std::underlying_type<RawEnum>::type; /* Test construction / conversion from/to different types. */ /* RE/EF -> underlying (explicit) */ -CHECK_VALID (true, und, und (RE ())) -CHECK_VALID (true, und, und (EF ())) +CHECK_VALID (true, und, und (RawEnum ())) +CHECK_VALID (true, und, und (EnumFlag ())) /* RE/EF -> int (explicit) */ -CHECK_VALID (true, int, int (RE ())) -CHECK_VALID (true, int, int (EF ())) +CHECK_VALID (true, int, int (RawEnum ())) +CHECK_VALID (true, int, int (EnumFlag ())) /* other -> RE */ /* You can construct a raw enum value from an int explicitly to punch a hole in the type system if need to. */ -CHECK_VALID (true, RE, RE (1)) -CHECK_VALID (true, RE, RE (RE2 ())) -CHECK_VALID (false, void, RE (EF2 ())) -CHECK_VALID (true, RE, RE (RE ())) -CHECK_VALID (false, void, RE (EF ())) +CHECK_VALID (true, RawEnum, RawEnum (1)) +CHECK_VALID (true, RawEnum, RawEnum (RawEnum2 ())) +CHECK_VALID (false, void, RawEnum (EnumFlag2 ())) +CHECK_VALID (true, RawEnum, RawEnum (RawEnum ())) +CHECK_VALID (false, void, RawEnum (EnumFlag ())) /* other -> EF. */ @@ -113,125 +115,125 @@ CHECK_VALID (false, void, RE (EF ())) enum. Unlike with raw enums, you can't construct an enum flags from an integer nor from an unrelated enum type explicitly. Add an intermediate conversion via the raw enum if you really need it. */ -CHECK_VALID (false, void, EF (1)) -CHECK_VALID (false, void, EF (1u)) -CHECK_VALID (false, void, EF (RE2 ())) -CHECK_VALID (false, void, EF (EF2 ())) -CHECK_VALID (true, EF, EF (RE ())) -CHECK_VALID (true, EF, EF (EF ())) +CHECK_VALID (false, void, EnumFlag (1)) +CHECK_VALID (false, void, EnumFlag (1u)) +CHECK_VALID (false, void, EnumFlag (RawEnum2 ())) +CHECK_VALID (false, void, EnumFlag (EnumFlag2 ())) +CHECK_VALID (true, EnumFlag, EnumFlag (RawEnum ())) +CHECK_VALID (true, EnumFlag, EnumFlag (EnumFlag ())) /* Test operators. */ /* operator OP (raw_enum, int) */ -CHECK_VALID (false, void, RE () | 1) -CHECK_VALID (false, void, RE () & 1) -CHECK_VALID (false, void, RE () ^ 1) +CHECK_VALID (false, void, RawEnum () | 1) +CHECK_VALID (false, void, RawEnum () & 1) +CHECK_VALID (false, void, RawEnum () ^ 1) /* operator OP (int, raw_enum) */ -CHECK_VALID (false, void, 1 | RE ()) -CHECK_VALID (false, void, 1 & RE ()) -CHECK_VALID (false, void, 1 ^ RE ()) +CHECK_VALID (false, void, 1 | RawEnum ()) +CHECK_VALID (false, void, 1 & RawEnum ()) +CHECK_VALID (false, void, 1 ^ RawEnum ()) /* operator OP (enum_flags, int) */ -CHECK_VALID (false, void, EF () | 1) -CHECK_VALID (false, void, EF () & 1) -CHECK_VALID (false, void, EF () ^ 1) +CHECK_VALID (false, void, EnumFlag () | 1) +CHECK_VALID (false, void, EnumFlag () & 1) +CHECK_VALID (false, void, EnumFlag () ^ 1) /* operator OP (int, enum_flags) */ -CHECK_VALID (false, void, 1 | EF ()) -CHECK_VALID (false, void, 1 & EF ()) -CHECK_VALID (false, void, 1 ^ EF ()) +CHECK_VALID (false, void, 1 | EnumFlag ()) +CHECK_VALID (false, void, 1 & EnumFlag ()) +CHECK_VALID (false, void, 1 ^ EnumFlag ()) /* operator OP (raw_enum, raw_enum) */ -CHECK_VALID (false, void, RE () | RE2 ()) -CHECK_VALID (false, void, RE () & RE2 ()) -CHECK_VALID (false, void, RE () ^ RE2 ()) -CHECK_VALID (true, RE, RE () | RE ()) -CHECK_VALID (true, RE, RE () & RE ()) -CHECK_VALID (true, RE, RE () ^ RE ()) +CHECK_VALID (false, void, RawEnum () | RawEnum2 ()) +CHECK_VALID (false, void, RawEnum () & RawEnum2 ()) +CHECK_VALID (false, void, RawEnum () ^ RawEnum2 ()) +CHECK_VALID (true, RawEnum, RawEnum () | RawEnum ()) +CHECK_VALID (true, RawEnum, RawEnum () & RawEnum ()) +CHECK_VALID (true, RawEnum, RawEnum () ^ RawEnum ()) /* operator OP (enum_flags, raw_enum) */ -CHECK_VALID (false, void, EF () | RE2 ()) -CHECK_VALID (false, void, EF () & RE2 ()) -CHECK_VALID (false, void, EF () ^ RE2 ()) -CHECK_VALID (true, EF, EF () | RE ()) -CHECK_VALID (true, EF, EF () & RE ()) -CHECK_VALID (true, EF, EF () ^ RE ()) +CHECK_VALID (false, void, EnumFlag () | RawEnum2 ()) +CHECK_VALID (false, void, EnumFlag () & RawEnum2 ()) +CHECK_VALID (false, void, EnumFlag () ^ RawEnum2 ()) +CHECK_VALID (true, EnumFlag, EnumFlag () | RawEnum ()) +CHECK_VALID (true, EnumFlag, EnumFlag () & RawEnum ()) +CHECK_VALID (true, EnumFlag, EnumFlag () ^ RawEnum ()) /* operator OP= (raw_enum, raw_enum), rvalue ref on the lhs. */ -CHECK_VALID (false, void, RE () |= RE2 ()) -CHECK_VALID (false, void, RE () &= RE2 ()) -CHECK_VALID (false, void, RE () ^= RE2 ()) -CHECK_VALID (false, void, RE () |= RE ()) -CHECK_VALID (false, void, RE () &= RE ()) -CHECK_VALID (false, void, RE () ^= RE ()) +CHECK_VALID (false, void, RawEnum () |= RawEnum2 ()) +CHECK_VALID (false, void, RawEnum () &= RawEnum2 ()) +CHECK_VALID (false, void, RawEnum () ^= RawEnum2 ()) +CHECK_VALID (false, void, RawEnum () |= RawEnum ()) +CHECK_VALID (false, void, RawEnum () &= RawEnum ()) +CHECK_VALID (false, void, RawEnum () ^= RawEnum ()) /* operator OP= (raw_enum, raw_enum), lvalue ref on the lhs. */ -CHECK_VALID (false, void, re |= RE2 ()) -CHECK_VALID (false, void, re &= RE2 ()) -CHECK_VALID (false, void, re ^= RE2 ()) -CHECK_VALID (true, RE&, re |= RE ()) -CHECK_VALID (true, RE&, re &= RE ()) -CHECK_VALID (true, RE&, re ^= RE ()) +CHECK_VALID (false, void, re |= RawEnum2 ()) +CHECK_VALID (false, void, re &= RawEnum2 ()) +CHECK_VALID (false, void, re ^= RawEnum2 ()) +CHECK_VALID (true, RawEnum&, re |= RawEnum ()) +CHECK_VALID (true, RawEnum&, re &= RawEnum ()) +CHECK_VALID (true, RawEnum&, re ^= RawEnum ()) /* operator OP= (enum_flags, raw_enum), rvalue ref on the lhs. */ -CHECK_VALID (false, void, EF () |= RE2 ()) -CHECK_VALID (false, void, EF () &= RE2 ()) -CHECK_VALID (false, void, EF () ^= RE2 ()) -CHECK_VALID (false, void, EF () |= RE ()) -CHECK_VALID (false, void, EF () &= RE ()) -CHECK_VALID (false, void, EF () ^= RE ()) +CHECK_VALID (false, void, EnumFlag () |= RawEnum2 ()) +CHECK_VALID (false, void, EnumFlag () &= RawEnum2 ()) +CHECK_VALID (false, void, EnumFlag () ^= RawEnum2 ()) +CHECK_VALID (false, void, EnumFlag () |= RawEnum ()) +CHECK_VALID (false, void, EnumFlag () &= RawEnum ()) +CHECK_VALID (false, void, EnumFlag () ^= RawEnum ()) /* operator OP= (enum_flags, raw_enum), lvalue ref on the lhs. */ -CHECK_VALID (false, void, ef |= RE2 ()) -CHECK_VALID (false, void, ef &= RE2 ()) -CHECK_VALID (false, void, ef ^= RE2 ()) -CHECK_VALID (true, EF&, ef |= EF ()) -CHECK_VALID (true, EF&, ef &= EF ()) -CHECK_VALID (true, EF&, ef ^= EF ()) +CHECK_VALID (false, void, ef |= RawEnum2 ()) +CHECK_VALID (false, void, ef &= RawEnum2 ()) +CHECK_VALID (false, void, ef ^= RawEnum2 ()) +CHECK_VALID (true, EnumFlag&, ef |= EnumFlag ()) +CHECK_VALID (true, EnumFlag&, ef &= EnumFlag ()) +CHECK_VALID (true, EnumFlag&, ef ^= EnumFlag ()) /* operator OP= (enum_flags, enum_flags), rvalue ref on the lhs. */ -CHECK_VALID (false, void, EF () |= EF2 ()) -CHECK_VALID (false, void, EF () &= EF2 ()) -CHECK_VALID (false, void, EF () ^= EF2 ()) -CHECK_VALID (false, void, EF () |= EF ()) -CHECK_VALID (false, void, EF () &= EF ()) -CHECK_VALID (false, void, EF () ^= EF ()) +CHECK_VALID (false, void, EnumFlag () |= EnumFlag2 ()) +CHECK_VALID (false, void, EnumFlag () &= EnumFlag2 ()) +CHECK_VALID (false, void, EnumFlag () ^= EnumFlag2 ()) +CHECK_VALID (false, void, EnumFlag () |= EnumFlag ()) +CHECK_VALID (false, void, EnumFlag () &= EnumFlag ()) +CHECK_VALID (false, void, EnumFlag () ^= EnumFlag ()) /* operator OP= (enum_flags, enum_flags), lvalue ref on the lhs. */ -CHECK_VALID (false, void, ef |= EF2 ()) -CHECK_VALID (false, void, ef &= EF2 ()) -CHECK_VALID (false, void, ef ^= EF2 ()) -CHECK_VALID (true, EF&, ef |= EF ()) -CHECK_VALID (true, EF&, ef &= EF ()) -CHECK_VALID (true, EF&, ef ^= EF ()) +CHECK_VALID (false, void, ef |= EnumFlag2 ()) +CHECK_VALID (false, void, ef &= EnumFlag2 ()) +CHECK_VALID (false, void, ef ^= EnumFlag2 ()) +CHECK_VALID (true, EnumFlag&, ef |= EnumFlag ()) +CHECK_VALID (true, EnumFlag&, ef &= EnumFlag ()) +CHECK_VALID (true, EnumFlag&, ef ^= EnumFlag ()) /* operator~ (raw_enum) */ -CHECK_VALID (false, void, ~RE ()) -CHECK_VALID (true, URE, ~URE ()) +CHECK_VALID (false, void, ~RawEnum ()) +CHECK_VALID (true, UnsignedRawEnum, ~UnsignedRawEnum ()) /* operator~ (enum_flags) */ -CHECK_VALID (false, void, ~EF ()) -CHECK_VALID (true, UEF, ~UEF ()) +CHECK_VALID (false, void, ~EnumFlag ()) +CHECK_VALID (true, UnsignedEnumFlag, ~UnsignedEnumFlag ()) /* Check ternary operator. This exercises implicit conversions. */ -CHECK_VALID (true, EF, true ? EF () : RE ()) -CHECK_VALID (true, EF, true ? RE () : EF ()) +CHECK_VALID (true, EnumFlag, true ? EnumFlag () : RawEnum ()) +CHECK_VALID (true, EnumFlag, true ? RawEnum () : EnumFlag ()) /* These are valid, but it's not a big deal since you won't be able to assign the resulting integer to an enum or an enum_flags without a @@ -246,19 +248,19 @@ CHECK_VALID (true, EF, true ? RE () : EF ()) They've been confirmed to compile/pass with gcc 5.3, gcc 7.1 and clang 3.7. */ -CHECK_VALID (true, int, true ? EF () : EF2 ()) -CHECK_VALID (true, int, true ? EF2 () : EF ()) -CHECK_VALID (true, int, true ? EF () : RE2 ()) -CHECK_VALID (true, int, true ? RE2 () : EF ()) +CHECK_VALID (true, int, true ? EnumFlag () : EnumFlag2 ()) +CHECK_VALID (true, int, true ? EnumFlag2 () : EnumFlag ()) +CHECK_VALID (true, int, true ? EnumFlag () : RawEnum2 ()) +CHECK_VALID (true, int, true ? RawEnum2 () : EnumFlag ()) /* Same, but with an unsigned enum. */ -typedef unsigned int uns; +using uns = unsigned int; -CHECK_VALID (true, uns, true ? EF () : UEF ()) -CHECK_VALID (true, uns, true ? UEF () : EF ()) -CHECK_VALID (true, uns, true ? EF () : URE ()) -CHECK_VALID (true, uns, true ? URE () : EF ()) +CHECK_VALID (true, uns, true ? EnumFlag () : UnsignedEnumFlag ()) +CHECK_VALID (true, uns, true ? UnsignedEnumFlag () : EnumFlag ()) +CHECK_VALID (true, uns, true ? EnumFlag () : UnsignedRawEnum ()) +CHECK_VALID (true, uns, true ? UnsignedRawEnum () : EnumFlag ()) /* Unfortunately this can't work due to the way C++ computes the return type of the ternary conditional operator. int isn't @@ -270,39 +272,39 @@ CHECK_VALID (true, uns, true ? URE () : EF ()) error: operands to ?: have different types ‘enum_flags<RE>’ and ‘int’ Confirmed to work with gcc 4.9, 5.3 and clang 3.7. */ -CHECK_VALID (false, void, true ? EF () : 0) -CHECK_VALID (false, void, true ? 0 : EF ()) +CHECK_VALID (false, void, true ? EnumFlag () : 0) +CHECK_VALID (false, void, true ? 0 : EnumFlag ()) /* Check that the ++/--/<</>>/<<=/>>= operators are deleted. */ -CHECK_VALID (false, void, RE ()++) -CHECK_VALID (false, void, ++RE ()) -CHECK_VALID (false, void, --RE ()) -CHECK_VALID (false, void, RE ()--) +CHECK_VALID (false, void, RawEnum ()++) +CHECK_VALID (false, void, ++RawEnum ()) +CHECK_VALID (false, void, --RawEnum ()) +CHECK_VALID (false, void, RawEnum ()--) -CHECK_VALID (false, void, RE () << 1) -CHECK_VALID (false, void, RE () >> 1) -CHECK_VALID (false, void, EF () << 1) -CHECK_VALID (false, void, EF () >> 1) +CHECK_VALID (false, void, RawEnum () << 1) +CHECK_VALID (false, void, RawEnum () >> 1) +CHECK_VALID (false, void, EnumFlag () << 1) +CHECK_VALID (false, void, EnumFlag () >> 1) -CHECK_VALID (false, void, RE () <<= 1) -CHECK_VALID (false, void, RE () >>= 1) -CHECK_VALID (false, void, EF () <<= 1) -CHECK_VALID (false, void, EF () >>= 1) +CHECK_VALID (false, void, RawEnum () <<= 1) +CHECK_VALID (false, void, RawEnum () >>= 1) +CHECK_VALID (false, void, EnumFlag () <<= 1) +CHECK_VALID (false, void, EnumFlag () >>= 1) /* Test comparison operators. */ -CHECK_VALID (false, void, EF () == EF2 ()) -CHECK_VALID (false, void, EF () == RE2 ()) -CHECK_VALID (false, void, RE () == EF2 ()) +CHECK_VALID (false, void, EnumFlag () == EnumFlag2 ()) +CHECK_VALID (false, void, EnumFlag () == RawEnum2 ()) +CHECK_VALID (false, void, RawEnum () == EnumFlag2 ()) -CHECK_VALID (true, bool, EF (RE (1)) == EF (RE (1))) -CHECK_VALID (true, bool, EF (RE (1)) == RE (1)) -CHECK_VALID (true, bool, RE (1) == EF (RE (1))) +CHECK_VALID (true, bool, EnumFlag (RawEnum (1)) == EnumFlag (RawEnum (1))) +CHECK_VALID (true, bool, EnumFlag (RawEnum (1)) == RawEnum (1)) +CHECK_VALID (true, bool, RawEnum (1) == EnumFlag (RawEnum (1))) -CHECK_VALID (false, void, EF () != EF2 ()) -CHECK_VALID (false, void, EF () != RE2 ()) -CHECK_VALID (false, void, RE () != EF2 ()) +CHECK_VALID (false, void, EnumFlag () != EnumFlag2 ()) +CHECK_VALID (false, void, EnumFlag () != RawEnum2 ()) +CHECK_VALID (false, void, RawEnum () != EnumFlag2 ()) /* Disable -Wenum-compare due to: @@ -323,23 +325,23 @@ CHECK_VALID (false, void, RE () != EF2 ()) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wenum-compare" #endif -CHECK_VALID (true, bool, RE () == RE2 ()) -CHECK_VALID (true, bool, RE () != RE2 ()) +CHECK_VALID (true, bool, RawEnum () == RawEnum2 ()) +CHECK_VALID (true, bool, RawEnum () != RawEnum2 ()) #if defined __GNUC__ # pragma GCC diagnostic pop #endif -CHECK_VALID (true, bool, EF (RE (1)) != EF (RE (2))) -CHECK_VALID (true, bool, EF (RE (1)) != RE (2)) -CHECK_VALID (true, bool, RE (1) != EF (RE (2))) +CHECK_VALID (true, bool, EnumFlag (RawEnum (1)) != EnumFlag (RawEnum (2))) +CHECK_VALID (true, bool, EnumFlag (RawEnum (1)) != RawEnum (2)) +CHECK_VALID (true, bool, RawEnum (1) != EnumFlag (RawEnum (2))) -CHECK_VALID (true, bool, EF () == 0) +CHECK_VALID (true, bool, EnumFlag () == 0) /* Check we didn't disable/delete comparison between non-flags enums and unrelated types by mistake. */ -CHECK_VALID (true, bool, NF (1) == NF (1)) -CHECK_VALID (true, bool, NF (1) == int (1)) -CHECK_VALID (true, bool, NF (1) == char (1)) +CHECK_VALID (true, bool, NonFlagsEnum (1) == NonFlagsEnum (1)) +CHECK_VALID (true, bool, NonFlagsEnum (1) == int (1)) +CHECK_VALID (true, bool, NonFlagsEnum (1) == char (1)) /* -------------------------------------------------------------------- */ diff --git a/gdb/unittests/intrusive_list-selftests.c b/gdb/unittests/intrusive_list-selftests.c index 28d0134..b17ce92 100644 --- a/gdb/unittests/intrusive_list-selftests.c +++ b/gdb/unittests/intrusive_list-selftests.c @@ -570,7 +570,6 @@ struct intrusive_list_test { /* Both lists empty. */ - item_type a ("a"), b ("b"), c ("c"); ListType list1; ListType list2; std::vector<const item_type *> expected; diff --git a/gdb/utils.c b/gdb/utils.c index 17498e0..9431030 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -192,7 +192,7 @@ verror (const char *string, va_list args) /* Emit a message and abort. */ -static void ATTRIBUTE_NORETURN +[[noreturn]] static void abort_with_message (const char *msg) { if (current_ui == NULL) diff --git a/gdb/valops.c b/gdb/valops.c index a0e945c..427fbb1 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -129,8 +129,8 @@ find_function_in_inferior (const char *name, struct objfile **objf_p) } else { - struct bound_minimal_symbol msymbol = - lookup_bound_minimal_symbol (name); + bound_minimal_symbol msymbol + = lookup_minimal_symbol (current_program_space, name); if (msymbol.minsym != NULL) { diff --git a/gdb/value.c b/gdb/value.c index e71f38b..d9b3c6e 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -61,7 +61,7 @@ struct internal_function char *name; /* The handler. */ - internal_function_fn handler; + internal_function_fn_noside handler; /* User data for the handler. */ void *cookie; @@ -1700,25 +1700,7 @@ value::record_latest () the value was taken, and fast watchpoints should be able to assume that a value on the value history never changes. */ if (lazy ()) - { - /* We know that this is a _huge_ array, any attempt to fetch this - is going to cause GDB to throw an error. However, to allow - the array to still be displayed we fetch its contents up to - `max_value_size' and mark anything beyond "unavailable" in - the history. */ - if (m_type->code () == TYPE_CODE_ARRAY - && m_type->length () > max_value_size - && array_length_limiting_element_count.has_value () - && m_enclosing_type == m_type - && calculate_limited_array_length (m_type) <= max_value_size) - m_limited_length = max_value_size; - - fetch_lazy (); - } - - ULONGEST limit = m_limited_length; - if (limit != 0) - mark_bytes_unavailable (limit, m_enclosing_type->length () - limit); + fetch_lazy (); /* Mark the value as recorded in the history for the availability check. */ m_in_history = true; @@ -2336,9 +2318,9 @@ internalvar_name (const struct internalvar *var) static struct internal_function * create_internal_function (const char *name, - internal_function_fn handler, void *cookie) + internal_function_fn_noside handler, void *cookie) { - struct internal_function *ifn = XNEW (struct internal_function); + struct internal_function *ifn = new (struct internal_function); ifn->name = xstrdup (name); ifn->handler = handler; @@ -2362,7 +2344,8 @@ value_internal_function_name (struct value *val) struct value * call_internal_function (struct gdbarch *gdbarch, const struct language_defn *language, - struct value *func, int argc, struct value **argv) + struct value *func, int argc, struct value **argv, + enum noside noside) { struct internal_function *ifn; int result; @@ -2371,7 +2354,7 @@ call_internal_function (struct gdbarch *gdbarch, result = get_internalvar_function (VALUE_INTERNALVAR (func), &ifn); gdb_assert (result); - return (*ifn->handler) (gdbarch, language, ifn->cookie, argc, argv); + return ifn->handler (gdbarch, language, ifn->cookie, argc, argv, noside); } /* The 'function' command. This does nothing -- it is just a @@ -2388,7 +2371,7 @@ function_command (const char *command, int from_tty) static struct cmd_list_element * do_add_internal_function (const char *name, const char *doc, - internal_function_fn handler, void *cookie) + internal_function_fn_noside handler, void *cookie) { struct internal_function *ifn; struct internalvar *var = lookup_internalvar (name); @@ -2403,17 +2386,50 @@ do_add_internal_function (const char *name, const char *doc, void add_internal_function (const char *name, const char *doc, - internal_function_fn handler, void *cookie) + internal_function_fn_noside handler, void *cookie) { do_add_internal_function (name, doc, handler, cookie); } +/* By default, internal functions are assumed to return int. Return a value + with that type to reflect this. If this is not correct for a specific + internal function, it should use an internal_function_fn_noside handler to + bypass this default. */ + +static struct value * +internal_function_default_return_type (struct gdbarch *gdbarch) +{ + return value::zero (builtin_type (gdbarch)->builtin_int, not_lval); +} + +/* See value.h. */ + +void +add_internal_function (const char *name, const char *doc, + internal_function_fn handler, void *cookie) +{ + internal_function_fn_noside fn + = [=] (struct gdbarch *gdbarch, + const struct language_defn *language, + void *_cookie, + int argc, + struct value **argv, + enum noside noside) + { + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return internal_function_default_return_type (gdbarch); + return handler (gdbarch, language, _cookie, argc, argv); + }; + + do_add_internal_function (name, doc, fn, cookie); +} + /* See value.h. */ void add_internal_function (gdb::unique_xmalloc_ptr<char> &&name, gdb::unique_xmalloc_ptr<char> &&doc, - internal_function_fn handler, void *cookie) + internal_function_fn_noside handler, void *cookie) { struct cmd_list_element *cmd = do_add_internal_function (name.get (), doc.get (), handler, cookie); @@ -2426,6 +2442,31 @@ add_internal_function (gdb::unique_xmalloc_ptr<char> &&name, cmd->name_allocated = 1; } +/* See value.h. */ + +void +add_internal_function (gdb::unique_xmalloc_ptr<char> &&name, + gdb::unique_xmalloc_ptr<char> &&doc, + internal_function_fn handler, void *cookie) +{ + internal_function_fn_noside fn + = [=] (struct gdbarch *gdbarch, + const struct language_defn *language, + void *_cookie, + int argc, + struct value **argv, + enum noside noside) + { + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return internal_function_default_return_type (gdbarch); + return handler (gdbarch, language, _cookie, argc, argv); + }; + + add_internal_function (std::forward<gdb::unique_xmalloc_ptr<char>>(name), + std::forward<gdb::unique_xmalloc_ptr<char>>(doc), + fn, cookie); +} + void value::preserve (struct objfile *objfile, htab_t copied_types) { @@ -2933,8 +2974,8 @@ value_static_field (struct type *type, int fieldno) { /* With some compilers, e.g. HP aCC, static data members are reported as non-debuggable symbols. */ - struct bound_minimal_symbol msym - = lookup_minimal_symbol (phys_name, NULL, NULL); + bound_minimal_symbol msym + = lookup_minimal_symbol (current_program_space, phys_name); struct type *field_type = type->field (fieldno).type (); if (!msym.minsym) @@ -3116,13 +3157,13 @@ value_fn_field (struct value **arg1p, struct fn_field *f, struct type *ftype = TYPE_FN_FIELD_TYPE (f, j); const char *physname = TYPE_FN_FIELD_PHYSNAME (f, j); struct symbol *sym; - struct bound_minimal_symbol msym; + bound_minimal_symbol msym; sym = lookup_symbol (physname, nullptr, SEARCH_FUNCTION_DOMAIN, nullptr).symbol; if (sym == nullptr) { - msym = lookup_bound_minimal_symbol (physname); + msym = lookup_minimal_symbol (current_program_space, physname); if (msym.minsym == NULL) return NULL; } @@ -3931,6 +3972,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. */ @@ -4236,7 +4282,8 @@ isvoid_internal_fn (struct gdbarch *gdbarch, static struct value * creal_internal_fn (struct gdbarch *gdbarch, const struct language_defn *language, - void *cookie, int argc, struct value **argv) + void *cookie, int argc, struct value **argv, + enum noside noside) { if (argc != 1) error (_("You must provide one argument for $_creal.")); @@ -4245,6 +4292,8 @@ creal_internal_fn (struct gdbarch *gdbarch, type *ctype = check_typedef (cval->type ()); if (ctype->code () != TYPE_CODE_COMPLEX) error (_("expected a complex number")); + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value::zero (ctype->target_type (), not_lval); return value_real_part (cval); } @@ -4255,7 +4304,7 @@ static struct value * cimag_internal_fn (struct gdbarch *gdbarch, const struct language_defn *language, void *cookie, int argc, - struct value **argv) + struct value **argv, enum noside noside) { if (argc != 1) error (_("You must provide one argument for $_cimag.")); @@ -4264,6 +4313,8 @@ cimag_internal_fn (struct gdbarch *gdbarch, type *ctype = check_typedef (cval->type ()); if (ctype->code () != TYPE_CODE_COMPLEX) error (_("expected a complex number")); + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value::zero (ctype->target_type (), not_lval); return value_imaginary_part (cval); } diff --git a/gdb/value.h b/gdb/value.h index 9d7e88d..13cfb00 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -1598,13 +1598,24 @@ extern struct value *find_function_in_inferior (const char *, extern struct value *value_allocate_space_in_inferior (int); -/* User function handler. */ - -typedef struct value *(*internal_function_fn) (struct gdbarch *gdbarch, - const struct language_defn *language, - void *cookie, - int argc, - struct value **argv); +/* User function handler. The internal_function_fn variant assumes return + type int. The internal_function_fn_noside returns some value with the + return type when passed noside == EVAL_AVOID_SIDE_EFFECTS. */ + +using internal_function_fn + = std::function<struct value *(struct gdbarch *gdbarch, + const struct language_defn *language, + void *cookie, + int argc, + struct value **argv)>; + +using internal_function_fn_noside + = std::function<struct value *(struct gdbarch *gdbarch, + const struct language_defn *language, + void *cookie, + int argc, + struct value **argv, + enum noside noside)>; /* Add a new internal function. NAME is the name of the function; DOC is a documentation string describing the function. HANDLER is @@ -1615,6 +1626,9 @@ typedef struct value *(*internal_function_fn) (struct gdbarch *gdbarch, extern void add_internal_function (const char *name, const char *doc, internal_function_fn handler, void *cookie); +extern void add_internal_function (const char *name, const char *doc, + internal_function_fn_noside handler, + void *cookie); /* This overload takes an allocated documentation string. */ @@ -1622,11 +1636,16 @@ extern void add_internal_function (gdb::unique_xmalloc_ptr<char> &&name, gdb::unique_xmalloc_ptr<char> &&doc, internal_function_fn handler, void *cookie); +extern void add_internal_function (gdb::unique_xmalloc_ptr<char> &&name, + gdb::unique_xmalloc_ptr<char> &&doc, + internal_function_fn_noside handler, + void *cookie); struct value *call_internal_function (struct gdbarch *gdbarch, const struct language_defn *language, struct value *function, - int argc, struct value **argv); + int argc, struct value **argv, + enum noside noside); const char *value_internal_function_name (struct value *); diff --git a/gdb/x86-tdep.c b/gdb/x86-tdep.c index 5d7aa95..e50b5fb 100644 --- a/gdb/x86-tdep.c +++ b/gdb/x86-tdep.c @@ -42,7 +42,7 @@ bool x86_in_indirect_branch_thunk (CORE_ADDR pc, const char * const *register_names, int lo, int hi) { - struct bound_minimal_symbol bmfun = lookup_minimal_symbol_by_pc (pc); + bound_minimal_symbol bmfun = lookup_minimal_symbol_by_pc (pc); if (bmfun.minsym == nullptr) return false; diff --git a/gdb/xml-support.c b/gdb/xml-support.c index b60b2c5..33c8e41 100644 --- a/gdb/xml-support.c +++ b/gdb/xml-support.c @@ -93,8 +93,8 @@ struct gdb_xml_parser ATTRIBUTE_PRINTF (2, 0); /* Issue an error message, and stop parsing. */ - void verror (const char *format, va_list ap) - ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 0); + [[noreturn]] void verror (const char *format, va_list ap) + ATTRIBUTE_PRINTF (2, 0); void body_text (const XML_Char *text, int length); void start_element (const XML_Char *name, const XML_Char **attrs); diff --git a/gdb/xml-support.h b/gdb/xml-support.h index b9bac7a..2ff0e3c 100644 --- a/gdb/xml-support.h +++ b/gdb/xml-support.h @@ -191,8 +191,9 @@ void gdb_xml_debug (struct gdb_xml_parser *parser, const char *format, ...) /* Issue an error message from one of PARSER's handlers, and stop parsing. */ -void gdb_xml_error (struct gdb_xml_parser *parser, const char *format, ...) - ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 3); +[[noreturn]] void gdb_xml_error (struct gdb_xml_parser *parser, + const char *format, ...) + ATTRIBUTE_PRINTF (2, 3); /* Find the attribute named NAME in the set of parsed attributes ATTRIBUTES. Returns NULL if not found. */ diff --git a/gdb/z80-tdep.c b/gdb/z80-tdep.c index 23cdb68..c442b60 100644 --- a/gdb/z80-tdep.c +++ b/gdb/z80-tdep.c @@ -356,8 +356,8 @@ z80_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR pc_beg, CORE_ADDR pc_end, /* stage2: check for FP saving scheme */ if (prologue[pos] == 0xcd) /* call nn */ { - struct bound_minimal_symbol msymbol; - msymbol = lookup_minimal_symbol ("__sdcc_enter_ix", NULL, NULL); + bound_minimal_symbol msymbol + = lookup_minimal_symbol (current_program_space, "__sdcc_enter_ix"); if (msymbol.minsym) { value = msymbol.value_address (); @@ -621,8 +621,8 @@ z80_frame_unwind_cache (const frame_info_ptr &this_frame, break; /* found */ for (i = sizeof(names)/sizeof(*names)-1; i >= 0; --i) { - struct bound_minimal_symbol msymbol; - msymbol = lookup_minimal_symbol (names[i], NULL, NULL); + bound_minimal_symbol msymbol + = lookup_minimal_symbol (current_program_space, names[i]); if (!msymbol.minsym) continue; if (addr == msymbol.value_address ()) @@ -719,8 +719,8 @@ z80_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr) static int addr = -1; if (addr == -1) { - struct bound_minimal_symbol bh; - bh = lookup_minimal_symbol ("_break_handler", NULL, NULL); + bound_minimal_symbol bh + = lookup_minimal_symbol (current_program_space, "_break_handler"); if (bh.minsym) addr = bh.value_address (); else @@ -894,14 +894,13 @@ read_target_long_array (CORE_ADDR memaddr, unsigned int *myaddr, static int z80_read_overlay_region_table () { - struct bound_minimal_symbol novly_regions_msym; - struct bound_minimal_symbol ovly_region_table_msym; struct gdbarch *gdbarch; int word_size; enum bfd_endian byte_order; z80_free_overlay_region_table (); - novly_regions_msym = lookup_minimal_symbol ("_novly_regions", NULL, NULL); + bound_minimal_symbol novly_regions_msym + = lookup_minimal_symbol (current_program_space, "_novly_regions"); if (! novly_regions_msym.minsym) { error (_("Error reading inferior's overlay table: " @@ -910,7 +909,8 @@ z80_read_overlay_region_table () return 0; } - ovly_region_table_msym = lookup_bound_minimal_symbol ("_ovly_region_table"); + bound_minimal_symbol ovly_region_table_msym + = lookup_minimal_symbol (current_program_space, "_ovly_region_table"); if (! ovly_region_table_msym.minsym) { error (_("Error reading inferior's overlay table: couldn't find " |