Move [PAC] into a new MI field addr_flags

Add a new print_pc which prints both the PC and a new field addr_flags.
Call this wherever the PC is printed in stack.c.

Add a new gdbarch method get_pc_address_flags to obtain the addr_flag
contents. By default returns an empty string, on AArch64 this returns
PAC if the address has been masked in the frame.

Document this in the manual and NEWS file.

gdb/ChangeLog:

	* NEWS (Other MI changes): New subsection.
	* aarch64-tdep.c (aarch64_get_pc_address_flags): New function.
	(aarch64_gdbarch_init): Add aarch64_get_pc_address_flags.
	* arch-utils.c (default_get_pc_address_flags): New function.
	* arch-utils.h (default_get_pc_address_flags): New declaration.
	* gdbarch.sh: Add get_pc_address_flags.
	* gdbarch.c: Regenerate.
	* gdbarch.h: Likewise.
	* stack.c (print_pc): New function.
	(print_frame_info) (print_frame): Call print_pc.

gdb/doc/ChangeLog:

	* gdb.texinfo (AArch64 Pointer Authentication)
	(GDB/MI Breakpoint Information) (Frame Information): Document
	addr_field.
This commit is contained in:
Alan Hayward 2019-08-16 10:19:18 +01:00
parent fdfc8cf7f0
commit aa7ca1bb44
11 changed files with 120 additions and 10 deletions

View File

@ -1,3 +1,16 @@
2019-08-16 Alan Hayward <alan.hayward@arm.com>
* NEWS (Other MI changes): New subsection.
* aarch64-tdep.c (aarch64_get_pc_address_flags): New function.
(aarch64_gdbarch_init): Add aarch64_get_pc_address_flags.
* arch-utils.c (default_get_pc_address_flags): New function.
* arch-utils.h (default_get_pc_address_flags): New declaration.
* gdbarch.sh: Add get_pc_address_flags.
* gdbarch.c: Regenerate.
* gdbarch.h: Likewise.
* stack.c (print_pc): New function.
(print_frame_info) (print_frame): Call print_pc.
2019-08-16 Tom de Vries <tdevries@suse.de>
* maint.c (maintenance_info_sections): Also handle !ALLOBJ case using

View File

