/* Dynamic architecture support for GDB, the GNU debugger.
- Copyright (C) 1998-2020 Free Software Foundation, Inc.
+ Copyright (C) 1998-2022 Free Software Foundation, Inc.
This file is part of GDB.
#include "gdb_obstack.h"
#include "infrun.h"
#include "osabi.h"
+#include "displaced-stepping.h"
struct floatformat;
struct ui_file;
struct syscalls_info;
struct thread_info;
struct ui_out;
+struct inferior;
#include "regcache.h"
return_method_struct,
};
+enum class memtag_type
+{
+ /* Logical tag, the tag that is stored in unused bits of a pointer to a
+ virtual address. */
+ logical = 0,
+
+ /* Allocation tag, the tag that is associated with every granule of memory in
+ the physical address space. Allocation tags are used to validate memory
+ accesses via pointers containing logical tags. */
+ allocation,
+};
+
/* The following are pre-initialized by GDBARCH. */
extern int gdbarch_significant_addr_bit (struct gdbarch *gdbarch);
extern void set_gdbarch_significant_addr_bit (struct gdbarch *gdbarch, int significant_addr_bit);
+/* Return a string representation of the memory tag TAG. */
+
+typedef std::string (gdbarch_memtag_to_string_ftype) (struct gdbarch *gdbarch, struct value *tag);
+extern std::string gdbarch_memtag_to_string (struct gdbarch *gdbarch, struct value *tag);
+extern void set_gdbarch_memtag_to_string (struct gdbarch *gdbarch, gdbarch_memtag_to_string_ftype *memtag_to_string);
+
+/* Return true if ADDRESS contains a tag and false otherwise. ADDRESS
+ must be either a pointer or a reference type. */
+
+typedef bool (gdbarch_tagged_address_p_ftype) (struct gdbarch *gdbarch, struct value *address);
+extern bool gdbarch_tagged_address_p (struct gdbarch *gdbarch, struct value *address);
+extern void set_gdbarch_tagged_address_p (struct gdbarch *gdbarch, gdbarch_tagged_address_p_ftype *tagged_address_p);
+
+/* Return true if the tag from ADDRESS matches the memory tag for that
+ particular address. Return false otherwise. */
+
+typedef bool (gdbarch_memtag_matches_p_ftype) (struct gdbarch *gdbarch, struct value *address);
+extern bool gdbarch_memtag_matches_p (struct gdbarch *gdbarch, struct value *address);
+extern void set_gdbarch_memtag_matches_p (struct gdbarch *gdbarch, gdbarch_memtag_matches_p_ftype *memtag_matches_p);
+
+/* Set the tags of type TAG_TYPE, for the memory address range
+ [ADDRESS, ADDRESS + LENGTH) to TAGS.
+ Return true if successful and false otherwise. */
+
+typedef bool (gdbarch_set_memtags_ftype) (struct gdbarch *gdbarch, struct value *address, size_t length, const gdb::byte_vector &tags, memtag_type tag_type);
+extern bool gdbarch_set_memtags (struct gdbarch *gdbarch, struct value *address, size_t length, const gdb::byte_vector &tags, memtag_type tag_type);
+extern void set_gdbarch_set_memtags (struct gdbarch *gdbarch, gdbarch_set_memtags_ftype *set_memtags);
+
+/* Return the tag of type TAG_TYPE associated with the memory address ADDRESS,
+ assuming ADDRESS is tagged. */
+
+typedef struct value * (gdbarch_get_memtag_ftype) (struct gdbarch *gdbarch, struct value *address, memtag_type tag_type);
+extern struct value * gdbarch_get_memtag (struct gdbarch *gdbarch, struct value *address, memtag_type tag_type);
+extern void set_gdbarch_get_memtag (struct gdbarch *gdbarch, gdbarch_get_memtag_ftype *get_memtag);
+
+/* memtag_granule_size is the size of the allocation tag granule, for
+ architectures that support memory tagging.
+ This is 0 for architectures that do not support memory tagging.
+ For a non-zero value, this represents the number of bytes of memory per tag. */
+
+extern CORE_ADDR gdbarch_memtag_granule_size (struct gdbarch *gdbarch);
+extern void set_gdbarch_memtag_granule_size (struct gdbarch *gdbarch, CORE_ADDR memtag_granule_size);
+
/* FIXME/cagney/2001-01-18: This should be split in two. A target method that
indicates if the target needs software single step. An ISA method to
implement it.
extern void gdbarch_displaced_step_fixup (struct gdbarch *gdbarch, struct displaced_step_copy_insn_closure *closure, CORE_ADDR from, CORE_ADDR to, struct regcache *regs);
extern void set_gdbarch_displaced_step_fixup (struct gdbarch *gdbarch, gdbarch_displaced_step_fixup_ftype *displaced_step_fixup);
-/* Return the address of an appropriate place to put displaced
- instructions while we step over them. There need only be one such
- place, since we're only stepping one thread over a breakpoint at a
- time.
+/* Prepare THREAD for it to displaced step the instruction at its current PC.
- For a general explanation of displaced stepping and how GDB uses it,
- see the comments in infrun.c. */
+ Throw an exception if any unexpected error happens. */
+
+extern bool gdbarch_displaced_step_prepare_p (struct gdbarch *gdbarch);
+
+typedef displaced_step_prepare_status (gdbarch_displaced_step_prepare_ftype) (struct gdbarch *gdbarch, thread_info *thread, CORE_ADDR &displaced_pc);
+extern displaced_step_prepare_status gdbarch_displaced_step_prepare (struct gdbarch *gdbarch, thread_info *thread, CORE_ADDR &displaced_pc);
+extern void set_gdbarch_displaced_step_prepare (struct gdbarch *gdbarch, gdbarch_displaced_step_prepare_ftype *displaced_step_prepare);
+
+/* Clean up after a displaced step of THREAD. */
+
+typedef displaced_step_finish_status (gdbarch_displaced_step_finish_ftype) (struct gdbarch *gdbarch, thread_info *thread, gdb_signal sig);
+extern displaced_step_finish_status gdbarch_displaced_step_finish (struct gdbarch *gdbarch, thread_info *thread, gdb_signal sig);
+extern void set_gdbarch_displaced_step_finish (struct gdbarch *gdbarch, gdbarch_displaced_step_finish_ftype *displaced_step_finish);
-typedef CORE_ADDR (gdbarch_displaced_step_location_ftype) (struct gdbarch *gdbarch);
-extern CORE_ADDR gdbarch_displaced_step_location (struct gdbarch *gdbarch);
-extern void set_gdbarch_displaced_step_location (struct gdbarch *gdbarch, gdbarch_displaced_step_location_ftype *displaced_step_location);
+/* Return the closure associated to the displaced step buffer that is at ADDR. */
+
+extern bool gdbarch_displaced_step_copy_insn_closure_by_addr_p (struct gdbarch *gdbarch);
+
+typedef const displaced_step_copy_insn_closure * (gdbarch_displaced_step_copy_insn_closure_by_addr_ftype) (inferior *inf, CORE_ADDR addr);
+extern const displaced_step_copy_insn_closure * gdbarch_displaced_step_copy_insn_closure_by_addr (struct gdbarch *gdbarch, inferior *inf, CORE_ADDR addr);
+extern void set_gdbarch_displaced_step_copy_insn_closure_by_addr (struct gdbarch *gdbarch, gdbarch_displaced_step_copy_insn_closure_by_addr_ftype *displaced_step_copy_insn_closure_by_addr);
+
+/* PARENT_INF has forked and CHILD_PTID is the ptid of the child. Restore the
+ contents of all displaced step buffers in the child's address space. */
+
+typedef void (gdbarch_displaced_step_restore_all_in_ptid_ftype) (inferior *parent_inf, ptid_t child_ptid);
+extern void gdbarch_displaced_step_restore_all_in_ptid (struct gdbarch *gdbarch, inferior *parent_inf, ptid_t child_ptid);
+extern void set_gdbarch_displaced_step_restore_all_in_ptid (struct gdbarch *gdbarch, gdbarch_displaced_step_restore_all_in_ptid_ftype *displaced_step_restore_all_in_ptid);
/* Relocate an instruction to execute at a different address. OLDLOC
is the address in the inferior memory where the instruction to
extern bool gdbarch_stap_parse_special_token_p (struct gdbarch *gdbarch);
-typedef int (gdbarch_stap_parse_special_token_ftype) (struct gdbarch *gdbarch, struct stap_parse_info *p);
-extern int gdbarch_stap_parse_special_token (struct gdbarch *gdbarch, struct stap_parse_info *p);
+typedef expr::operation_up (gdbarch_stap_parse_special_token_ftype) (struct gdbarch *gdbarch, struct stap_parse_info *p);
+extern expr::operation_up gdbarch_stap_parse_special_token (struct gdbarch *gdbarch, struct stap_parse_info *p);
extern void set_gdbarch_stap_parse_special_token (struct gdbarch *gdbarch, gdbarch_stap_parse_special_token_ftype *stap_parse_special_token);
/* Perform arch-dependent adjustments to a register name.
extern bool gdbarch_dtrace_parse_probe_argument_p (struct gdbarch *gdbarch);
-typedef void (gdbarch_dtrace_parse_probe_argument_ftype) (struct gdbarch *gdbarch, struct expr_builder *builder, int narg);
-extern void gdbarch_dtrace_parse_probe_argument (struct gdbarch *gdbarch, struct expr_builder *builder, int narg);
+typedef expr::operation_up (gdbarch_dtrace_parse_probe_argument_ftype) (struct gdbarch *gdbarch, int narg);
+extern expr::operation_up gdbarch_dtrace_parse_probe_argument (struct gdbarch *gdbarch, int narg);
extern void set_gdbarch_dtrace_parse_probe_argument (struct gdbarch *gdbarch, gdbarch_dtrace_parse_probe_argument_ftype *dtrace_parse_probe_argument);
/* True if the given ADDR does not contain the instruction sequence
struct gdbarch_info
{
- /* Use default: NULL (ZERO). */
- const struct bfd_arch_info *bfd_arch_info;
+ gdbarch_info ()
+ /* Ensure the union is zero-initialized. Relies on the fact that there's
+ no member larger than TDESC_DATA. */
+ : tdesc_data ()
+ {}
+
+ const struct bfd_arch_info *bfd_arch_info = nullptr;
- /* Use default: BFD_ENDIAN_UNKNOWN (NB: is not ZERO). */
- enum bfd_endian byte_order;
+ enum bfd_endian byte_order = BFD_ENDIAN_UNKNOWN;
- enum bfd_endian byte_order_for_code;
+ enum bfd_endian byte_order_for_code = BFD_ENDIAN_UNKNOWN;
- /* Use default: NULL (ZERO). */
- bfd *abfd;
+ bfd *abfd = nullptr;
- /* Use default: NULL (ZERO). */
union
{
- /* Architecture-specific information. The generic form for targets
- that have extra requirements. */
- struct gdbarch_tdep_info *tdep_info;
-
/* Architecture-specific target description data. Numerous targets
need only this, so give them an easy way to hold it. */
struct tdesc_arch_data *tdesc_data;
int *id;
};
- /* Use default: GDB_OSABI_UNINITIALIZED (-1). */
- enum gdb_osabi osabi;
+ enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
- /* Use default: NULL (ZERO). */
- const struct target_desc *target_desc;
+ const struct target_desc *target_desc = nullptr;
};
typedef struct gdbarch *(gdbarch_init_ftype) (struct gdbarch_info info, struct gdbarch_list *arches);
/* Helper function. Find an architecture matching info.
- INFO should be initialized using gdbarch_info_init, relevant fields
- set, and then finished using gdbarch_info_fill.
+ INFO should have relevant fields set, and then finished using
+ gdbarch_info_fill.
Returns the corresponding architecture, or NULL if no matching
architecture was found. */