forked from Imagelibrary/binutils-gdb
gdb/poke: Support the $reg::REGNAME syntax
Make it possible to use $reg::REGNAME to access the content of a register from poke expressions.
This commit is contained in:
committed by
Lancelot SIX
parent
21c2659b8e
commit
d734c63af7
@@ -373,3 +373,45 @@ struct_person @{
|
||||
postal_address=0x5555555547c5UL#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 =
|
||||
struct uint<32>
|
||||
@{
|
||||
uint<27> other_flags;
|
||||
uint<1> AF;
|
||||
uint<1> r2 = 0;
|
||||
uint<1> PF;
|
||||
uint<1> r1 = 1;
|
||||
uint<1> CF;
|
||||
@}
|
||||
(@value{GDBN}) poke $reg::eflags as EFlags_T
|
||||
EFlags_T @{
|
||||
other_flags=(uint<27>) 0x12,
|
||||
AF=(uint<1>) 0x0,
|
||||
r2=(uint<1>) 0x0,
|
||||
PF=(uint<1>) 0x1,
|
||||
r1=(uint<1>) 0x1,
|
||||
CF=(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
|
||||
|
||||
52
gdb/poke.c
52
gdb/poke.c
@@ -22,6 +22,7 @@
|
||||
#include "arch-utils.h"
|
||||
#include "target.h"
|
||||
#include "gdbcmd.h"
|
||||
#include "user-regs.h"
|
||||
extern "C" {
|
||||
#include <libpoke.h>
|
||||
}
|
||||
@@ -320,6 +321,57 @@ poke_alien_token_handler (const char *id, char **errmsg)
|
||||
= (gdbarch_addressable_memory_unit_size (target_gdbarch ())
|
||||
* 8);
|
||||
}
|
||||
else if (strncmp (id, "reg::", 5) == 0)
|
||||
{
|
||||
const std::string regname { id + 5 };
|
||||
|
||||
if (!target_has_registers ())
|
||||
{
|
||||
*errmsg
|
||||
= xstrdup (string_printf (_("cannot read register '%s': "
|
||||
"target has no registers"),
|
||||
regname.c_str ()).c_str ());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
frame_info *frame = get_selected_frame ();
|
||||
struct gdbarch *gdbarch = get_frame_arch (frame);
|
||||
const int regnum
|
||||
= user_reg_map_name_to_regnum (gdbarch, regname.c_str (),
|
||||
regname.length ());
|
||||
|
||||
if (regnum == -1)
|
||||
{
|
||||
*errmsg = xstrdup (string_printf (_("unknown register '%s'"),
|
||||
regname.c_str ()).c_str ());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct value *reg_value;
|
||||
|
||||
try
|
||||
{
|
||||
reg_value = value_of_register (regnum, frame);
|
||||
}
|
||||
catch (const gdb_exception_error &except)
|
||||
{
|
||||
*errmsg
|
||||
= xstrdup (string_printf (_("failed to fetch register '%s' "
|
||||
"for selected frame"),
|
||||
regname.c_str ()).c_str ());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct type *type = value_type (reg_value);
|
||||
|
||||
alien_token.kind = PK_ALIEN_TOKEN_INTEGER;
|
||||
alien_token.value.integer.magnitude
|
||||
= value_as_long (reg_value);
|
||||
alien_token.value.integer.width
|
||||
= TYPE_LENGTH (type) * HOST_CHAR_BIT;
|
||||
alien_token.value.integer.signed_p
|
||||
= !type->is_unsigned ();
|
||||
}
|
||||
else
|
||||
{
|
||||
struct value *value;
|
||||
|
||||
Reference in New Issue
Block a user