Andrew Burgess [Wed, 10 Sep 2025 10:04:45 +0000 (11:04 +0100)]
gdb: remove program_space::core_bfd member function
This commit removes the program_space::core_bfd member function, which
was left in place as a temporary hack in the last commit in order to
reduce the size of the last commit.
In every place that 'current_program_space->core_bfd ()' was used I
now call 'get_inferior_core_bfd (current_inferior ())'.
I think there is further scope for improving things in the future,
reducing the number of times we access the core file via global state,
but doing that cleanup might be more involved than the clean up I've
done up to this point. So I'm leaving that work for the future.
But I think in some places, at the top level (e.g. user command
functions), there's always going to be some cases where we just need
to access the current global state, this is just the nature of the
command handlers.
There should be no user visible changes after this commit.
Andrew Burgess [Wed, 8 Oct 2025 10:18:07 +0000 (11:18 +0100)]
gdb: move core file bfd from program_space into core_target
This commit moves the 'gdb_bfd_ref_ptr cbfd' out of program_space and
into core_target, where it is now called m_core_bfd.
I believe this change makes sense as the core_target instance holds
additional information that is parsed from the core file BFD, and so
storing the parsed information separately from the BFD doesn't make
much sense to me.
To minimise the churn in this commit, I have retained the
program_space::core_bfd member function as a temporary hack. This
function forwards the request to the new function
get_inferior_core_bfd. This works fine for now as
program_space::core_bfd is, after this commit, only called on the
current_program_space. If this all seems like a total hack, then it
is, but don't worry too much, the next commit will clean this all up.
I was tempted to make the new function get_inferior_core_bfd, a member
function of the inferior class, inferior::core_bfd. In fact, that
would have been my preferred change. However, the new function needs
visibility of the core_target class, which, right now is private
within the corelow.c file.
This shouldn't be a problem, we could just declare the member function
in inferior.h, and implement the function in corelow.c. But this
would mean the implementation of inferior::core_bfd, would not live in
inferior.c. Previously when I've implemented member functions outside
their natural home (e.g. an inferior function not in inferior.c) I've
received review feedback that this is not desirable. So, for now,
I've gone with a free function.
I also needed to change get_current_core_target, renaming it to
get_core_target, and taking an inferior as an argument. Existing call
sites are updated to pass 'current_inferior ()', but
get_inferior_core_bfd passes something that might not be the current
inferior.
There should be no user visible changes after this commit.
Andrew Burgess [Sun, 28 Sep 2025 15:16:53 +0000 (16:16 +0100)]
gdb: fix for 'set suppress-cli-notifications on' missed case
I noticed this behaviour:
(gdb) info threads
Id Target Id Frame
1 Thread 0xf7dbc700 (LWP 3161872) "thr" 0xf7eb2888 in clone () from /lib/libc.so.6
* 2 Thread 0xf7dbbb40 (LWP 3161884) "thr" breakpt () at thr.c:19
(gdb) set suppress-cli-notifications on
(gdb) thread 1
(gdb) thread 1
[Switching to thread 1 (Thread 0xf7dbc700 (LWP 3161872))]
#0 0xf7eb2888 in clone () from /lib/libc.so.6
(gdb)
I think that the second 'thread 1' should not produce any output just
like the 'inferior' command, continuing in the same GDB session:
(gdb) inferior 1
(gdb)
Without suppress-cli-notifications we would see an inferior, thread,
and frame being printed, but with suppress-cli-notifications set to
on, we get no output.
The difference in behaviours is that in inferior_command (inferior.c),
we always call notify_user_selected_context_changed, even in the case
where the inferior doesn't actually change.
In thread_command (thread.c), we have some code that catches the
thread not changed case, and calls print_selected_thread_frame. The
notify_user_selected_context_changed function is only called if the
thread actually changes.
I did consider simply extending thread_command to check the global
cli_suppress_notification.user_selected_context state and skipping the
call to print_selected_thread_frame if suppression is on.
However, I realised that calling print_selected_thread_frame actually
introduces a bug.
When the 'thread' command is used to select the currently selected
thread, GDB still calls 'thread_selected'. And 'thread_select' always
selects frame #0 within that thread, consider this session:
(gdb) info threads
Id Target Id Frame
1 Thread 0xf7dbc700 (LWP 723986) "thr" 0xf7eb2888 in clone () from /lib/libc.so.6
* 2 Thread 0xf7dbbb40 (LWP 723990) "thr" breakpt () at thr.c:19
(gdb) bt
#0 breakpt () at thr.c:19
#1 0x080491fd in thread_worker (arg=0xffff9514) at thr.c:31
#2 0xf7f7667e in start_thread () from /lib/libpthread.so.0
#3 0xf7eb289a in clone () from /lib/libc.so.6
(gdb) frame 3
#3 0xf7eb289a in clone () from /lib/libc.so.6
(gdb) thread 2
[Switching to thread 2 (Thread 0xf7dbbb40 (LWP 723990))]
#0 breakpt () at thr.c:19
19 while (stop)
(gdb) frame
#0 breakpt () at thr.c:19
19 while (stop)
(gdb)
Notice that the frame resets back to frame #0.
By only calling print_selected_thread_frame, and not calling
notify_user_selected_context_changed, this means that GDB will fail to
emit an MI async notification. It is this async notification which
tells MI consumers that the frame has been reset to #0.
And so, I think that the correct solution is, like with the 'inferior'
command, to always call notify_user_selected_context_changed.
This does mean that in some cases unnecessary MI notifications can be
emitted, however, an MI consumer should be able to handle these. We
could try to avoid these, but we would need to extend thread_command
to check that neither the thread OR frame has changed after the call
to thread_select, and right now, I'm not sure it's worth adding the
extra complexity.
I've rewritten the gdb.base/cli-suppress-notification.exp test to
cover more cases, especially the reselecting the same thread case.
And I've updated the gdb.mi/user-selected-context-sync.exp test to
allow for the additional MI notifications that are emitted, and to
check the frame reset case.
While working on this change, I did wonder about calls to
notify_user_selected_context_changed for frame related commands. In
places we do elide calls to notify_user_selected_context_changed if
the frame hasn't changed. I wondered if there were more bugs here?
I don't think there are though. While changing the inferior will also
change the selected thread, and the selected frame. And changing the
thread will also change the selected frame. Changing the frame is the
"inner most" context related thing that can be changed. There are no
side effect changes that also need to be notified, so for these cases,
I think we are fine.
Also in infrun.c I fixed a code style issue relating to
notify_user_selected_context_changed. It's not a functional change
required by this commit, but it's related to this patch, so I'm
including it here.
Reviewed-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> Tested-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> Approved-By: Tom Tromey <tom@tromey.com>
cris: bfd: Default selected target to the configured target
Whether targ_defvec is set to the best match for the configured target
or some of the other supported targets usually doesn't matter, as the
actual target being used, usually is set by some other mechanism, like
an input object file.
In some situations it matters though: it might be confusing to see
--help output not showing the configured target first in the list of
supported targets. Also, some corner cases risk running into bugs like
PR33485, for cris-elf and cris-linux because cris_aout_vec is the
default target where instead the bug-free behavior of
cris_elf32_us_vec or cris_elf32_vec would be expected.
The test just verifies that the target list emitted for the --help
option has the expected target first.
bfd:
* config.bfd <cris-*-* | crisv32-*-*>: Split into <cris-*-*aout*>,
<cris-*-linux-* | crisv32-*-linux-*>, <cris-*-* | crisv32-*-*> cases
respectively setting targ_defvec per the target instead of always
cris_aout_vec.
binutils:
* testsuite/binutils-all/cris: New directory intended for
tests focused on behavior of the binutils programs, not the assembler
or linker.
* testsuite/binutils-all/cris/cris.exp: New file with run_dump_test
loop.
testsuite/binutils-all/cris/tgt-a.d,
testsuite/binutils-all/cris/tgt-e.d,
testsuite/binutils-all/cris/tgt-l.d: New tests.
Co-authored-by: Maciej W. Rozycki <macro@redhat.com>
Simon Marchi [Wed, 3 Sep 2025 14:50:05 +0000 (10:50 -0400)]
gdbsupport: make reference_to_pointer_iterator's constructor non-variadic
For the same reason as the previous patches (making things easier to
understand, at the cost of being more explicit), change
reference_to_pointer_iterator's constructor to take an already built
underlying iterator.
There are no uses of this utility in the code base right now, so no
callers to update.
Change-Id: Ifadb4c3a5ee53a8d0eb6c0d79efcc92271492e8e Approved-By: Tom Tromey <tom@tromey.com>
Simon Marchi [Wed, 3 Sep 2025 14:50:04 +0000 (10:50 -0400)]
gdbsupport: remove variadicity from filtered_iterator constructor
For the same reason as the previous patches (making things easier to
understand, at the cost of being more explicit), remove
filtered_iterator's variadic constructor, forcing the callers to pass
already built underlying iterators.
Change-Id: I1a9b6d43f3f087579b61b90b6f8f4128d66e19a1 Approved-By: Tom Tromey <tom@tromey.com>
Simon Marchi [Wed, 3 Sep 2025 14:50:03 +0000 (10:50 -0400)]
gdbsupport: remove variadicity from basic_safe_iterator constructors
Change the constructors to accept `Iterator` objects directly. This
requires the callers to explicitly pass `Iterator` object (unless
perhaps `Iterator` has a non-explicit one-argument constructor.
The rationale is the same as the previous patch: make the code easier to
follow and make it easier to fix build errors, at the expense of making
callers more explicit.
Change-Id: Icd2a4ef971456ca250f96227a9b83c935d619451 Approved-By: Tom Tromey <tom@tromey.com>
Simon Marchi [Wed, 3 Sep 2025 14:50:02 +0000 (10:50 -0400)]
gdbsupport: remove variadicity from iterator_range constructor
There are two ways to build an iterator_range:
- Using the variadic constructor, where the arguments you pass are used
to construct the "begin" underlying iterator. The "end" iterator is
obtained by default-constructing the underlying iterator.
- Using the other constructor, by explicitly providing the "begin" and
"end" iterators.
My experience is that using the variadic constructor is very confusing,
especially when you have multiple layers of iterator wrappers. It's not
obvious where the arguments you provide end up. When you have a
compilation error, it is hard to decipher.
I propose to remove the variadicity of the first constructor of
iterator_range, and subsequently of the other iterator wrappers. This
requires callers to be more verbose, explicitly instantiate all the
layers. But since we only instantiate these iterator wrappers in
factory functions, I think it's fine. If there is a compilation error,
it will be much easier to find and fix the problem.
Using the new one-argument constructor, it is still assumed that the end
iterator can be obtained by default-constructing the underlying iterator
type, which I think is fine and not too confusing.
Change-Id: I54d6fdef18bcd7e308825064e0fc18fadd7ca717 Approved-By: Tom Tromey <tom@tromey.com>
Simon Marchi [Wed, 3 Sep 2025 14:49:57 +0000 (10:49 -0400)]
gdb: change inf_threads_iterator to yield references
When adding reference_to_pointer_iterator, I saw it as a temporary
thing, to not have to do a codebase-wide change right away. Remove it
from inf_threads_iterator and adjust all the users.
It's very possible that I forgot to update some spots in the files I
can't compile, but it will be very easy to fix if that happens.
Change-Id: Iddc462fecfaafb6a9861d185b217bc714e7dc651 Approved-By: Tom Tromey <tom@tromey.com>
Andrew Burgess [Sun, 5 Oct 2025 17:51:12 +0000 (18:51 +0100)]
gdb/python: make use of gdb.Style for shipped Python commands
With the recent addition of the gdb.Style Python API, this commit goes
through the gdb.Command sub-classes which we ship with GDB and adds
some styling support.
This adds 'title' style in a couple of places where we layout tables.
And uses 'filename' style where we are printing filenames.
While I was making these changes I've made a couple of related fixes.
In 'info frame-filter', 'info missing-objfile-handlers', 'info
pretty-printer', and 'info xmethod', we would sometimes print the
gdb.Progspace.filename unconditionally, even though this field can
sometimes be None. To better handle this case, I now check for None,
and print '<no-file>' instead. We already printed that same string
for the program space name in at least one other case, so this change
makes things a little more consistent.
I don't format the '<no-file>' string with the filename style, only if
we have an actual filename does the string get formatted.
The other fix I made was in 'maint info python-disassemblers'. Here
I've added an extra space between the two columns in the output
table. The two columns are 'Architecture' and 'Disassembler Name'.
Given that one column contains a white space, it was rather confusing
having a single space between columns. Luckily the tests don't depend
on a single space, so nothing needs updating for this change.
Additionally, in 'info frame-filter' I've updated the exception
handling to use the gdb.warning function, rather than just printing a
line of output. This means that should this case occur we get the
neat little emoji. We have no tests that trigger this warning, and I
couldn't figure out how to write one. In this end, I just hacked the
Python code to raise an exception and checked the output looked
reasonable. I suspect this warning might be a hard one to trigger!
Tom Tromey [Fri, 3 Oct 2025 16:59:29 +0000 (10:59 -0600)]
Ignore artificial fields in Ada
A user found an unusual Ada situation that DWARF does not readily
support. Consider this type:
type Discrete_Typ is tagged null record;
type Int_Typ (Is_Static : Boolean) is new Discrete_Typ with null record;
type Signed_Int_Typ (Is_Static : Boolean) is
new Int_Typ (Is_Static => Is_Static)
with record
case Is_Static is
when True =>
Field : Integer;
when others =>
null;
end case;
end record;
Here, Signed_Int_Typ has a variant part where the discriminant is
stored in a superclass.
Anyway, this code caused gnat-llvm to crash. While fixing the crash,
I decided to fix this by emitting an anonymous field in Signed_Int_Typ
that represents the discriminant. This would allow member DIEs to
refer to it -- which I suppose is possibly why DWARF specified that
the discriminant should be a member of the variant (though I don't
really know; this decision always seemed very strange to me).
Making the field anonymous lead to the strange error:
Type ... is not a structure or union type.
... which comes from lookup_struct_elt, which fails when an anonymous
member of a structure has a non-composite type. This patch includes a
fix for this issue.
After fixing that, though I decided it would be better if the
artificial discriminant were still given a name. So, this patch
includes a change to ada_is_ignored_field to ignore artificial fields.
Tom Tromey [Tue, 7 Oct 2025 14:13:44 +0000 (08:13 -0600)]
Fix compile-ops.exp
The recent change to change the parsing of location expressions in the
test suite broke compile-ops.exp. I neglected to update that patch.
This patch fixes the oversight.
Tom de Vries [Tue, 7 Oct 2025 08:25:57 +0000 (10:25 +0200)]
[gdb/symtab] Improve invalid range check in create_addrmap_from_gdb_index
When running test-case gdb.tui/tui-missing-src.exp with target board
gold-gdb-index (and likewise fission and fission-dwp) on aarch64-linux, I run
into:
...
FAIL: gdb.tui/tui-missing-src.exp: checking if inside f2 ()
...
The address range for f2 is [0x400694, 0x4006b8), but the address table says
it's [0x40053f, 0x400563).
The address 0x40053f is not even in a section:
...
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
...
[12] .plt PROGBITS 00000000004004b8 0004b8 000050 10 AX 0 0 8
[13] .text PROGBITS 0000000000400540 000540 000178 00 AX 0 0 64
...
but part of the hole [0x400508, 0x400540) in between .plt and .text.
Detect this in the invalid range check in create_addrmap_from_gdb_index.
Tested on aarch64-linux.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
MIPS/BFD: Fix rightshift for remaining n32 reloc howtos
Correct the rightshift amount for the R_MIPS_HIGHER, R_MIPS_HIGHEST and
R_MIPS_CALL_HI16 RELA relocation howtos, missed with commit f38e9921479a
("MIPS HI16 and LO16 reloc howtos").
On VxWorks calls can refer directly to a .got.plt entry, in which case
they won't have an entry in the regular GOT. It was missed with commit 6c42ddb92b90 ("MIPS GOT: Remove TLS GOT info from the symbol table"),
<https://inbox.sourceware.org/binutils/878v6uyaw3.fsf@talisman.default/>,
which revamped GOT entry bookkeeping, and consequently space for regular
GOT entries is needlessly reserved and then not used, with extraneous
null dynamic relocations attached, e.g.:
MIPS/LD/testsuite: Adapt VxWorks segment matching for PR ld/20815 fix
Adjust segment addresses in the program header dump to account for the
inclusion of the program headers in the segment, removing a regression
from commit 1a9ccd70f9a7 ("Fix the linker so that it will not silently
generate ELF binaries with invalid program headers. Fix readelf to
report such invalid binaries."):
mips-vxworks -FAIL: VxWorks executable test 2 (dynamic)
mipsel-vxworks -FAIL: VxWorks executable test 2 (dynamic)
IA-64/GAS: Work around format truncation compilation errors
Work around compilation errors:
.../gas/config/tc-ia64.c: In function 'declare_register_set':
.../gas/config/tc-ia64.c:5375:41: error: '%u' directive output may be truncated writing between 1 and 10 bytes into a region of size 8 [-Werror=format-truncation=]
5375 | snprintf (name, sizeof (name), "%s%u", prefix, i);
| ^~
.../gas/config/tc-ia64.c:5375:38: note: directive argument in the range [0, 4294967294]
5375 | snprintf (name, sizeof (name), "%s%u", prefix, i);
| ^~~~~~
.../gas/config/tc-ia64.c:5375:7: note: 'snprintf' output 2 or more bytes (assuming 11) into a destination of size 8
5375 | snprintf (name, sizeof (name), "%s%u", prefix, i);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
observed with GCC 10. Pick 16 for a round 64-bit stack frame size.
Matthieu Longo [Mon, 21 Jul 2025 11:01:26 +0000 (12:01 +0100)]
aarch64: GICv5 hypervisor control system registers
This patch adds support for hypervisor control registers on AArch64,
available via the Generic Interrupt Controller v5 feature, and enabled
via the +gcie flag.
Also, the new system register 'icc_ppi_priorityr8_el1' clashed with the
encoding of 's3_0_c12_c15_0' used in a test for the generic syntax of
system registers using mrs and msr.
This patch replaces 's3_0_c12_c15_0' in the test by an unused encoding:
s3_7_c0_c15_0.
Matthieu Longo [Fri, 18 Jul 2025 15:47:44 +0000 (16:47 +0100)]
aarch64: GICv5 CPU interface system registers
This patch adds support for 13 new AArch64 system registers for the CPU
interface, which are enabled on using Generic Interrupt Controller v5
(+gcie flag) feature:
- 7 R/W registers: ICC_APR_EL1, ICC_APR_EL3, ICC_CR0_EL1, ICC_CR0_EL3
ICC_ICSR_EL1, ICC_PCR_EL1, ICC_PCR_EL3.
- 6 RO registers: ICC_DOMHPPIR_EL3, ICC_HAPR_EL1, ICC_HPPIR_EL1,
ICC_HPPIR_EL3, ICC_IAFFIDR_EL1, ICC_IDR0_EL1.
Note: the already-existing ID_AA64PFR2_EL1 register is required by the
GICv5 feature.
Add new instructions from the Generic Interrupt Controller, GICv5,
extension. These instructions are aliases to system instructions and are
the following:
Generic Interrupt Controller v5, GICv5, adds new system registers
and system instructions. These are enabled with the +gcie flag, where
gcie stands for GICv5 (Generic Interrupt Controller) CPU Interrupt
Extension.
Andrew Burgess [Mon, 25 Aug 2025 15:48:22 +0000 (16:48 +0100)]
gdb/python: add Corefile.mapped_files method
Add a new Corefile.mapped_files method which returns a list of
gdb.CorefileMappedFile objects.
Each gdb.CorefileMappedFile object represents a file that was mapped
into the process when the core file was created.
A gdb.CorefileMappedFile has attributes:
+ filename -- A string, the name of the mapped file.
+ build_id -- A string or None, the build-id of the mapped file if
GDB could find it (None if not).
+ is_main_executable -- A boolean, True if this mapping is the main
executable.
+ regions -- A list containing the regions of this file that were
mapped into the process.
The 'regions' list is a list of gdb.CorefileMappedFileRegion objects,
each of these objects has the following attributes:
+ start -- the start address within the inferior.
+ end -- the end address within the inferior.
+ file_offset -- the offset within the mapped file for this mapping.
Andrew Burgess [Mon, 25 Aug 2025 15:47:20 +0000 (16:47 +0100)]
gdb: make structured core file mappings processing global
In corelow.c, within core_target::build_file_mappings, we have code
that wraps around a call to gdbarch_read_core_file_mappings and
provides more structure to the results.
Specifically, gdbarch_read_core_file_mappings calls a callback once
for every region of every mapped file. The wrapper code groups all of
the mappings for one file into an instance of 'struct mapped_file',
this allows all of the mapped regions to be associated with the
build-id and filename of a file.
In the next commit I plan to make this information available via the
Python API, and so I need to allow access to this structured wrapping
outside of corelow.c.
This commit renames 'struct mapped_file' to 'struct core_mapped_file'
and moves the struct into gdbcore.h. Then a new global function
gdb_read_core_file_mappings is created into which I move the code to
build the structured data.
Then corelow.c is updated to call gdb_read_core_file_mappings.
This commit does not extend the Python API, that is for the next
commit.
There should be no user visible changes after this commit.
Andrew Burgess [Thu, 21 Aug 2025 08:45:18 +0000 (09:45 +0100)]
gdb/python: introduce gdb.Corefile API
This commit starts adding some core file related features to the
Python API.
In this initial commit I've tried to keep the changes as small as
possible for easy review.
There's a new Python class gdb.Corefile, which represents a loaded
core file. This API doesn't allow the user to create their own
gdb.Corefile objects, a core file must be loaded using the 'core-file'
command, then a gdb.Corefile object can be obtained by querying the
inferior in which the core file was loaded.
There's a new attribute gdb.Inferior.corefile, this is None when no
core file is loaded, or contains a gdb.Corefile object if a core file
has been loaded.
Currently, the gdb.Corefile object has one attribute, and one method,
these are:
gdb.Corefile.filename -- the file name of the loaded core file.
gdb.Corefile.is_valid() -- indicates if a gdb.Corefile object is
valid or not. See notes below.
A gdb.Corefile object is only valid while the corresponding core file
is loaded into an inferior. Unloading the core file, or loading a
different one will cause a gdb.Corefile object to become invalid. For
example:
In order to track changes to the core file, there is a new observable
'core_file_changed', which accounts for the changes in corelow.c,
observable,c, and observable.h. Currently, this observable is not
visible as a Python event.
I chose to access the core file via the inferior even though the core
file BFD object is actually stored within the program_space. As such,
it might seem that the natural choice would be to add the attribute as
gdb.Progspace.corefile.
This patch was never merged, it is still on my backlog, but the
observation in that work is that some targets are not really
shareable. For example, the core_target (corelow.c) stores
information about the loaded core file within the target instance. As
such, each target instance represents a single loaded core file.
Except that the BFD part of the core file is stored in the
program_space, which is a little weird.
During review, Tom made the observation, that maybe we should
investigate moving the core file BFD into the core_target. I'm
inclined to agree with this as a direction of travel.
All this leaves us with two observations:
1. Currently, loading a core file into an inferior, then using
'add-inferior' will try to share the core_target between
inferiors. This is broken, and can trigger GDB crashes. The
obvious fix, without reworking core_target, is just to prevent
this sharing, making core_target per-inferior.
2. Having the core file information split between the core_target
instance, and the BFD stored in the program_space is a little
weird, and is really just historical. Planning for a future
where the BFD is also stored in the core_target might be wise.
So, if we imagine that the BFD is (one day) moved into the
core_target, and that the core_target really becomes non-shareable,
then it is, I think, clearer that the corefile attribute should live
on the gdb.Inferior object, not the gdb.Progspace object.
There's testing for all the functionality added in this commit.
Tom Tromey [Tue, 16 Sep 2025 20:33:15 +0000 (14:33 -0600)]
Make location expressions be code in DWARF assembler
Currently the DWARF assembler implements manual parsing for location
expressions. With a recent refactoring, this lead to the use of
[subst] in a number of places.
Following the same logic as the DW_AT_* change, this patch changes
location expressions to simply be nested Tcl code. This avoids the
need for subst and also allows more complex logic, should that ever be
needed.
Tom Tromey [Tue, 16 Sep 2025 19:48:18 +0000 (13:48 -0600)]
Store the "uplevel" target in DWARF assembler
This changes the DWARF assembler to store the desired "uplevel" frame
in Dwarf::assemble. This frame is then used in the relevant "uplevel"
invocations in the assembler.
This is primarily useful for the next patch, but it also seems
somewhat cleaner in general to me, as the implementation can now be
refactored without worrying too much about introducing new stack
frames.
timurgol007 [Mon, 6 Oct 2025 11:35:44 +0000 (14:35 +0300)]
gdb: tidy RISC-V part in gdb/Makefile.in and gdb/configure.tgt
I noticed that the length of line in gdb/configure.tgt was more than
80 lines, so I straightened it out. Also, in gdb/Makefile.in newly added
file riscv-linux-canonicalize-syscall-gen.c was missed in ALLDEPFILES,
so I added it there. And the last change: one more file
riscv-linux-canonicalize-syscall-gen.o was not in alphabetical order.
Alan Modra [Mon, 6 Oct 2025 02:31:19 +0000 (13:01 +1030)]
segv in debug_write_type
In commit 6c3458a8b7ee I claimed that u.kenum is always non-NULL,
which is true for debug_make_enum_type, but not for enums made by
debug_make_undefined_tagged_type. Fix that oversight
Alan Modra [Sun, 5 Oct 2025 22:38:26 +0000 (09:08 +1030)]
readelf reloc range check
A fuzzed object file hit this sanitizer error.
readelf.c:16764:9: runtime error: pointer index expression with base
0x6dd4491e1590 overflowed to 0xe7af96d4491e17a1
The same could occur in any of the IN_RANGE reloc checks, where the
reloc address is calculated as "start + r_offset" then compared
against "start" and "end". So don't do that. Compare r_offset
against the memory size, first.
* readelf.c (IN_RANGE): Delete.
(in_range): New inline funcion.
(target_specific_reloc_handling): Replace "end" param with
"size". Update uses. Replace IN_RANGE with in_range.
(apply_relocations): Delete "end" variable. Update
target_specific_reloc_handling calls and replace IN_RANGE.
Avoid pointer overflow.
Alan Modra [Sun, 5 Oct 2025 23:23:03 +0000 (09:53 +1030)]
msp430: extended_dst disassembly
This avoids a gcc-14.2 bug reporting an "error: null destination
pointer" on an sprintf buffer that is not NULL. Don't ask me why this
happens to work.
* msp430-dis.c (msp430_singleoperand): Don't overprint op or
comm for extended_dst.
Tom Tromey [Sun, 14 Sep 2025 21:20:25 +0000 (15:20 -0600)]
Rework domain choices in ctfread.c
Another patch I am working on induced some failures in CTF tests.
Looking into this, I found that ctfread.c seems to largely work by
accident. In particular, it often chooses the wrong domain for a
symbol.
In CTF, I believe there are 4 kinds of symbols: types, variables,
functions, and "data objects" (which IIUC may be either a variable or
a function).
ctfread.c was examining the type-kind of a variable and sometimes
treating one as a type. add_stt_entries and
ctf_psymtab_add_stt_entries only ever used VAR_DOMAIN (but are called
for functions, which should be in FUNCTION_DOMAIN). And
ctf_psymtab_type_cb sometimes used VAR_DOMAIN, but is only called for
types, and so should only ever use TYPE_DOMAIN or STRUCT_DOMAIN.
This patch cleans all this up, based on my understanding of the
situation. This passes the existing tests, and also works with my
aforementioned yet-to-be-submitted patch as well.
Finally, I renamed new_symbol because it is only used for type
symbols.
Acked-By: Simon Marchi <simon.marchi@efficios.com>
Tom Tromey [Sat, 13 Sep 2025 21:32:50 +0000 (15:32 -0600)]
Fix name checks in ctfread.c
I noticed that ctfread.c could create a symbol with the name "". This
happens because a couple of spots check that a name is not NULL -- but
libctf never returns such names. Instead check the string contents.
I left the NULL checks in for robustness.
Note that other spots in ctfread.c already do check the contents of
the name. I changed these to avoid strlen and instead check the first
character.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
Andrew Burgess [Tue, 17 Jun 2025 17:09:49 +0000 (18:09 +0100)]
gdb/python: extend gdb.write to support styled output
It is already possible to produce styled output from Python by
converting the gdb.Style to its escape code sequence, and writing that
to the output stream.
But this commit adds an alternative option to the mix by extending the
existing gdb.write() function to accept a 'style' argument. The value
of this argument can be 'None' to indicate no style change should be
performed, this is the default, and matches the existing behaviour.
Or the new 'style' argument can be a gdb.Style object, in which case
the specified style is applied only for the string passed to
gdb.write, after which the default style is re-applied.
Using gdb.write with a style object more closely matches how GDB
handles styling internally, and has the benefit that the user doesn't
need to remember to restore the default style when they are done.
Reviewed-By: Eli Zaretskii <eliz@gnu.org> Approved-By: Tom Tromey <tom@tromey.com>
Andrew Burgess [Wed, 23 Apr 2025 13:51:17 +0000 (14:51 +0100)]
gdb/python: new class gdb.StyleParameterSet
Add a new helper class gdb.StyleParameterSet. This new class can be
used to simplify creation of new style parameter sets. A style
parameter set is the 'foreground', 'background', and (optionally), the
'intensity' settings, all grouped under a single prefix command.
And example usage is:
(gdb) python s = gdb.StyleParameterSet("my-style")
(gdb) show style my-style
style my-style background: The "my-style" style background color is: none
style my-style foreground: The "my-style" style foreground color is: none
style my-style intensity: The "my-style" style display intensity is: normal
(gdb)
Having created a gdb.StyleParameterSet, the object itself can be used
to access a named style corresponding to the setting group, like this:
Of course, having access to the gdb.Style makes it easy to change the
settings, or the settings can be adjusted via the normal CLI 'set'
commands.
As gdb.StyleParameterSet manages a set of parameters, and the
gdb.Parameter class uses Parameter.value as the attribute to read the
parameter's value, there is also StyleParameterSet.value, but this is
just an alias for StyleParameterSet.style, that is, it allows the
gdb.Style object to be read and written too.
It is worth noting that this class only creates a single level of
prefix command. As an example GDB has style 'disassembler mnemonic',
where the 'disassembler' part is a group of related styles. If a user
wanted to create:
style
my-style-group
style-1
style-2
style-3
Where each of 'style-1', 'style-2', and 'style-3' will have the full
set of 'foreground', 'background', and 'intensity', then the
gdb.StyleParameterSet can be used to create the 'style-N' part, but
the user will have to create the 'my-style-group' prefix themselves,
possibly using gdb.ParameterPrefix, e.g.:
Andrew Burgess [Fri, 18 Apr 2025 13:24:03 +0000 (14:24 +0100)]
gdb/python: add gdb.Style class
This commit adds a new gdb.Style class. This class represents a
complete style within GDB. A complete style is a collection of
foreground color, background color, and an intensity.
A gdb.Style comes in two flavours, named, and unnamed.
A named style is one that is based on an existing style within GDB.
For example, we have 'set style filename ...', the name of this style
is 'filename'. We also have 'set style disassembler mnemonic ...',
the name of this style is 'disassembler mnemonic'. A named style is
created by passing the name of the style, like this:
The other type of style is an unnamed style. An unnamed style is
created using a foreground and background color, along with an
intensity. Colors are specified using gdb.Color objects. An example
of creating an unnamed style is:
We can see here an example of the new intensity constants that have
been added in this commit, there is gdb.INTENSITY_NORMAL,
gdb.INTENSITY_BOLD, and gdb.INTENSITY_DIM. All of the arguments are
optional, the default for the colors is gdb.Color(), which will apply
the terminal default, and the default intensity is
gdb.INTENSITY_NORMAL.
Having created a gdb.Style object there are two ways that it can be
used to style GDB's output. The Style.escape_sequence() method
returns the escape sequence needed to apply this style, this can be
used as in:
The problem with this approach is that it is the users responsibility
to restore the style to the default when they are done. In the above
example, all output after the escape sequence is printed, including
the next GDB prompt, will be in the s1 (filename) style. Which is why
the Style.apply method exists. This method takes a string and returns
the same string with escape sequences added before and after. The
before sequence switches to the style, while the after escape sequence
restores the terminal default style. This can be used like:
(gdb) python print(s1.apply("Filename Style"))
Now only the 'Filename Style' text will be styled. The next GDB
prompt will be in the default terminal style. Personally, I think the
apply method is the more useful, but having 'escape_sequence' matches
what gdb.Color offers, though if/when this patch is merged, I might
propose a similar 'apply' type method for the gdb.Color class.
The gdb.Style class has 'foreground', 'background', and 'intensity'
attributes which, when read, return the obvious values. These
attributes can also be written too.
When writing to an attribute of an unnamed Style object then the Style
object itself is updated, as you might expect.
When writing to an attribute of a named Style then the style setting
itself is updated as the following example shows:
(gdb) python s1 = gdb.Style("filename")
(gdb) python print(s1.foreground)
green
(gdb) show style filename foreground
The "filename" style foreground color is: green
(gdb) python s1.foreground=gdb.Color("red")
(gdb) python print(s1.foreground)
red
(gdb) show style filename foreground
The "filename" style foreground color is: red
(gdb)
We can see that a gdb.Style object is connected to the underlying
style settings, it doesn't take a copy of the style settings at
creation time. And the relationship works both ways. Continuing the
above example:
(gdb) set style filename foreground blue
(gdb) python print(s1.foreground)
blue
(gdb)
Here we see that changing the setting value causes the gdb.Style
object to update. And this is what you would want. I imagine this
being used in a Python extension to GDB, where a user might create
global objects for some named styles, and then use these globals to
format output from some custom commands. If a user of an extension
changes a style setting then the extension wants to adapt to that
change.
Both the Style.escape_sequence and Style.apply methods take the global
style enabled setting into consideration. If styling is disabled then
Style.escape_sequence will return an empty string, and Style.apply
will return an unmodified copy of the original string object (actually
the input object with Py_INCREF applied).
There is also support for representing a gdb.Style as a string:
This is the binutils fix for PR 33384. Here we are assuming that no
const char* comma-separated option strings are passed in to
disassemble_info.disassembler_options. That is true for current usage
in gdb and binutils. In fact, there is only one place that passes a
string in read-only memory, gdb/tdep-i386.c:disassembly_flavor, and
that one is a single option.
include/
* dis-asm.h (struct disassemble_info): Comment.
(disassembler_options_cmp, next_disassembler_option),
(FOR_EACH_DISASSEMBLER_OPTION): Delete.
(for_each_disassembler_option): Declare.
opcodes/
* disassemble.c (disassembler_options_cmp): Delete.
(for_each_disassembler_option): New function.
* arc-dis.c (parse_option): Replace disassembler_options_cmp
with strcmp.
(parse_cpu_option): Likewise.
(parse_disassembler_options): Replace FOR_EACH_DISASSEMBLER_OPTION
with for_each_disassembler_option, and extract loop body to..
(arc_parse_option): ..this new function.
* arm-dis.c (parse_arm_disassembler_options): Delete, extracting
loop body to..
(arm_parse_option): ..this new function.
(print_insn): Use for_each_disassembler_option.
* csky-dis.c (parse_csky_dis_options): Delete, extracting loop
body to..
(parse_csky_option): ..this new function.
(print_insn_csky): Use for_each_disassembler_option.
* nfp-dis.c (parse_disassembler_options): Replace
FOR_EACH_DISASSEMBLER_OPTION with for_each_disassembler_option,
and extract loop body to..
(nfp_parse_option): ..this new function. Use opcodes_error_handler
here rather than info->fprintf_func to print error.
* ppc-dis.c (ppc_parse_cpu): Replace disassembler_options_cmp
with strcmp.
(struct ppc_parse_data): New.
(powerpc_init_dialect): Adjust to use new struct. Replace
FOR_EACH_DISASSEMBLER_OPTION with for_each_disassembler_option,
and extract loop body to..
(ppc_parse_option): ..this new function.
Alan Modra [Fri, 3 Oct 2025 23:14:58 +0000 (08:44 +0930)]
gdb: PR 33384 invalid disassembler option message
This is the gdb part of fixing PR33384, where it is noted that an
error in a disassembler option prints the rest of the comma separated
option string rather than just the option in error.
Removing FOR_EACH_DISASSEMBLER_OPTION seemed a good idea to me, as we
then expose the strchr there which is useful in zero terminating the
option, and in the case of arm-tdep.c, to replace strcspn. Also, if
the option is zero terminated we don't need disassembler_options_cmp.
Alternatively, you could do similarly to arm-tdep.c in disasm.c by
changing the error message to use %.*s with a length found by strcspn.
I rejected that smaller patch on the grounds that it makes for churn
in message translation. I also prefer to see code using the standard
string functions.
Regression tested on x86_64-linux. Message behaviour tested on
powerpc64le-linux and arm-linux-eabi.
* arm-tdep.c (show_disassembly_style_sfunc): Don't use
FOR_EACH_DISASSEMBLER_OPTION. Use strchr needed for loop
control to size option len.
* disasm.c (set_disassembler_options): Don't use
FOR_EACH_DISASSEMBLER_OPTION. Overwrite comma in options with
a zero. Replace disassembler_options_cmp with strcmp.
Alan Modra [Fri, 3 Oct 2025 23:09:02 +0000 (08:39 +0930)]
mips gas: expression initialisation
There is a make_expr_symbol in append_insn, which gets called from
macro_build, which is all over the place. Many of these set up an
expression without initialising all fields. Now the uninitialised
fields should not be accessed in a properly functioning assembler,
but I'm inclined to think anything copied ought to be initialised.
* config/tc-mips.c (fix_loongson2f_jump, load_register),
(add_got_offset, add_got_offset_hilo, macro_build_branch_likely),
(macro, mips16_macro, s_cpload, s_cpsetup, s_cprestore)
(s_cpreturn): Use structure initialiser to ensure all fields of
expression are initialised.
(load_address): Copy entire structure for the same reason.
Alan Modra [Fri, 3 Oct 2025 23:07:37 +0000 (08:37 +0930)]
gas: more expression initialisation
There are many more places that copy an uninitialised expressionS to a
symbol via symbol_set_value_expression and make_expr_symbol. This
patch focuses on general gas code that does that, and a few backends.
Note that unlike the i386 case that oss-fuzz found, it is likely that
the tc-alpha.c, tc-ppc.c and tc-tic54x.c changes are not fixing bugs,
alpha and tic54x because they don't use X_md, ppc because it carefully
handles X_md. Also, as an example an O_constant expression should
only ever have its X_add_number field accessed, therefore the other
fields can stay uninitialised. However, I think that copying
uninitialised struct fields around is not good practice. If nothing
else it can be confusing when examining symbols under gdb.
I also replaced gen-sframe.c "#ifdef SFRAME_FRE_TYPE_SELECTION_OPT"
with "if (SFRAME_FRE_TYPE_SELECTION_OPT)" so code in the false
branches is compiled and thus less likely to bitrot. (As far as I can
see, SFRAME_FRE_TYPE_SELECTION_OPT is always 1.)
Alan Modra [Fri, 3 Oct 2025 23:07:02 +0000 (08:37 +0930)]
gas: initialisation of expressionS in operand()
This patch removes clean_up_expression which runs just before operand()
returns. clean_up_expression sets as yet uninitialised fields of
expressionS. Well, it sets fields based on the value of X_op,
trusting that others have been written, and has one notable exception:
X_md is not initialised.
Instead initialise expressionS fully inside operand(), which is called
at the start of expr(), and introduce md_expr_init for the odd
backends that want to mess with X_md.
This is in response to an oss-fuzz report that read.c:pseudo_set calls
expr() leaving exp.X_md uninitialised and can copy that to a symbol
via symbol_set_value_expression. tc-i386-intel.c:565 is one place
that later tests the uninitialised X_md.
* config/tc-z80.h (md_expr_init, md_expr_init_rest): Define.
* config/tc-microblaze.h: Likewise.
* expr.c (clean_up_expression): Delete.
(operand): Init expression early.
(expr): Use md_expr_init_rest to init X_md when necessary.
Alan Modra [Fri, 3 Oct 2025 23:06:22 +0000 (08:36 +0930)]
arc gas: don't use X_md as input to expression()
tc-arc.c:tokenize_arguments tweaks expression() parsing, controlling
whether arc_parse_name does anything by setting X_op and X_md in the
expressionS argument passed to expression(). I want to change expr()
to always fully initialise its result, and that means either a special
expression initialiser for arc, or controlling arc_parse_name by some
other means. Since arc_parse_name already tests "assembling_insn" and
no other code does, change "assembling_insn" to directly control
arc_parse_name. Doing it this way also stops a possible uninitialised
access to right.X_op from expr() in arc_parse_name with current gas.
The next patch in this series will also stop such uninitialised
accesses.
* config/tc-arc.c (assembling_insn): Update comment.
(tokenize_arguments): Don't set X_op and X_md to control
expression(), instead just use assembling_insn.
(md_operand): Similarly.
(arc_parse_name): Don't test X_op and X_md.
(md_assemble): Don't set assembling_insn here.
Tom de Vries [Sat, 4 Oct 2025 00:07:16 +0000 (02:07 +0200)]
[gdb] Fix assertion failure due to null frame
PR gdb/33512 reports an assertion failure in test-case
gdb.ada/access_to_packed_array.exp on i386-linux:
...
(gdb) maint print symbols
gdb/frame.c:3400: internal-error: reinflate: \
Assertion `m_cached_level >= -1' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n) FAIL: $exp: \
maint print symbols (GDB internal error)
...
I haven't been able to reproduce the failure by running the test-case on
x86_64-linux with target board unix/-m32, but I'm able to reproduce on
x86_64-linux by using the exec attached to the PR:
...
$ cat gdb.in
file foo
maint expand-symtabs
maint print symbols
$ gdb -q -batch -ex "set trace-commands on" -x gdb.in
...
c_to: array (gdb/frame.c:3395: internal-error: reinflate: \
Assertion `m_cached_level >= -1' failed.
...
The backtrace at the point of the assertion failure is:
...
(gdb) bt
#0 __pthread_kill_implementation (threadid=<optimized out>,
signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
#1 0x00007ffff62a8e7f in __pthread_kill_internal (signo=6,
threadid=<optimized out>) at pthread_kill.c:78
#2 0x00007ffff6257842 in __GI_raise (sig=sig@entry=6)
at ../sysdeps/posix/raise.c:26
#3 0x00007ffff623f5cf in __GI_abort () at abort.c:79
#4 0x00000000010e7ac6 in dump_core () at gdb/utils.c:223
#5 0x00000000010e81b8 in internal_vproblem(internal_problem *, const char *, int, const char *, typedef __va_list_tag __va_list_tag *) (
problem=0x2ceb0c0 <internal_error_problem>,
file=0x1ad5a90 "gdb/frame.c", line=3395,
fmt=0x1ad5a08 "%s: Assertion `%s' failed.", ap=0x7fffffffc3c0)
at gdb/utils.c:475
#6 0x00000000010e82ac in internal_verror (
file=0x1ad5a90 "gdb/frame.c", line=3395,
fmt=0x1ad5a08 "%s: Assertion `%s' failed.", ap=0x7fffffffc3c0)
at gdb/utils.c:501
#7 0x00000000019be79f in internal_error_loc (
file=0x1ad5a90 "gdb/frame.c", line=3395,
fmt=0x1ad5a08 "%s: Assertion `%s' failed.")
at gdbsupport/errors.cc:57
#8 0x00000000009b5c16 in frame_info_ptr::reinflate (this=0x7fffffffc878)
at gdb/frame.c:3395
#9 0x00000000009b66f9 in frame_info_ptr::operator-> (this=0x7fffffffc878)
at gdb/frame.h:290
#10 0x00000000009b4bd5 in get_frame_arch (this_frame=...)
at gdb/frame.c:3075
#11 0x000000000081dd89 in dwarf_expr_context::fetch_result (
this=0x7fffffffc810, type=0x410d600, subobj_type=0x410d600,
subobj_offset=0, as_lval=true)
at gdb/dwarf2/expr.c:1006
#12 0x000000000081e2ef in dwarf_expr_context::evaluate (this=0x7fffffffc810,
addr=0x7ffff459ce6b "W\aF\003", len=1, as_lval=true,
per_cu=0x7fffd00053f0, frame=..., addr_info=0x7fffffffcc30, type=0x0,
subobj_type=0x0, subobj_offset=0)
at gdb/dwarf2/expr.c:1136
#13 0x0000000000877c14 in dwarf2_locexpr_baton_eval (dlbaton=0x3e99c18,
frame=..., addr_stack=0x7fffffffcc30, valp=0x7fffffffcab0,
push_values=..., is_reference=0x7fffffffc9b0)
at gdb/dwarf2/loc.c:1604
#14 0x0000000000877f71 in dwarf2_evaluate_property (prop=0x3e99ce0,
initial_frame=..., addr_stack=0x7fffffffcc30, value=0x7fffffffcab0,
push_values=...) at gdb/dwarf2/loc.c:1668
#15 0x00000000009def76 in resolve_dynamic_range (dyn_range_type=0x3e99c50,
addr_stack=0x7fffffffcc30, frame=..., rank=0, resolve_p=true)
at gdb/gdbtypes.c:2198
#16 0x00000000009e0ded in resolve_dynamic_type_internal (type=0x3e99c50,
addr_stack=0x7fffffffcc30, frame=..., top_level=true)
at gdb/gdbtypes.c:2934
#17 0x00000000009e1079 in resolve_dynamic_type (type=0x3e99c50, valaddr=...,
addr=0, in_frame=0x0) at gdb/gdbtypes.c:2989
#18 0x0000000000488ebc in ada_discrete_type_low_bound (type=0x3e99c50)
at gdb/ada-lang.c:710
#19 0x00000000004eb734 in print_range (type=0x3e99c50, stream=0x30157b0,
bounds_preferred_p=0) at gdb/ada-typeprint.c:156
#20 0x00000000004ebffe in print_array_type (type=0x3e99d10, stream=0x30157b0,
show=1, level=9, flags=0x1bdcf20 <type_print_raw_options>)
at gdb/ada-typeprint.c:381
#21 0x00000000004eda3c in ada_print_type (type0=0x3e99d10,
varstring=0x401f710 "c_to", stream=0x30157b0, show=1, level=9,
flags=0x1bdcf20 <type_print_raw_options>)
at gdb/ada-typeprint.c:1015
#22 0x00000000004b4627 in ada_language::print_type (
this=0x2f949b0 <ada_language_defn>, type=0x3e99d10,
varstring=0x401f710 "c_to", stream=0x30157b0, show=1, level=9,
flags=0x1bdcf20 <type_print_raw_options>)
at gdb/ada-lang.c:13681
#23 0x0000000000f74646 in print_symbol (gdbarch=0x3256270, symbol=0x3e99db0,
depth=9, outfile=0x30157b0) at gdb/symmisc.c:545
#24 0x0000000000f737e6 in dump_symtab_1 (symtab=0x3ddd7e0, outfile=0x30157b0)
at gdb/symmisc.c:313
#25 0x0000000000f73a69 in dump_symtab (symtab=0x3ddd7e0, outfile=0x30157b0)
at gdb/symmisc.c:370
#26 0x0000000000f7420f in maintenance_print_symbols (args=0x0, from_tty=0)
at gdb/symmisc.c:481
#27 0x00000000006c7fde in do_simple_func (args=0x0, from_tty=0, c=0x321e270)
at gdb/cli/cli-decode.c:94
#28 0x00000000006ce65a in cmd_func (cmd=0x321e270, args=0x0, from_tty=0)
at gdb/cli/cli-decode.c:2826
#29 0x0000000001005b78 in execute_command (p=0x3f48fe3 "", from_tty=0)
at gdb/top.c:564
#30 0x0000000000966095 in command_handler (
command=0x3f48fd0 "maint print symbols")
at gdb/event-top.c:613
#31 0x0000000001005141 in read_command_file (stream=0x3011a40)
at gdb/top.c:333
#32 0x00000000006e2a64 in script_from_file (stream=0x3011a40,
file=0x7fffffffe21f "gdb.in")
at gdb/cli/cli-script.c:1705
#33 0x00000000006bb88c in source_script_from_stream (stream=0x3011a40,
file=0x7fffffffe21f "gdb.in", file_to_open=0x7fffffffd760 "gdb.in")
at gdb/cli/cli-cmds.c:706
#34 0x00000000006bba12 in source_script_with_search (
file=0x7fffffffe21f "gdb.in", from_tty=0, search_path=0)
at gdb/cli/cli-cmds.c:751
#35 0x00000000006bbab2 in source_script (file=0x7fffffffe21f "gdb.in",
from_tty=0) at gdb/cli/cli-cmds.c:760
#36 0x0000000000b835cb in catch_command_errors (
command=0x6bba7e <source_script(char const*, int)>,
arg=0x7fffffffe21f "gdb.in", from_tty=0, do_bp_actions=false)
at gdb/main.c:510
#37 0x0000000000b83803 in execute_cmdargs (cmdarg_vec=0x7fffffffd980,
file_type=CMDARG_FILE, cmd_type=CMDARG_COMMAND, ret=0x7fffffffd8c8)
at gdb/main.c:606
#38 0x0000000000b84d79 in captured_main_1 (context=0x7fffffffdb90)
at gdb/main.c:1349
#39 0x0000000000b84fe4 in captured_main (context=0x7fffffffdb90)
at gdb/main.c:1372
#40 0x0000000000b85092 in gdb_main (args=0x7fffffffdb90)
at gdb/main.c:1401
#41 0x000000000041a382 in main (argc=9, argv=0x7fffffffdcc8)
at gdb/gdb.c:38
(gdb)
...
The immediate problem is in dwarf_expr_context::fetch_result where we're
calling get_frame_arch:
...
switch (this->m_location)
{
case DWARF_VALUE_REGISTER:
{
gdbarch *f_arch = get_frame_arch (this->m_frame);
...
with a null frame:
...
(gdb) p this->m_frame.is_null ()
$1 = true
(gdb)
...
Fix this using ensure_have_frame in dwarf_expr_context::execute_stack_op for
DW_OP_reg<n> and DW_OP_regx, getting us instead:
...
c_to: array (<>) of character; computed at runtime
...
Tested on x86_64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33512
Tom Tromey [Fri, 19 Sep 2025 16:05:38 +0000 (10:05 -0600)]
Clean up "return -1" in gdb.ada
gdb tests historically used "return -1" for some kinds of failure, but
there is no reason for the "-1". This patch removes this from the
gdb.ada tests.