There are two kinds of MOPS instructions: set instructions and copy
instructions. Within each group there are variants with minor
differences in how they read or write to memory — e.g., non-temporal
read and/or write, unprivileged read and/or write and permutations of
those — but they work in the same way in terms of the registers and
regions of memory that they modify.
The new gdb.reverse/aarch64-mops.exp testcase verifies that MOPS
instructions are recorded and correctly reversed. Not all variants of the
copy and set instructions are tested, since there are many and the record
and replay target processes them in the same way.
PR tdep/31666
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31666
Approved-By: Luis Machado <luis.machado@arm.com>
Tested-By: Luis Machado <luis.machado@arm.com>
(cherry picked from commit ebd06ca6b9)
The AArch64 MOPS (Memory Operation) instructions provide a standardised
instruction sequence to perform a memset, memcpy or memmove. A sequence is
always composed of three instructions: a prologue instruction, a main
instruction and an epilogue instruction. As an illustration, here are the
implementations of these memory operations in glibc 2.39:
(gdb) disassemble/r
Dump of assembler code for function __memset_mops:
=> 0x0000fffff7e8d780 <+0>: d503201f nop
0x0000fffff7e8d784 <+4>: aa0003e3 mov x3, x0
0x0000fffff7e8d788 <+8>: 19c10443 setp [x3]!, x2!, x1
0x0000fffff7e8d78c <+12>: 19c14443 setm [x3]!, x2!, x1
0x0000fffff7e8d790 <+16>: 19c18443 sete [x3]!, x2!, x1
0x0000fffff7e8d794 <+20>: d65f03c0 ret
End of assembler dump.
(gdb) disassemble/r
Dump of assembler code for function __memcpy_mops:
=> 0x0000fffff7e8c580 <+0>: d503201f nop
0x0000fffff7e8c584 <+4>: aa0003e3 mov x3, x0
0x0000fffff7e8c588 <+8>: 19010443 cpyfp [x3]!, [x1]!, x2!
0x0000fffff7e8c58c <+12>: 19410443 cpyfm [x3]!, [x1]!, x2!
0x0000fffff7e8c590 <+16>: 19810443 cpyfe [x3]!, [x1]!, x2!
0x0000fffff7e8c594 <+20>: d65f03c0 ret
End of assembler dump.
(gdb) disassemble/r
Dump of assembler code for function __memmove_mops:
=> 0x0000fffff7e8d180 <+0>: d503201f nop
0x0000fffff7e8d184 <+4>: aa0003e3 mov x3, x0
0x0000fffff7e8d188 <+8>: 1d010443 cpyp [x3]!, [x1]!, x2!
0x0000fffff7e8d18c <+12>: 1d410443 cpym [x3]!, [x1]!, x2!
0x0000fffff7e8d190 <+16>: 1d810443 cpye [x3]!, [x1]!, x2!
0x0000fffff7e8d194 <+20>: d65f03c0 ret
End of assembler dump.
The Arm Architecture Reference Manual says that "the prologue, main, and
epilogue instructions are expected to be run in succession and to appear
consecutively in memory". Therefore this patch disables displaced stepping
on them.
The testcase verifies that MOPS sequences are correctly single-stepped.
PR tdep/31666
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31666
Approved-By: Luis Machado <luis.machado@arm.com>
Tested-By: Luis Machado <luis.machado@arm.com>
(cherry picked from commit b995344c11)
Most files including gdbcmd.h currently rely on it to access things
actually declared in cli/cli-cmds.h (setlist, showlist, etc). To make
things easy, replace all includes of gdbcmd.h with includes of
cli/cli-cmds.h. This might lead to some unused includes of
cli/cli-cmds.h, but it's harmless, and much faster than going through
the 170 or so files by hand.
Change-Id: I11f884d4d616c12c05f395c98bbc2892950fb00f
Approved-By: Tom Tromey <tom@tromey.com>
Move the declarations out of defs.h, and the implementations out of
findvar.c.
I opted for a new file, because this functionality of converting
integers to bytes and vice-versa seems a bit to generic to live in
findvar.c.
Change-Id: I524858fca33901ee2150c582bac16042148d2251
Approved-By: John Baldwin <jhb@FreeBSD.org>
I found a couple of spots where VLAs are in use but where they can
easily be removed.
In one spot, adding 'const' is enough -- and is already done in
similar code elsewhere in the file.
In another spot, one of two arrays will be used, so making the buffer
large enough for both works.
Approved-By: John Baldwin <jhb@FreeBSD.org>
Now that defs.h, server.h and common-defs.h are included via the
`-include` option, it is no longer necessary for source files to include
them. Remove all the inclusions of these files I could find. Update
the generation scripts where relevant.
Change-Id: Ia026cff269c1b7ae7386dd3619bc9bb6a5332837
Approved-By: Pedro Alves <pedro@palves.net>
We currently pass frames to function by value, as `frame_info_ptr`.
This is somewhat expensive:
- the size of `frame_info_ptr` is 64 bytes, which is a bit big to pass
by value
- the constructors and destructor link/unlink the object in the global
`frame_info_ptr::frame_list` list. This is an `intrusive_list`, so
it's not so bad: it's just assigning a few points, there's no memory
allocation as if it was `std::list`, but still it's useless to do
that over and over.
As suggested by Tom Tromey, change many function signatures to accept
`const frame_info_ptr &` instead of `frame_info_ptr`.
Some functions reassign their `frame_info_ptr` parameter, like:
void
the_func (frame_info_ptr frame)
{
for (; frame != nullptr; frame = get_prev_frame (frame))
{
...
}
}
I wondered what to do about them, do I leave them as-is or change them
(and need to introduce a separate local variable that can be
re-assigned). I opted for the later for consistency. It might not be
clear why some functions take `const frame_info_ptr &` while others take
`frame_info_ptr`. Also, if a function took a `frame_info_ptr` because
it did re-assign its parameter, I doubt that we would think to change it
to `const frame_info_ptr &` should the implementation change such that
it doesn't need to take `frame_info_ptr` anymore. It seems better to
have a simple rule and apply it everywhere.
Change-Id: I59d10addef687d157f82ccf4d54f5dde9a963fd0
Approved-By: Andrew Burgess <aburgess@redhat.com>
This commit is the result of the following actions:
- Running gdb/copyright.py to update all of the copyright headers to
include 2024,
- Manually updating a few files the copyright.py script told me to
update, these files had copyright headers embedded within the
file,
- Regenerating gdbsupport/Makefile.in to refresh it's copyright
date,
- Using grep to find other files that still mentioned 2023. If
these files were updated last year from 2022 to 2023 then I've
updated them this year to 2024.
I'm sure I've probably missed some dates. Feel free to fix them up as
you spot them.
Make aarch64 use the new gdbarch_pseudo_register_write. This fixes
writing pseudo registers to non-current frames on this architecture.
Change-Id: Ic012a0b95ae728d45a7121f77a79d604c23a849e
Reviewed-By: John Baldwin <jhb@FreeBSD.org>
Approved-By: Luis Machado <luis.machado@arm.com>
Tested-By: Luis Machado <luis.machado@arm.com>
It seems like the intention here is to read the contents of the ZA
register and only write part of it. However, there's no actual read of
the ZA register, so it looks like we'll write uninitialized bytes to the
target, for the portion of the raw register where we don't write the
pseudo register. Add a call to raw_read to fix this.
I don't know how to test this though.
Change-Id: I7548240bd4324f6a3b729a1ebf7502fae5a46e9e
Reviewed-By: John Baldwin <jhb@FreeBSD.org>
Approved-by: Luis Machado <luis.machado@arm.com>
This is not necessary, but it seems more natural to me to make
aarch64_za_offsets_from_regnum return a za_offsets object, rather than
fill an instance passed by parameter.
Change-Id: I40a185f055727da887ce7774be193eef1f4b9147
Approved-by: Luis Machado <luis.machado@arm.com>
Reviewed-By: John Baldwin <jhb@FreeBSD.org>
The next patch introduces a new variant of gdbarch_pseudo_register_write
that takes a frame instead of a regcache for implementations to write
raw registers. Rename to old one to make it clear it's deprecated.
Change-Id: If8872c89c6f8a1edfcab983eb064248fd5ff3115
Reviewed-By: John Baldwin <jhb@FreeBSD.org>
Change gdbarch_pseudo_register_read_value to take a frame instead of a
regcache. The frame (and formerly the regcache) is used to read raw
registers needed to make up the pseudo register value. The problem with
using the regcache is that it always provides raw register values for
the current frame (frame 0).
Let's say the user wants to read the ebx register on amd64. ebx is a pseudo
register, obtained by reading the bottom half (bottom 4 bytes) of the
rbx register, which is a raw register. If the currently selected frame
is frame 0, it works fine:
(gdb) frame 0
#0 break_here_asm () at /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.arch/amd64-pseudo-unwind-asm.S:36
36 in /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.arch/amd64-pseudo-unwind-asm.S
(gdb) p/x $ebx
$1 = 0x24252627
(gdb) p/x $rbx
$2 = 0x2021222324252627
But if the user is looking at another frame, and the raw register behind
the pseudo register has been saved at some point in the call stack, then
we get a wrong answer:
(gdb) frame 1
#1 0x000055555555517d in caller () at /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.arch/amd64-pseudo-unwind-asm.S:56
56 in /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.arch/amd64-pseudo-unwind-asm.S
(gdb) p/x $ebx
$3 = 0x24252627
(gdb) p/x $rbx
$4 = 0x1011121314151617
Here, the value of ebx was computed using the value of rbx in frame 0
(through the regcache), it should have been computed using the value of
rbx in frame 1.
In other to make this work properly, make the following changes:
- Make dwarf2_frame_prev_register return nullptr if it doesn't know how
to unwind a register and that register is a pseudo register.
Previously, it returned `frame_unwind_got_register`, meaning, in our
example, "the value of ebx in frame 1 is the same as the value of ebx
in frame 0", which is obviously false. Return nullptr as a way to
say "I don't know".
- In frame_unwind_register_value, when prev_register (for instance
dwarf2_frame_prev_register) returns nullptr, and we are trying to
read a pseudo register, try to get the register value through
gdbarch_pseudo_register_read_value or gdbarch_pseudo_register_read.
If using gdbarch_pseudo_register_read, the behavior is known to be
broken. Implementations should be migrated to use
gdbarch_pseudo_register_read_value to fix that.
- Change gdbarch_pseudo_register_read_value to take a frame_info
instead of a regcache, update implementations (aarch64, amd64, i386).
In i386-tdep.c, I made a copy of i386_mmx_regnum_to_fp_regnum that
uses a frame instead of a regcache. The version using the regcache
is still used by i386_pseudo_register_write. It will get removed in
a subsequent patch.
- Add some helpers in value.{c,h} to implement the common cases of
pseudo registers: taking part of a raw register and concatenating
multiple raw registers.
- Update readable_regcache::{cooked_read,cooked_read_value} to pass the
current frame to gdbarch_pseudo_register_read_value. Passing the
current frame will give the same behavior as before: for frame 0, raw
registers will be read from the current thread's regcache.
Notes:
- I do not plan on changing gdbarch_pseudo_register_read to receive a
frame instead of a regcache. That method is considered deprecated.
Instead, we should be working on migrating implementations to use
gdbarch_pseudo_register_read_value instead.
- In frame_unwind_register_value, we still ask the unwinder to try to
unwind pseudo register values. It's apparently possible for the
debug info to provide information about [1] pseudo registers, so we
want to try that first, before falling back to computing them
ourselves.
[1] https://inbox.sourceware.org/gdb-patches/20180528174715.A954AD804AD@oc3748833570.ibm.com/
Change-Id: Id6ef1c64e19090a183dec050e4034d8c2394e7ca
Reviewed-by: John Baldwin <jhb@FreeBSD.org>
Some functions related to the handling of registers in frames accept
"this frame", for which we want to read or write the register values,
while other functions accept "the next frame", which is the frame next
to that. The later is needed because we sometimes need to read register
values for a frame that does not exist yet (usually when trying to
unwind that frame-to-be).
value_of_register and value_of_register_lazy both take "this frame",
even if what they ultimately want internally is "the next frame". This
is annoying if you are in a spot that currently has "the next frame" and
need to call one of these functions (which happens later in this
series). You need to get the previous frame only for those functions to
get the next frame again. This is more manipulations, more chances of
mistake.
I propose to change these functions (and a few more functions in the
subsequent patches) to operate on "the next frame". Things become a bit
less awkward when all these functions agree on which frame they take.
So, in this patch, change value_of_register_lazy and value_of_register
to take "the next frame" instead of "this frame". This adds a lot of
get_next_frame_sentinel_okay, but if we convert the user registers API
to also use "the next frame" instead of "this frame", it will get simple
again.
Change-Id: Iaa24815e648fbe5ae3c214c738758890a91819cd
Reviewed-By: John Baldwin <jhb@FreeBSD.org>
This changes gdb to use the C++17 [[fallthrough]] attribute rather
than special comments.
This was mostly done by script, but I neglected a few spellings and so
also fixed it up by hand.
I suspect this fixes the bug mentioned below, by switching to a
standard approach that, presumably, clang supports.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23159
Approved-By: John Baldwin <jhb@FreeBSD.org>
Approved-By: Luis Machado <luis.machado@arm.com>
Approved-By: Pedro Alves <pedro@palves.net>
SME2 defines a new 512-bit register named ZT0, and it is only available
if SME is also supported. The ZT0 state is valid only if the SVCR ZA bit
is enabled. Otherwise its contents are empty (0).
The target description is dynamic and gets generated at runtime based on the
availability of the feature.
Validated under Fast Models.
Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
The SME (Scalable Matrix Extension) [1] exposes a new matrix register ZA with
variable sizes. It also exposes a new mode called streaming mode.
Similarly to SVE, the ZA register size is dictated by a vector length, but the
SME vector length is called streaming vetor length. The total size for
ZA in a given moment is svl x svl.
In streaming mode, the SVE registers have their sizes based on svl rather than
the regular vector length (vl).
The feature detection is controlled by the HWCAP2_SME bit, but actual support
should be validated by attempting a ptrace call for one of the new register
sets: NT_ARM_ZA and NT_ARM_SSVE.
Due to its large size, the ZA register is exposed as a vector of bytes, but we
introduce a number of pseudo-registers that gives various different views
into the ZA contents. These can be arranged in a couple categories: tiles and
tile slices.
Tiles are matrices the same size or smaller than ZA. Tile slices are vectors
which map to ZA's rows/columns in different ways.
A new dynamic target description is provided containing the ZA register, the SVG
register and the SVCR register. The size of ZA, like the SVE vector registers,
is based on the vector length register SVG (VG for SVE).
This patch enables SME register support for gdb.
[1] https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/scalable-matrix-extension-armv9-a-architecture
Co-Authored-By: Ezra Sitorus <ezra.sitorus@arm.com>
Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
In a target without SVE support, the V registers have a size of 16 bytes,
otherwise they may have a size bigger than 16 bytes (depending on the current
vector length for the Z registers, as they overlap the V registers).
In aarch64-tdep.c:aarch64_store_return_value, the code is laid
out in a way that allocates the buffer with the size of the register, but
only updates the amount of bytes for the particular type we're returning.
This may cause a situation where we have a register size of 32 bytes but
are returning a floating point value of 8 bytes. The temporary buffer
will therefore have 32 bytes, but we'll only update 8 bytes of it.
When we write the entire register back, it will have potentially 24 bytes
of garbage in it.
Fix this by first reading the original contents of the register and then
overriding only the bytes that we need for the return value.
Tested on aarch64-linux Ubuntu 22.04/20.04.
Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
As noted by Tom Tromey, there are some formatting issues with the ternary
operator in the aarch64/arm codebase. This patch fixes those.
Reviewed-By: Tom Tromey <tom@tromey.com>
The gdb.dwarf2/dw2-prologue-end-2.exp test was failing for both AArch64 and
Arm.
As Tom pointed out here (https://inbox.sourceware.org/gdb-patches/6663707c-4297-c2f2-a0bd-f3e84fc62aad@suse.de/),
there are issues with both the prologue skipper for AArch64 and Arm and an
incorrect assumption by the testcase.
This patch fixes both of AArch64's and Arm's prologue skippers to not skip past
the end of a function. It also incorporates a fix to the testcase so it
doesn't assume the prologue skipper will stop at the first instruction of the
functions/labels.
Regression-tested on aarch64-linux/arm-linux Ubuntu 20.04/22.04 and
x86_64-linux Ubuntu 20.04.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30506
Co-Authored-By: Tom de Vries <tdevries@suse.de>
Co-Authored-By: Luis Machado <luis.machado@arm.com>
This changes field_is_static to be a method on struct field, and
updates all the callers. Most of this patch was written by script.
Regression tested on x86-64 Fedora 36.
Older gdb's (9, 10, 11 and 12) have a bug that causes them to crash whenever
a target reports the pauth feature string in the target description and also
provide additional register outside of gdb's known and expected feature
strings.
This was fixed in gdb 13 onwards, but that means we're stuck with gdb's out
there that will crash on connection to the above targets.
QEMU has postponed inclusion of the pauth feature string in version 8, and
instead we agreed to use a new feature name to prevent crashing those older
gdb's.
Initially there was a plan to backport a trivial fix all the way to gdb 9, but
given QEMU's choice, this is no longer needed.
This new feature string is org.gnu.gdb.aarch64.pauth_v2, and should be used
by all targets going forward, except native linux gdb and gdbserver, for
backwards compatibility with older gdb's/gdbserver's.
gdb/gdbserver will still emit the old feature string for Linux since it doesn't
report additional system registers and thus doesn't cause a crash of older
gdb's. We can revisit this in the future once the problematic gdb's are likely
no longer in use.
I've added some documentation to explain the situation.
This commit aims to address a problem that exists with the current
approach to displaced stepping, and was identified in PR gdb/22921.
Displaced stepping is currently supported on AArch64, ARM, amd64,
i386, rs6000 (ppc), and s390. Of these, I believe there is a problem
with the current approach which will impact amd64 and ARM, and can
lead to random register corruption when the inferior makes use of
asynchronous signals and GDB is using displaced stepping.
The problem can be found in displaced_step_buffers::finish in
displaced-stepping.c, and is this; after GDB tries to perform a
displaced step, and the inferior stops, GDB classifies the stop into
one of two states, either the displaced step succeeded, or the
displaced step failed.
If the displaced step succeeded then gdbarch_displaced_step_fixup is
called, which has the job of fixing up the state of the current
inferior as if the step had not been performed in a displaced manner.
This all seems just fine.
However, if the displaced step is considered to have not completed
then GDB doesn't call gdbarch_displaced_step_fixup, instead GDB
remains in displaced_step_buffers::finish and just performs a minimal
fixup which involves adjusting the program counter back to its
original value.
The problem here is that for amd64 and ARM setting up for a displaced
step can involve changing the values in some temporary registers. If
the displaced step succeeds then this is fine; after the step the
temporary registers are restored to their original values in the
architecture specific code.
But if the displaced step does not succeed then the temporary
registers are never restored, and they retain their modified values.
In this context a temporary register is simply any register that is
not otherwise used by the instruction being stepped that the
architecture specific code considers safe to borrow for the lifetime
of the instruction being stepped.
In the bug PR gdb/22921, the amd64 instruction being stepped is
an rip-relative instruction like this:
jmp *0x2fe2(%rip)
When we displaced step this instruction we borrow a register, and
modify the instruction to something like:
jmp *0x2fe2(%rcx)
with %rcx having its value adjusted to contain the original %rip
value.
Now if the displaced step does not succeed, then %rcx will be left
with a corrupted value. Obviously corrupting any register is bad; in
the bug report this problem was spotted because %rcx is used as a
function argument register.
And finally, why might a displaced step not succeed? Asynchronous
signals provides one reason. GDB sets up for the displaced step and,
at that precise moment, the OS delivers a signal (SIGALRM in the bug
report), the signal stops the inferior at the address of the displaced
instruction. GDB cancels the displaced instruction, handles the
signal, and then tries again with the displaced step. But it is that
first cancellation of the displaced step that causes the problem; in
that case GDB (correctly) sees the displaced step as having not
completed, and so does not perform the architecture specific fixup,
leaving the register corrupted.
The reason why I think AArch64, rs600, i386, and s390 are not effected
by this problem is that I don't believe these architectures make use
of any temporary registers, so when a displaced step is not completed
successfully, the minimal fix up is sufficient.
On amd64 we use at most one temporary register.
On ARM, looking at arm_displaced_step_copy_insn_closure, we could
modify up to 16 temporary registers, and the instruction being
displaced stepped could be expanded to multiple replacement
instructions, which increases the chances of this bug triggering.
This commit only aims to address the issue on amd64 for now, though I
believe that the approach I'm proposing here might be applicable for
ARM too.
What I propose is that we always call gdbarch_displaced_step_fixup.
We will now pass an extra argument to gdbarch_displaced_step_fixup,
this a boolean that indicates whether GDB thinks the displaced step
completed successfully or not.
When this flag is false this indicates that the displaced step halted
for some "other" reason. On ARM GDB can potentially read the
inferior's program counter in order figure out how far through the
sequence of replacement instructions we got, and from that GDB can
figure out what fixup needs to be performed.
On targets like amd64 the problem is slightly easier as displaced
stepping only uses a single replacement instruction. If the displaced
step didn't complete the GDB knows that the single instruction didn't
execute.
The point is that by always calling gdbarch_displaced_step_fixup, each
architecture can now ensure that the inferior state is fixed up
correctly in all cases, not just the success case.
On amd64 this ensures that we always restore the temporary register
value, and so bug PR gdb/22921 is resolved.
In order to move all architectures to this new API, I have moved the
minimal roll-back version of the code inside the architecture specific
fixup functions for AArch64, rs600, s390, and ARM. For all of these
except ARM I think this is good enough, as no temporaries are used all
that's needed is the program counter restore anyway.
For ARM the minimal code is no worse than what we had before, though I
do consider this architecture's displaced-stepping broken.
I've updated the gdb.arch/amd64-disp-step.exp test to cover the
'jmpq*' instruction that was causing problems in the original bug, and
also added support for testing the displaced step in the presence of
asynchronous signal delivery.
I've also added two new tests (for amd64 and i386) that check that GDB
can correctly handle displaced stepping over a single instruction that
branches to itself. I added these tests after a first version of this
patch relied too much on checking the program-counter value in order
to see if the displaced instruction had executed. This works fine in
almost all cases, but when an instruction branches to itself a pure
program counter check is not sufficient. The new tests expose this
problem.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=22921
Approved-By: Pedro Alves <pedro@palves.net>
Make find_thread_ptid (the overload that takes a process_stratum_target)
a method of process_stratum_target.
Change-Id: Ib190a925a83c6b93e9c585dc7c6ab65efbdd8629
Reviewed-By: Tom Tromey <tom@tromey.com>
There were reports of gdb throwing internal errors when calling
inferior_thread ()/get_current_regcache () on a system with
Pointer Authentication enabled.
In such cases, gdb produces the following backtrace:
../../../repos/binutils-gdb/gdb/thread.c:86: internal-error: inferior_thread: Assertion `current_thread_ != nullptr' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
----- Backtrace -----
0xaaaae04a571f gdb_internal_backtrace_1
../../../repos/binutils-gdb/gdb/bt-utils.c:122
0xaaaae04a57f3 _Z22gdb_internal_backtracev
../../../repos/binutils-gdb/gdb/bt-utils.c:168
0xaaaae0b52ccf internal_vproblem
../../../repos/binutils-gdb/gdb/utils.c:401
0xaaaae0b5310b _Z15internal_verrorPKciS0_St9__va_list
../../../repos/binutils-gdb/gdb/utils.c:481
0xaaaae0e24b8f _Z18internal_error_locPKciS0_z
../../../repos/binutils-gdb/gdbsupport/errors.cc:58
0xaaaae0a88983 _Z15inferior_threadv
../../../repos/binutils-gdb/gdb/thread.c:86
0xaaaae0956c87 _Z20get_current_regcachev
../../../repos/binutils-gdb/gdb/regcache.c:428
0xaaaae035223f aarch64_remove_non_address_bits
../../../repos/binutils-gdb/gdb/aarch64-tdep.c:3572
0xaaaae03e8abb _Z31gdbarch_remove_non_address_bitsP7gdbarchm
../../../repos/binutils-gdb/gdb/gdbarch.c:3109
0xaaaae0a692d7 memory_xfer_partial
../../../repos/binutils-gdb/gdb/target.c:1620
0xaaaae0a695e3 _Z19target_xfer_partialP10target_ops13target_objectPKcPhPKhmmPm
../../../repos/binutils-gdb/gdb/target.c:1684
0xaaaae0a69e9f target_read_partial
../../../repos/binutils-gdb/gdb/target.c:1937
0xaaaae0a69fdf _Z11target_readP10target_ops13target_objectPKcPhml
../../../repos/binutils-gdb/gdb/target.c:1977
0xaaaae0a69937 _Z18target_read_memorymPhl
../../../repos/binutils-gdb/gdb/target.c:1773
0xaaaae08be523 ps_xfer_memory
../../../repos/binutils-gdb/gdb/proc-service.c:90
0xaaaae08be6db ps_pdread
../../../repos/binutils-gdb/gdb/proc-service.c:124
0x40001ed7c3b3 _td_fetch_value
/build/glibc-RIFKjK/glibc-2.31/nptl_db/fetch-value.c:115
0x40001ed791ef td_ta_map_lwp2thr
/build/glibc-RIFKjK/glibc-2.31/nptl_db/td_ta_map_lwp2thr.c:194
0xaaaae07f4473 thread_from_lwp
../../../repos/binutils-gdb/gdb/linux-thread-db.c:413
0xaaaae07f6d6f _ZN16thread_db_target4waitE6ptid_tP17target_waitstatus10enum_flagsI16target_wait_flagE
../../../repos/binutils-gdb/gdb/linux-thread-db.c:1420
0xaaaae0a6b33b _Z11target_wait6ptid_tP17target_waitstatus10enum_flagsI16target_wait_flagE
../../../repos/binutils-gdb/gdb/target.c:2586
0xaaaae0789cf7 do_target_wait_1
../../../repos/binutils-gdb/gdb/infrun.c:3825
0xaaaae0789e6f operator()
../../../repos/binutils-gdb/gdb/infrun.c:3884
0xaaaae078a167 do_target_wait
../../../repos/binutils-gdb/gdb/infrun.c:3903
0xaaaae078b0af _Z20fetch_inferior_eventv
../../../repos/binutils-gdb/gdb/infrun.c:4314
0xaaaae076652f _Z22inferior_event_handler19inferior_event_type
../../../repos/binutils-gdb/gdb/inf-loop.c:41
0xaaaae07dc68b handle_target_event
../../../repos/binutils-gdb/gdb/linux-nat.c:4206
0xaaaae0e25fbb handle_file_event
../../../repos/binutils-gdb/gdbsupport/event-loop.cc:573
0xaaaae0e264f3 gdb_wait_for_event
../../../repos/binutils-gdb/gdbsupport/event-loop.cc:694
0xaaaae0e24f9b _Z16gdb_do_one_eventi
../../../repos/binutils-gdb/gdbsupport/event-loop.cc:217
0xaaaae080f033 start_event_loop
../../../repos/binutils-gdb/gdb/main.c:411
0xaaaae080f1b7 captured_command_loop
../../../repos/binutils-gdb/gdb/main.c:475
0xaaaae0810b97 captured_main
../../../repos/binutils-gdb/gdb/main.c:1318
0xaaaae0810c1b _Z8gdb_mainP18captured_main_args
../../../repos/binutils-gdb/gdb/main.c:1337
0xaaaae0338453 main
../../../repos/binutils-gdb/gdb/gdb.c:32
---------------------
../../../repos/binutils-gdb/gdb/thread.c:86: internal-error: inferior_thread: Assertion `current_thread_ != nullptr' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n)
We also see failures across the testsuite if the tests get executed on a target
that has native support for the pointer authentication feature. But
gdb.base/break.exp and gdb.base/access-mem-running.exp are two examples of
tests that run into errors and internal errors.
This issue started after commit d88cb738e6, which
enabled more broad use of pointer authentication masks to remove non-address
bits of pointers, but wasn't immediately detected because systems with native
support for pointer authentication are not that common yet.
The above crash happens because gdb is in the middle of handling an event,
and do_target_wait_1 calls switch_to_inferior_no_thread, nullifying the
current thread. This means a call to inferior_thread () will assert, and
attempting to call get_current_regcache () will also call inferior_thread (),
resulting in an assertion as well.
target_has_registers was one function that seemed useful for detecting these
types of situation where we don't have a register cache. The problem with that
is the inconsistent state of inferior_ptid, which is used by
target_has_registers.
Despite the call to switch_to_no_thread in switch_to_inferior_no_thread from
do_target_wait_1 in the backtrace above clearing inferior_ptid, the call to
ps_xfer_memory sets inferior_ptid momentarily before reading memory:
static ps_err_e
ps_xfer_memory (const struct ps_prochandle *ph, psaddr_t addr,
gdb_byte *buf, size_t len, int write)
{
scoped_restore_current_inferior restore_inferior;
set_current_inferior (ph->thread->inf);
scoped_restore_current_program_space restore_current_progspace;
set_current_program_space (ph->thread->inf->pspace);
scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
inferior_ptid = ph->thread->ptid;
CORE_ADDR core_addr = ps_addr_to_core_addr (addr);
int ret;
if (write)
ret = target_write_memory (core_addr, buf, len);
else
ret = target_read_memory (core_addr, buf, len);
return (ret == 0 ? PS_OK : PS_ERR);
}
Maybe this shouldn't happen, or maybe it is just an unfortunate state to be
in. But this prevents the use of target_has_registers to guard against the
lack of registers, since, although current_thread_ is still nullptr,
inferior_ptid is valid and is not null_ptid.
There is another crash scenario after we kill a previously active inferior, in
which case the gdbarch will still say we support pointer authentication but we
will also have no current thread (inferior_thread () will assert etc).
If the target has support for pointer authentication, gdb needs to use
a couple (or 4, for bare-metal) mask registers to mask off some bits of
pointers, and for that it needs to access the registers.
At some points, like the one from the backtrace above, there is no active
thread/current regcache because gdb is in the middle of doing event handling
and switching between threads.
Simon suggested the use of inferior_ptid to fetch the register cache, as
opposed to relying on the current register cache. Though we need to make sure
inferior_ptid is valid (not null_ptid), I think this works nicely.
With inferior_ptid, we can do safety checks along the way, making sure we have
a thread to fetch a register cache from and checking if the thread is actually
stopped or running.
The following patch implements this idea with safety checks to make sure we
don't run into assertions or errors. If any of the checks fail, we fallback to
using a default mask to remove non-address bits of a pointer.
I discussed with Pedro the possibility of caching the mask register values
(which are per-process and can change mid-execution), but there isn't a good
spot to cache those values. Besides, the mask registers can change constantly
for bare-metal debugging when switching between exception levels.
In some cases, it is just not possible to get access to these mask registers,
like the case where threads are running. In those cases, using a default mask
to remove the non-address bits should be enough.
This can happen when we let threads run in the background and then we attempt
to access a memory address (now that gdb is capable of reading memory even
with threads running). Thus gdb will attempt to remove non-address bits
of that memory access, will attempt to access registers, running into errors.
Regression-tested on aarch64-linux Ubuntu 20.04.
At the moment GDB only handles pointer authentication (pauth) for userspace
addresses and if we're debugging a Linux-hosted program.
The Linux Kernel can be configured to use pauth instructions for some
additional security hardening, but GDB doesn't handle this well.
To overcome this limitation, GDB needs a couple things:
1 - The target needs to advertise pauth support.
2 - The hook to remove non-address bits from a pointer needs to be registered
in aarch64-tdep.c as opposed to aarch64-linux-tdep.c.
There is a patch for QEMU that addresses the first point, and it makes
QEMU's gdbstub expose a couple more pauth mask registers, so overall we will
have up to 4 pauth masks (2 masks or 4 masks):
pauth_dmask
pauth_cmask
pauth_dmask_high
pauth_cmask_high
pauth_dmask and pauth_cmask are the masks used to remove pauth signatures
from userspace addresses. pauth_dmask_high and pauth_cmask_high masks are used
to remove pauth signatures from kernel addresses.
The second point is easily addressed by moving code around.
When debugging a Linux Kernel built with pauth with an unpatched GDB, we get
the following backtrace:
#0 __fput (file=0xffff0000c17a6400) at /repos/linux/fs/file_table.c:296
#1 0xffff8000082bd1f0 in ____fput (work=<optimized out>) at /repos/linux/fs/file_table.c:348
#2 0x30008000080ade30 [PAC] in ?? ()
#3 0x30d48000080ade30 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
With a patched GDB, we get something a lot more meaningful:
#0 __fput (file=0xffff0000c1bcfa00) at /repos/linux/fs/file_table.c:296
#1 0xffff8000082bd1f0 in ____fput (work=<optimized out>) at /repos/linux/fs/file_table.c:348
#2 0xffff8000080ade30 [PAC] in task_work_run () at /repos/linux/kernel/task_work.c:179
#3 0xffff80000801db90 [PAC] in resume_user_mode_work (regs=0xffff80000a96beb0) at /repos/linux/include/linux/resume_user_mode.h:49
#4 do_notify_resume (regs=regs@entry=0xffff80000a96beb0, thread_flags=4) at /repos/linux/arch/arm64/kernel/signal.c:1127
#5 0xffff800008fb9974 [PAC] in prepare_exit_to_user_mode (regs=0xffff80000a96beb0) at /repos/linux/arch/arm64/kernel/entry-common.c:137
#6 exit_to_user_mode (regs=0xffff80000a96beb0) at /repos/linux/arch/arm64/kernel/entry-common.c:142
#7 el0_svc (regs=0xffff80000a96beb0) at /repos/linux/arch/arm64/kernel/entry-common.c:638
#8 0xffff800008fb9d34 [PAC] in el0t_64_sync_handler (regs=<optimized out>) at /repos/linux/arch/arm64/kernel/entry-common.c:655
#9 0xffff800008011548 [PAC] in el0t_64_sync () at /repos/linux/arch/arm64/kernel/entry.S:586
Backtrace stopped: Cannot access memory at address 0xffff80000a96c0c8
This introduces the set_lval method on value, one step toward removing
deprecated_lval_hack. Ultimately I think the goal should be for some
of these set_* methods to be replaced with constructors; but I haven't
done this, as the series is already too long. Other 'deprecated'
methods can probably be handled the same way.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This patch turns a grab bag of value functions to methods of value.
These are done together because their implementations are
interrelated.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This turns many functions that are related to optimized-out or
availability-checking to be methods of value. The static function
value_entirely_covered_by_range_vector is also converted to be a
private method.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This turns the remaining value_contents functions -- value_contents,
value_contents_all, value_contents_for_printing, and
value_contents_for_printing_const -- into methods of value. It also
converts the static functions require_not_optimized_out and
require_available to be private methods.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This turns value_contents_raw, value_contents_writeable, and
value_contents_all_raw into methods on value. The remaining functions
will be changed later in the series; they were a bit trickier and so I
didn't include them in this patch.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
Consider the test-case test.c, compiled without debug info:
...
void
foo (const char *s)
{
}
int
main (void)
{
foo ("foo");
return 0;
}
...
Disassembly of foo:
...
0000000000400564 <foo>:
400564: d10043ff sub sp, sp, #0x10
400568: f90007e0 str x0, [sp, #8]
40056c: d503201f nop
400570: 910043ff add sp, sp, #0x10
400574: d65f03c0 ret
...
Now, let's do "info frame" at each insn in foo, as well as printing $sp
and $x29 (and strip the output of info frame to the first line, for brevity):
...
$ gdb -q a.out
Reading symbols from a.out...
(gdb) b *foo
Breakpoint 1 at 0x400564
(gdb) r
Starting program: a.out
Breakpoint 1, 0x0000000000400564 in foo ()
(gdb) display /x $sp
1: /x $sp = 0xfffffffff3a0
(gdb) display /x $x29
2: /x $x29 = 0xfffffffff3a0
(gdb) info frame
Stack level 0, frame at 0xfffffffff3a0:
(gdb) si
0x0000000000400568 in foo ()
1: /x $sp = 0xfffffffff390
2: /x $x29 = 0xfffffffff3a0
(gdb) info frame
Stack level 0, frame at 0xfffffffff3a0:
(gdb) si
0x000000000040056c in foo ()
1: /x $sp = 0xfffffffff390
2: /x $x29 = 0xfffffffff3a0
(gdb) info frame
Stack level 0, frame at 0xfffffffff3a0:
(gdb) si
0x0000000000400570 in foo ()
1: /x $sp = 0xfffffffff390
2: /x $x29 = 0xfffffffff3a0
(gdb) info frame
Stack level 0, frame at 0xfffffffff3a0:
(gdb) si
0x0000000000400574 in foo ()
1: /x $sp = 0xfffffffff3a0
2: /x $x29 = 0xfffffffff3a0
(gdb) info frame
Stack level 0, frame at 0xfffffffff3b0:
pc = 0x400574 in foo; saved pc = 0x40058c
(gdb) si
0x000000000040058c in main ()
1: /x $sp = 0xfffffffff3a0
2: /x $x29 = 0xfffffffff3a0
...
The "frame at" bit lists 0xfffffffff3a0 except at the last insn, where it
lists 0xfffffffff3b0.
The frame address is calculated here in aarch64_make_prologue_cache_1:
...
unwound_fp = get_frame_register_unsigned (this_frame, cache->framereg);
if (unwound_fp == 0)
return;
cache->prev_sp = unwound_fp + cache->framesize;
...
For insns after the prologue, we have cache->framereg == sp and
cache->framesize == 16, so unwound_fp + cache->framesize gives the wrong
answer once sp has been restored to entry value by the before-last insn.
Fix this by detecting the situation that the sp has been restored.
This fixes PRs tdep/30010 and tdep/30011.
This also fixes the aarch64 FAILs in gdb.reverse/solib-precsave.exp and
gdb.reverse/solib-reverse.exp I reported in PR gdb/PR29721.
Tested on aarch64-linux.
PR tdep/30010
PR tdep/30011
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30010
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30011
This helps resolve some cyclic include problem later in the series.
The only language-related thing frame.h needs is enum language, and that
is in defs.h.
Doing so reveals that a bunch of files were relying on frame.h to
include language.h, so fix the fallouts here and there.
Change-Id: I178a7efec1953c2d088adb58483bade1f349b705
Reviewed-By: Bruno Larsen <blarsen@redhat.com>
In aarch64-tdep.c we find these register aliases:
...
{
/* 64-bit register names. */
{"fp", AARCH64_FP_REGNUM},
{"lr", AARCH64_LR_REGNUM},
{"sp", AARCH64_SP_REGNUM},
...
The sp alias is superfluous, because the canonical name of x31 is already sp.
The fp alias is superfluous, because it's already taken by the default meaning
of fp, assigned here in _initialize_frame_reg:
...
user_reg_add_builtin ("fp", value_of_builtin_frame_fp_reg, NULL);
...
Fix this by removing the fp and sp aliases.
While we're at it, add an x31 alias for sp.
Approved-By: Luis Machado <luis.machado@arm.com>
Tested on aarch64-linux.
PR tdep/30012
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30012
It's currently not clear how the ownership of gdbarch_tdep objects
works. In fact, nothing ever takes ownership of it. This is mostly
fine because we never free gdbarch objects, and thus we never free
gdbarch_tdep objects. There is an exception to that however: when
initialization fails, we do free the gdbarch object that is not going to
be used, and we free the tdep too. Currently, i386 and s390 do it.
To make things clearer, change gdbarch_alloc so that it takes ownership
of the tdep. The tdep is thus automatically freed if the gdbarch is
freed.
Change all gdbarch initialization functions to pass a new gdbarch_tdep
object to gdbarch_alloc and then retrieve a non-owning reference from
the gdbarch object.
Before this patch, the xtensa architecture had a single global instance
of xtensa_gdbarch_tdep. Since we need to pass a dynamically allocated
gdbarch_tdep_base instance to gdbarch_alloc, remove this global
instance, and dynamically allocate one as needed, like we do for all
other architectures. Make the `rmap` array externally visible and
rename it to the less collision-prone `xtensa_rmap` name.
Change-Id: Id3d70493ef80ce4bdff701c57636f4c79ed8aea2
Approved-By: Andrew Burgess <aburgess@redhat.com>
This converts a few selected architectures to use
gdbarch_return_value_as_value rather than gdbarch_return_value. The
architectures are just the ones that I am able to test. This patch
should not introduce any behavior changes.
This commit is the result of running the gdb/copyright.py script,
which automated the update of the copyright year range for all
source files managed by the GDB project to be updated to include
year 2023.
With the AArch64 Scalable Matrix Extension we have a new TPIDR2 register, and
it will be added to the existing NT_ARM_TLS register set. Kernel patches are
being reviewed here:
https://lore.kernel.org/linux-arm-kernel/20220818170111.351889-1-broonie@kernel.org/
From GDB's perspective, we handle it in a similar way to the existing TPIDR
register. But we need to consider cases of systems that only have TPIDR and
systems that have both TPIDR and TPIDR2.
With that in mind, the following patch adds the required code to support
TPIDR2 and turns the org.gnu.gdb.aarch64.tls feature into a
dynamically-generated target description as opposed to a static target
description containing only TPIDR.
That means we can remove the gdb/features/aarch64-tls.xml file and replace the
existing gdb/features/aarch64-tls.c auto-generated file with a new file that
dynamically generates the target description containing either TPIDR alone or
TPIDR and TPIDR2.
In the future, when *BSD's start to support this register, they can just
enable it as is being done for the AArch64 Linux target.
The core file read/write code has been updated to support TPIDR2 as well.
On GDBserver's side, there is a small change to the find_regno function to
expose a non-throwing version of it.
It always seemed strange to me how find_regno causes the whole operation to
abort if it doesn't find a particular register name. The patch moves code
from find_regno into find_regno_no_throw and makes find_regno call
find_regno_no_throw instead.
This allows us to do register name lookups to find a particular register
number without risking erroring out if nothing is found.
The patch also adjusts the feature detection code for aarch64-fbsd, since
the infrastructure is shared amongst all aarch64 targets. I haven't added
code to support TPIDR2 in aarch64-fbsd though, as I'm not sure when/if
that will happen.
PR tdep/28796
As reported, we are using some memory read routines that don't handle read
errors gracefully. Convert those to use the safe_* versions if available.
This allows the code to handle those read errors in a more sensible way.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28796
Currently, every internal_error call must be passed __FILE__/__LINE__
explicitly, like:
internal_error (__FILE__, __LINE__, "foo %d", var);
The need to pass in explicit __FILE__/__LINE__ is there probably
because the function predates widespread and portable variadic macros
availability. We can use variadic macros nowadays, and in fact, we
already use them in several places, including the related
gdb_assert_not_reached.
So this patch renames the internal_error function to something else,
and then reimplements internal_error as a variadic macro that expands
__FILE__/__LINE__ itself.
The result is that we now should call internal_error like so:
internal_error ("foo %d", var);
Likewise for internal_warning.
The patch adjusts all calls sites. 99% of the adjustments were done
with a perl/sed script.
The non-mechanical changes are in gdbsupport/errors.h,
gdbsupport/gdb_assert.h, and gdb/gdbarch.py.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
Change-Id: Ia6f372c11550ca876829e8fd85048f4502bdcf06
This changes GDB to use frame_info_ptr instead of frame_info *
The substitution was done with multiple sequential `sed` commands:
sed 's/^struct frame_info;/class frame_info_ptr;/'
sed 's/struct frame_info \*/frame_info_ptr /g' - which left some
issues in a few files, that were manually fixed.
sed 's/\<frame_info \*/frame_info_ptr /g'
sed 's/frame_info_ptr $/frame_info_ptr/g' - used to remove whitespace
problems.
The changed files were then manually checked and some 'sed' changes
undone, some constructors and some gets were added, according to what
made sense, and what Tromey originally did
Co-Authored-By: Bruno Larsen <blarsen@redhat.com>
Approved-by: Tom Tomey <tom@tromey.com>
The aarch64 port handles W registers as aliases of X registers. This is
incorrect because X registers are 64-bit and W registers are 32-bit.
This patch teaches GDB how to handle W registers as pseudo-registers of
32-bit, the bottom half of the X registers.
Testcase included.
When using AArch64 GDB with the QEMU debugging stub (in user mode), we get
additional system registers that GDB doesn't particularly care about, so
it doesn't number those explicitly.
But given the pseudo-register numbers are above the number of real registers,
we need to setup/account for the real registers first before going ahead and
numbering the pseudo-registers. This has to happen at the end of
aarch64_gdbarch_init, after the call to tdesc_use_registers, as that
updates the total number of real registers.
This is in preparation to supporting pointer authentication for bare metal
aarch64 (QEMU).