@ -287,6 +287,13 @@ maint show test-options-completion-result
These can be used to catch C++ exceptions in a similar fashion to
the CLI commands 'catch throw', 'catch rethrow', and 'catch catch'.
* Other MI changes
** Backtraces and frames include a new optional field addr_flags which is
given after the addr field. On AArch64 this contains PAC if the address
has been masked in the frame. On all other targets the field is not
present.
* Testsuite
The testsuite now creates the files gdb.cmd (containing the arguments

View File

@ -273,6 +273,17 @@ aarch64_frame_unmask_lr (struct gdbarch_tdep *tdep,
return addr;
}
/* Implement the "get_pc_address_flags" gdbarch method. */
static std::string
aarch64_get_pc_address_flags (frame_info *frame, CORE_ADDR pc)
{
if (pc != 0 && get_frame_pc_masked (frame))
return "PAC";
return "";
}
/* Analyze a prologue, looking for a recognizable stack frame
and frame pointer. Scan until we encounter a store that could
clobber the stack frame unexpectedly, or an unknown instruction. */
@ -3370,6 +3381,8 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_gen_return_address (gdbarch, aarch64_gen_return_address);
set_gdbarch_get_pc_address_flags (gdbarch, aarch64_get_pc_address_flags);
tdesc_use_registers (gdbarch, tdesc, tdesc_data);
/* Add standard register aliases. */

View File

@ -995,6 +995,14 @@ default_type_align (struct gdbarch *gdbarch, struct type *type)
return 0;
}
/* See arch-utils.h. */
std::string
default_get_pc_address_flags (frame_info *frame, CORE_ADDR pc)
{
return "";
}
void
_initialize_gdbarch_utils (void)
{

View File

@ -272,4 +272,8 @@ extern bool default_in_indirect_branch_thunk (gdbarch *gdbarch,
extern ULONGEST default_type_align (struct gdbarch *gdbarch,
struct type *type);
/* Default implementation of gdbarch get_pc_address_flags method. */
extern std::string default_get_pc_address_flags (frame_info *frame,
CORE_ADDR pc);
#endif /* ARCH_UTILS_H */

View File

@ -1,3 +1,9 @@
2019-08-16 Alan Hayward <alan.hayward@arm.com>
* gdb.texinfo (AArch64 Pointer Authentication)
(GDB/MI Breakpoint Information) (Frame Information): Document
addr_field.
2019-08-12 Tom Tromey <tom@tromey.com>
* gdb.texinfo (Configure Options): Document minimum version of

View File

@ -24397,7 +24397,8 @@ When @value{GDBN} is debugging the AArch64 architecture, and the program is
using the v8.3-A feature Pointer Authentication (PAC), then whenever the link
register @code{$lr} is pointing to an PAC function its value will be masked.
When GDB prints a backtrace, any addresses that required unmasking will be
postfixed with the marker [PAC].
postfixed with the marker [PAC]. When using the MI, this is printed as part
of the @code{addr_flags} field.
@node i386
@subsection x86 Architecture-specific Issues
@ -28925,6 +28926,11 @@ breakpoint; or the string @samp{<MULTIPLE>}, for a breakpoint with
multiple locations. This field will not be present if no address can
be determined. For example, a watchpoint does not have an address.
@item addr_flags
Optional field containing any flags related to the address. These flags are
architecture-dependent; see @ref{Architectures} for their meaning for a
particular CPU.
@item func
If known, the function in which the breakpoint appears.
If not known, this field is not present.
@ -29025,6 +29031,11 @@ Note that this is not the same as the field @code{enable}.
@item addr
The address of this location as an hexidecimal number.
@item addr_flags
Optional field containing any flags related to the address. These flags are
architecture-dependent; see @ref{Architectures} for their meaning for a
particular CPU.
@item func
If known, the function in which the location appears.
If not known, this field is not present.
@ -29077,6 +29088,11 @@ be absent if @value{GDBN} is unable to determine the function name.
@item addr
The code address for the frame. This field is always present.
@item addr_flags
Optional field containing any flags related to the address. These flags are
architecture-dependent; see @ref{Architectures} for their meaning for a
particular CPU.
@item file
The name of the source files that correspond to the frame's code
address. This field may be absent.

View File

@ -358,6 +358,7 @@ struct gdbarch
char ** disassembler_options;
const disasm_options_and_args_t * valid_disassembler_options;
gdbarch_type_align_ftype *type_align;
gdbarch_get_pc_address_flags_ftype *get_pc_address_flags;
};
/* Create a new ``struct gdbarch'' based on information provided by
@ -473,6 +474,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
gdbarch->gnu_triplet_regexp = default_gnu_triplet_regexp;
gdbarch->addressable_memory_unit_size = default_addressable_memory_unit_size;
gdbarch->type_align = default_type_align;
gdbarch->get_pc_address_flags = default_get_pc_address_flags;
/* gdbarch_alloc() */
return gdbarch;
@ -721,6 +723,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of disassembler_options, invalid_p == 0 */
/* Skip verify of valid_disassembler_options, invalid_p == 0 */
/* Skip verify of type_align, invalid_p == 0 */
/* Skip verify of get_pc_address_flags, invalid_p == 0 */
if (!log.empty ())
internal_error (__FILE__, __LINE__,
_("verify_gdbarch: the following are invalid ...%s"),
@ -1065,6 +1068,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
fprintf_unfiltered (file,
"gdbarch_dump: get_longjmp_target = <%s>\n",
host_address_to_string (gdbarch->get_longjmp_target));
fprintf_unfiltered (file,
"gdbarch_dump: get_pc_address_flags = <%s>\n",
host_address_to_string (gdbarch->get_pc_address_flags));
fprintf_unfiltered (file,
"gdbarch_dump: gdbarch_get_siginfo_type_p() = %d\n",
gdbarch_get_siginfo_type_p (gdbarch));
@ -5156,6 +5162,23 @@ set_gdbarch_type_align (struct gdbarch *gdbarch,
gdbarch->type_align = type_align;
}
std::string
gdbarch_get_pc_address_flags (struct gdbarch *gdbarch, frame_info *frame, CORE_ADDR pc)
{
gdb_assert (gdbarch != NULL);
gdb_assert (gdbarch->get_pc_address_flags != NULL);
if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_get_pc_address_flags called\n");
return gdbarch->get_pc_address_flags (frame, pc);
}
void
set_gdbarch_get_pc_address_flags (struct gdbarch *gdbarch,
gdbarch_get_pc_address_flags_ftype get_pc_address_flags)
{
gdbarch->get_pc_address_flags = get_pc_address_flags;
}
/* Keep a registry of per-architecture data-pointers required by GDB
modules. */

View File

@ -1640,6 +1640,12 @@ typedef ULONGEST (gdbarch_type_align_ftype) (struct gdbarch *gdbarch, struct typ
extern ULONGEST gdbarch_type_align (struct gdbarch *gdbarch, struct type *type);
extern void set_gdbarch_type_align (struct gdbarch *gdbarch, gdbarch_type_align_ftype *type_align);
/* Return a string containing any flags for the given PC in the given FRAME. */
typedef std::string (gdbarch_get_pc_address_flags_ftype) (frame_info *frame, CORE_ADDR pc);
extern std::string gdbarch_get_pc_address_flags (struct gdbarch *gdbarch, frame_info *frame, CORE_ADDR pc);
extern void set_gdbarch_get_pc_address_flags (struct gdbarch *gdbarch, gdbarch_get_pc_address_flags_ftype *get_pc_address_flags);
extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);

View File

@ -1210,6 +1210,9 @@ v;const disasm_options_and_args_t *;valid_disassembler_options;;;0;0;;0;host_add
# default rules as laid out in gdbtypes.c:type_align.
m;ULONGEST;type_align;struct type *type;type;;default_type_align;;0
# Return a string containing any flags for the given PC in the given FRAME.
f;std::string;get_pc_address_flags;frame_info *frame, CORE_ADDR pc;frame, pc;;default_get_pc_address_flags;;0
EOF
}

View File

@ -923,6 +923,23 @@ print_frame_info_to_print_what (const char *print_frame_info)
print_frame_info);
}
/* Print the PC from FRAME, plus any flags, to UIOUT. */
static void
print_pc (struct ui_out *uiout, struct gdbarch *gdbarch, frame_info *frame,
CORE_ADDR pc)
{
uiout->field_core_addr ("addr", gdbarch, pc);
std::string flags = gdbarch_get_pc_address_flags (gdbarch, frame, pc);
if (!flags.empty ())
{
uiout->text (" [");
uiout->field_string ("addr_flags", flags);
uiout->text ("]");
}
}
/* See stack.h. */
void
@ -980,8 +997,7 @@ print_frame_info (const frame_print_options &fp_opts,
if (uiout->is_mi_like_p ())
{
annotate_frame_address ();
uiout->field_core_addr ("addr",
gdbarch, get_frame_pc (frame));
print_pc (uiout, gdbarch, frame, get_frame_pc (frame));
annotate_frame_address_end ();
}
@ -1065,8 +1081,7 @@ print_frame_info (const frame_print_options &fp_opts,
ability to decide for themselves if it is desired. */
if (opts.addressprint && mid_statement)
{
uiout->field_core_addr ("addr",
gdbarch, get_frame_pc (frame));
print_pc (uiout, gdbarch, frame, get_frame_pc (frame));
uiout->text ("\t");
}
@ -1292,11 +1307,7 @@ print_frame (const frame_print_options &fp_opts,
{
annotate_frame_address ();
if (pc_p)
{
uiout->field_core_addr ("addr", gdbarch, pc);
if (get_frame_pc_masked (frame))
uiout->field_string ("pac", " [PAC]");
}
print_pc (uiout, gdbarch, frame, pc);
else
uiout->field_string ("addr", "<unavailable>",
ui_out_style_kind::ADDRESS);