From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7833) id 87DD83858C50; Wed, 3 May 2023 16:24:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 87DD83858C50 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1683131079; bh=fwfcEvhjzCDA0WwQPGW1jE8LFHjcVa/uRZmG0Zu0tg0=; h=From:To:Subject:Date:From; b=f3u0HMRW33Jljhqs0JR+6nfDSvSKs3WQg7mexpYfaZ/7qrDQCjJy/fpFZVj6sTI+e xhiEbTBgskXbCMzwsr7UuxL9aC58MWacQxJ8Ho/CLDHye/rSEWe4wkxhsdjxTFGdgB A0hwvrTOtNFz1rshrDp1eHWTNUp95ZeXW4wLsuuE= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Lancelot SIX To: gdb-cvs@sourceware.org Subject: [binutils-gdb/lsix/poke-gdb] gdb/poke: Support the $reg::REGNAME syntax X-Act-Checkin: binutils-gdb X-Git-Author: Lancelot SIX X-Git-Refname: refs/heads/lsix/poke-gdb X-Git-Oldrev: 21c2659b8edc2cd70bfe291272bb5ea080a95b9a X-Git-Newrev: d734c63af73c6d774013e0091683246381b5ce63 Message-Id: <20230503162439.87DD83858C50@sourceware.org> Date: Wed, 3 May 2023 16:24:39 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3Dd734c63af73c= 6d774013e0091683246381b5ce63 commit d734c63af73c6d774013e0091683246381b5ce63 Author: Lancelot SIX Date: Mon Sep 19 12:30:12 2022 +0100 gdb/poke: Support the $reg::REGNAME syntax =20 Make it possible to use $reg::REGNAME to access the content of a register from poke expressions. Diff: --- gdb/doc/poke.texi | 42 ++++++++++++++++++++++++++++++++++++++++++ gdb/poke.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/gdb/doc/poke.texi b/gdb/doc/poke.texi index c7a3a8b43a4..8af56a224b8 100644 --- a/gdb/doc/poke.texi +++ b/gdb/doc/poke.texi @@ -373,3 +373,45 @@ struct_person @{ postal_address=3D0x5555555547c5UL#B @} @end smallexample + +Poke can read registers in the target by using the @code{$reg::REGNAME} +notation. The read is done in the context of the selected frame. + +The following example shows how poke could be used to decode the value of = the +@code{EFLAGS} register of the x86 ISA: + +@smallexample +(@value{GDBN}) poke type EFlags_T =3D + struct uint<32> + @{ + uint<27> other_flags; + uint<1> AF; + uint<1> r2 =3D 0; + uint<1> PF; + uint<1> r1 =3D 1; + uint<1> CF; + @} +(@value{GDBN}) poke $reg::eflags as EFlags_T +EFlags_T @{ + other_flags=3D(uint<27>) 0x12, + AF=3D(uint<1>) 0x0, + r2=3D(uint<1>) 0x0, + PF=3D(uint<1>) 0x1, + r1=3D(uint<1>) 0x1, + CF=3D(uint<1>) 0x0 +@} +@end smallexample + +It can also be useful to interpret the content of a register as an address= . To +do so, it is possible to use the @code{$reg::REGNAME#B} notation. + +For example, the following can be used to inspect the current stack frame: + +@smallexample +(@value{GDBN}) poke load "std-types.pk" +(@value{GDBN}) poke load ios +(@value{GDBN}) poke ios_dump_bytes :ios get_ios :from $reg::sp#B + :size ($reg::fp - $reg::sp)#B + :group_by 1#B +00007fffffffddd0: 0d f0 ad de 00 00 00 00 ef be ad de 00 00 00 00 +@end smallexample diff --git a/gdb/poke.c b/gdb/poke.c index e2833ed6bba..9bb24236d2f 100644 --- a/gdb/poke.c +++ b/gdb/poke.c @@ -22,6 +22,7 @@ #include "arch-utils.h" #include "target.h" #include "gdbcmd.h" +#include "user-regs.h" extern "C" { #include } @@ -320,6 +321,57 @@ poke_alien_token_handler (const char *id, char **errms= g) =3D (gdbarch_addressable_memory_unit_size (target_gdbarch ()) * 8); } + else if (strncmp (id, "reg::", 5) =3D=3D 0) + { + const std::string regname { id + 5 }; + + if (!target_has_registers ()) + { + *errmsg + =3D xstrdup (string_printf (_("cannot read register '%s': " + "target has no registers"), + regname.c_str ()).c_str ()); + return nullptr; + } + + frame_info *frame =3D get_selected_frame (); + struct gdbarch *gdbarch =3D get_frame_arch (frame); + const int regnum + =3D user_reg_map_name_to_regnum (gdbarch, regname.c_str (), + regname.length ()); + + if (regnum =3D=3D -1) + { + *errmsg =3D xstrdup (string_printf (_("unknown register '%s'"), + regname.c_str ()).c_str ()); + return nullptr; + } + + struct value *reg_value; + + try + { + reg_value =3D value_of_register (regnum, frame); + } + catch (const gdb_exception_error &except) + { + *errmsg + =3D xstrdup (string_printf (_("failed to fetch register '%s' " + "for selected frame"), + regname.c_str ()).c_str ()); + return nullptr; + } + + struct type *type =3D value_type (reg_value); + + alien_token.kind =3D PK_ALIEN_TOKEN_INTEGER; + alien_token.value.integer.magnitude + =3D value_as_long (reg_value); + alien_token.value.integer.width + =3D TYPE_LENGTH (type) * HOST_CHAR_BIT; + alien_token.value.integer.signed_p + =3D !type->is_unsigned (); + } else { struct value *value;