[v5,1/2] gdb: Make tagged pointer support configurable.
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gdb_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-arm |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 |
success
|
Test passed
|
Commit Message
From: Christina Schimpe <christina.schimpe@intel.com>
The gdbarch function gdbarch_remove_non_address_bits adjusts addresses to
enable debugging of programs with tagged pointers on Linux, for instance for
ARM's feature top byte ignore (TBI).
Once the function is implemented for an architecture, it adjusts addresses for
memory access, breakpoints and watchpoints.
Linear address masking (LAM) is Intel's (R) implementation of tagged
pointer support. It requires certain adaptions to GDB's tagged pointer
support due to the following:
- LAM supports address tagging for data accesses only. Thus, specifying
breakpoints on tagged addresses is not a valid use case.
- In contrast to the implementation for ARM's TBI, the Linux kernel supports
tagged pointers for memory access.
This patch makes GDB's tagged pointer support configurable such that it is
possible to enable the address adjustment for a specific feature only (e.g
memory access, breakpoints or watchpoints). This way, one can make sure
that addresses are only adjusted when necessary. In case of LAM, this
avoids unnecessary parsing of the /proc/<pid>/status file to get the
untag mask.
Reviewed-By: Felix Willgerodt <felix.willgerodt@intel.com>
---
gdb/aarch64-linux-nat.c | 2 +-
gdb/aarch64-linux-tdep.c | 13 ++++----
gdb/aarch64-tdep.c | 17 ++++++----
gdb/aarch64-tdep.h | 6 ++++
gdb/breakpoint.c | 5 +--
gdb/gdbarch-gen.h | 49 ++++++++++++++++++++++-------
gdb/gdbarch.c | 66 ++++++++++++++++++++++++++++++++-------
gdb/gdbarch_components.py | 53 ++++++++++++++++++++++++++-----
gdb/target.c | 3 +-
9 files changed, 168 insertions(+), 46 deletions(-)
Comments
On 7/9/24 13:17, Schimpe, Christina wrote:
> From: Christina Schimpe <christina.schimpe@intel.com>
>
> The gdbarch function gdbarch_remove_non_address_bits adjusts addresses to
> enable debugging of programs with tagged pointers on Linux, for instance for
> ARM's feature top byte ignore (TBI).
> Once the function is implemented for an architecture, it adjusts addresses for
> memory access, breakpoints and watchpoints.
>
> Linear address masking (LAM) is Intel's (R) implementation of tagged
> pointer support. It requires certain adaptions to GDB's tagged pointer
> support due to the following:
> - LAM supports address tagging for data accesses only. Thus, specifying
> breakpoints on tagged addresses is not a valid use case.
> - In contrast to the implementation for ARM's TBI, the Linux kernel supports
> tagged pointers for memory access.
>
> This patch makes GDB's tagged pointer support configurable such that it is
> possible to enable the address adjustment for a specific feature only (e.g
> memory access, breakpoints or watchpoints). This way, one can make sure
> that addresses are only adjusted when necessary. In case of LAM, this
> avoids unnecessary parsing of the /proc/<pid>/status file to get the
> untag mask.
>
> Reviewed-By: Felix Willgerodt <felix.willgerodt@intel.com>
> ---
> gdb/aarch64-linux-nat.c | 2 +-
> gdb/aarch64-linux-tdep.c | 13 ++++----
> gdb/aarch64-tdep.c | 17 ++++++----
> gdb/aarch64-tdep.h | 6 ++++
> gdb/breakpoint.c | 5 +--
> gdb/gdbarch-gen.h | 49 ++++++++++++++++++++++-------
> gdb/gdbarch.c | 66 ++++++++++++++++++++++++++++++++-------
> gdb/gdbarch_components.py | 53 ++++++++++++++++++++++++++-----
> gdb/target.c | 3 +-
> 9 files changed, 168 insertions(+), 46 deletions(-)
>
> diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
> index 2e6541f53c3..dac42b4f48b 100644
> --- a/gdb/aarch64-linux-nat.c
> +++ b/gdb/aarch64-linux-nat.c
> @@ -945,7 +945,7 @@ aarch64_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
> kernel can potentially be tagged addresses. */
> struct gdbarch *gdbarch = thread_architecture (inferior_ptid);
> const CORE_ADDR addr_trap
> - = gdbarch_remove_non_address_bits (gdbarch, (CORE_ADDR) siginfo.si_addr);
> + = aarch64_remove_non_address_bits (gdbarch, (CORE_ADDR) siginfo.si_addr);
>
> /* Check if the address matches any watched address. */
> state = aarch64_get_debug_reg_state (inferior_ptid.pid ());
> diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
> index a1296a8f0c7..bf5ce72aa5f 100644
> --- a/gdb/aarch64-linux-tdep.c
> +++ b/gdb/aarch64-linux-tdep.c
> @@ -2456,7 +2456,7 @@ static bool
> aarch64_linux_tagged_address_p (struct gdbarch *gdbarch, CORE_ADDR address)
> {
> /* Remove the top byte for the memory range check. */
> - address = gdbarch_remove_non_address_bits (gdbarch, address);
> + address = aarch64_remove_non_address_bits (gdbarch, address);
>
> /* Check if the page that contains ADDRESS is mapped with PROT_MTE. */
> if (!linux_address_in_memtag_page (address))
> @@ -2478,7 +2478,7 @@ aarch64_linux_memtag_matches_p (struct gdbarch *gdbarch,
>
> /* Fetch the allocation tag for ADDRESS. */
> std::optional<CORE_ADDR> atag
> - = aarch64_mte_get_atag (gdbarch_remove_non_address_bits (gdbarch, addr));
> + = aarch64_mte_get_atag (aarch64_remove_non_address_bits (gdbarch, addr));
>
> if (!atag.has_value ())
> return true;
> @@ -2517,7 +2517,7 @@ aarch64_linux_set_memtags (struct gdbarch *gdbarch, struct value *address,
> else
> {
> /* Remove the top byte. */
> - addr = gdbarch_remove_non_address_bits (gdbarch, addr);
> + addr = aarch64_remove_non_address_bits (gdbarch, addr);
>
> /* With G being the number of tag granules and N the number of tags
> passed in, we can have the following cases:
> @@ -2566,7 +2566,7 @@ aarch64_linux_get_memtag (struct gdbarch *gdbarch, struct value *address,
> else
> {
> /* Remove the top byte. */
> - addr = gdbarch_remove_non_address_bits (gdbarch, addr);
> + addr = aarch64_remove_non_address_bits (gdbarch, addr);
> std::optional<CORE_ADDR> atag = aarch64_mte_get_atag (addr);
>
> if (!atag.has_value ())
> @@ -2640,8 +2640,9 @@ aarch64_linux_report_signal_info (struct gdbarch *gdbarch,
> uiout->text ("\n");
>
> std::optional<CORE_ADDR> atag
> - = aarch64_mte_get_atag (gdbarch_remove_non_address_bits (gdbarch,
> - fault_addr));
> + = aarch64_mte_get_atag (
> + aarch64_remove_non_address_bits (gdbarch, fault_addr));
> +
> gdb_byte ltag = aarch64_mte_get_ltag (fault_addr);
>
> if (!atag.has_value ())
> diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
> index e4bca6c6632..ba1dc3d5844 100644
> --- a/gdb/aarch64-tdep.c
> +++ b/gdb/aarch64-tdep.c
> @@ -4088,10 +4088,9 @@ aarch64_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
> return streq (inst.opcode->name, "ret");
> }
>
> -/* AArch64 implementation of the remove_non_address_bits gdbarch hook. Remove
> - non address bits from a pointer value. */
> +/* See aarch64-tdep.h. */
>
> -static CORE_ADDR
> +CORE_ADDR
> aarch64_remove_non_address_bits (struct gdbarch *gdbarch, CORE_ADDR pointer)
> {
> /* By default, we assume TBI and discard the top 8 bits plus the VA range
> @@ -4585,9 +4584,15 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
> tdep->ra_sign_state_regnum = ra_sign_state_offset + num_regs;
>
> /* Architecture hook to remove bits of a pointer that are not part of the
> - address, like memory tags (MTE) and pointer authentication signatures. */
> - set_gdbarch_remove_non_address_bits (gdbarch,
> - aarch64_remove_non_address_bits);
> + address, like memory tags (MTE) and pointer authentication signatures.
> + Configure address adjustment for watch-, breakpoints and memory
> + transfer. */
> + set_gdbarch_remove_non_address_bits_watchpoint
> + (gdbarch, aarch64_remove_non_address_bits);
> + set_gdbarch_remove_non_address_bits_breakpoint
> + (gdbarch, aarch64_remove_non_address_bits);
> + set_gdbarch_remove_non_address_bits_memory
> + (gdbarch, aarch64_remove_non_address_bits);
>
> /* SME pseudo-registers. */
> if (tdep->has_sme ())
> diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h
> index 0e6024bfcbc..a9c8815f8be 100644
> --- a/gdb/aarch64-tdep.h
> +++ b/gdb/aarch64-tdep.h
> @@ -203,4 +203,10 @@ void aarch64_displaced_step_fixup (struct gdbarch *gdbarch,
>
> bool aarch64_displaced_step_hw_singlestep (struct gdbarch *gdbarch);
>
> +/* AArch64 implementation of the remove_non_address_bits gdbarch hooks.
> + Remove non address bits from a pointer value. */
> +
> +CORE_ADDR aarch64_remove_non_address_bits (struct gdbarch *gdbarch,
> + CORE_ADDR pointer);
> +
> #endif /* aarch64-tdep.h */
> diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
> index a973518ac5f..8c2d9d247ec 100644
> --- a/gdb/breakpoint.c
> +++ b/gdb/breakpoint.c
> @@ -2238,7 +2238,8 @@ update_watchpoint (struct watchpoint *b, bool reparse)
> loc->gdbarch = v->type ()->arch ();
> loc->pspace = wp_pspace;
> loc->address
> - = gdbarch_remove_non_address_bits (loc->gdbarch, addr);
> + = gdbarch_remove_non_address_bits_watchpoint (loc->gdbarch,
> + addr);
> b->add_location (*loc);
>
> if (bitsize != 0)
> @@ -7477,7 +7478,7 @@ adjust_breakpoint_address (struct gdbarch *gdbarch,
> }
>
> adjusted_bpaddr
> - = gdbarch_remove_non_address_bits (gdbarch, adjusted_bpaddr);
> + = gdbarch_remove_non_address_bits_breakpoint (gdbarch, adjusted_bpaddr);
>
> /* An adjusted breakpoint address can significantly alter
> a user's expectations. Print a warning if an adjustment
> diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h
> index b982fd7cd09..9fda85f860f 100644
> --- a/gdb/gdbarch-gen.h
> +++ b/gdb/gdbarch-gen.h
> @@ -684,19 +684,46 @@ extern CORE_ADDR gdbarch_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR ad
> extern void set_gdbarch_addr_bits_remove (struct gdbarch *gdbarch, gdbarch_addr_bits_remove_ftype *addr_bits_remove);
>
> /* On some architectures, not all bits of a pointer are significant.
> - On AArch64, for example, the top bits of a pointer may carry a "tag", which
> - can be ignored by the kernel and the hardware. The "tag" can be regarded as
> - additional data associated with the pointer, but it is not part of the address.
> + On AArch64 and amd64, for example, the top bits of a pointer may carry a
> + "tag", which can be ignored by the kernel and the hardware. The "tag" can be
> + regarded as additional data associated with the pointer, but it is not part
> + of the address.
>
> Given a pointer for the architecture, this hook removes all the
> - non-significant bits and sign-extends things as needed. It gets used to remove
> - non-address bits from data pointers (for example, removing the AArch64 MTE tag
> - bits from a pointer) and from code pointers (removing the AArch64 PAC signature
> - from a pointer containing the return address). */
> -
> -typedef CORE_ADDR (gdbarch_remove_non_address_bits_ftype) (struct gdbarch *gdbarch, CORE_ADDR pointer);
> -extern CORE_ADDR gdbarch_remove_non_address_bits (struct gdbarch *gdbarch, CORE_ADDR pointer);
> -extern void set_gdbarch_remove_non_address_bits (struct gdbarch *gdbarch, gdbarch_remove_non_address_bits_ftype *remove_non_address_bits);
> + non-significant bits and sign-extends things as needed. It gets used to
> + remove non-address bits from pointers used for watchpoints. */
> +
> +typedef CORE_ADDR (gdbarch_remove_non_address_bits_watchpoint_ftype) (struct gdbarch *gdbarch, CORE_ADDR pointer);
> +extern CORE_ADDR gdbarch_remove_non_address_bits_watchpoint (struct gdbarch *gdbarch, CORE_ADDR pointer);
> +extern void set_gdbarch_remove_non_address_bits_watchpoint (struct gdbarch *gdbarch, gdbarch_remove_non_address_bits_watchpoint_ftype *remove_non_address_bits_watchpoint);
> +
> +/* On some architectures, not all bits of a pointer are significant.
> + On AArch64 and amd64, for example, the top bits of a pointer may carry a
> + "tag", which can be ignored by the kernel and the hardware. The "tag" can be
> + regarded as additional data associated with the pointer, but it is not part
> + of the address.
> +
> + Given a pointer for the architecture, this hook removes all the
> + non-significant bits and sign-extends things as needed. It gets used to
> + remove non-address bits from pointers used for breakpoints. */
> +
> +typedef CORE_ADDR (gdbarch_remove_non_address_bits_breakpoint_ftype) (struct gdbarch *gdbarch, CORE_ADDR pointer);
> +extern CORE_ADDR gdbarch_remove_non_address_bits_breakpoint (struct gdbarch *gdbarch, CORE_ADDR pointer);
> +extern void set_gdbarch_remove_non_address_bits_breakpoint (struct gdbarch *gdbarch, gdbarch_remove_non_address_bits_breakpoint_ftype *remove_non_address_bits_breakpoint);
> +
> +/* On some architectures, not all bits of a pointer are significant.
> + On AArch64 and amd64, for example, the top bits of a pointer may carry a
> + "tag", which can be ignored by the kernel and the hardware. The "tag" can be
> + regarded as additional data associated with the pointer, but it is not part
> + of the address.
> +
> + Given a pointer for the architecture, this hook removes all the
> + non-significant bits and sign-extends things as needed. It gets used to
> + remove non-address bits from any pointer used to access memory. */
> +
> +typedef CORE_ADDR (gdbarch_remove_non_address_bits_memory_ftype) (struct gdbarch *gdbarch, CORE_ADDR pointer);
> +extern CORE_ADDR gdbarch_remove_non_address_bits_memory (struct gdbarch *gdbarch, CORE_ADDR pointer);
> +extern void set_gdbarch_remove_non_address_bits_memory (struct gdbarch *gdbarch, gdbarch_remove_non_address_bits_memory_ftype *remove_non_address_bits_memory);
>
> /* Return a string representation of the memory tag TAG. */
>
> diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
> index 58e9ebbdc59..99a54a38d61 100644
> --- a/gdb/gdbarch.c
> +++ b/gdb/gdbarch.c
> @@ -143,7 +143,9 @@ struct gdbarch
> int frame_red_zone_size = 0;
> gdbarch_convert_from_func_ptr_addr_ftype *convert_from_func_ptr_addr = convert_from_func_ptr_addr_identity;
> gdbarch_addr_bits_remove_ftype *addr_bits_remove = core_addr_identity;
> - gdbarch_remove_non_address_bits_ftype *remove_non_address_bits = default_remove_non_address_bits;
> + gdbarch_remove_non_address_bits_watchpoint_ftype *remove_non_address_bits_watchpoint = default_remove_non_address_bits;
> + gdbarch_remove_non_address_bits_breakpoint_ftype *remove_non_address_bits_breakpoint = default_remove_non_address_bits;
> + gdbarch_remove_non_address_bits_memory_ftype *remove_non_address_bits_memory = default_remove_non_address_bits;
> gdbarch_memtag_to_string_ftype *memtag_to_string = default_memtag_to_string;
> gdbarch_tagged_address_p_ftype *tagged_address_p = default_tagged_address_p;
> gdbarch_memtag_matches_p_ftype *memtag_matches_p = default_memtag_matches_p;
> @@ -407,7 +409,9 @@ verify_gdbarch (struct gdbarch *gdbarch)
> /* Skip verify of frame_red_zone_size, invalid_p == 0 */
> /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */
> /* Skip verify of addr_bits_remove, invalid_p == 0 */
> - /* Skip verify of remove_non_address_bits, invalid_p == 0 */
> + /* Skip verify of remove_non_address_bits_watchpoint, invalid_p == 0 */
> + /* Skip verify of remove_non_address_bits_breakpoint, invalid_p == 0 */
> + /* Skip verify of remove_non_address_bits_memory, invalid_p == 0 */
> /* Skip verify of memtag_to_string, invalid_p == 0 */
> /* Skip verify of tagged_address_p, invalid_p == 0 */
> /* Skip verify of memtag_matches_p, invalid_p == 0 */
> @@ -910,8 +914,14 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
> "gdbarch_dump: addr_bits_remove = <%s>\n",
> host_address_to_string (gdbarch->addr_bits_remove));
> gdb_printf (file,
> - "gdbarch_dump: remove_non_address_bits = <%s>\n",
> - host_address_to_string (gdbarch->remove_non_address_bits));
> + "gdbarch_dump: remove_non_address_bits_watchpoint = <%s>\n",
> + host_address_to_string (gdbarch->remove_non_address_bits_watchpoint));
> + gdb_printf (file,
> + "gdbarch_dump: remove_non_address_bits_breakpoint = <%s>\n",
> + host_address_to_string (gdbarch->remove_non_address_bits_breakpoint));
> + gdb_printf (file,
> + "gdbarch_dump: remove_non_address_bits_memory = <%s>\n",
> + host_address_to_string (gdbarch->remove_non_address_bits_memory));
> gdb_printf (file,
> "gdbarch_dump: memtag_to_string = <%s>\n",
> host_address_to_string (gdbarch->memtag_to_string));
> @@ -3198,20 +3208,54 @@ set_gdbarch_addr_bits_remove (struct gdbarch *gdbarch,
> }
>
> CORE_ADDR
> -gdbarch_remove_non_address_bits (struct gdbarch *gdbarch, CORE_ADDR pointer)
> +gdbarch_remove_non_address_bits_watchpoint (struct gdbarch *gdbarch, CORE_ADDR pointer)
> +{
> + gdb_assert (gdbarch != NULL);
> + gdb_assert (gdbarch->remove_non_address_bits_watchpoint != NULL);
> + if (gdbarch_debug >= 2)
> + gdb_printf (gdb_stdlog, "gdbarch_remove_non_address_bits_watchpoint called\n");
> + return gdbarch->remove_non_address_bits_watchpoint (gdbarch, pointer);
> +}
> +
> +void
> +set_gdbarch_remove_non_address_bits_watchpoint (struct gdbarch *gdbarch,
> + gdbarch_remove_non_address_bits_watchpoint_ftype remove_non_address_bits_watchpoint)
> +{
> + gdbarch->remove_non_address_bits_watchpoint = remove_non_address_bits_watchpoint;
> +}
> +
> +CORE_ADDR
> +gdbarch_remove_non_address_bits_breakpoint (struct gdbarch *gdbarch, CORE_ADDR pointer)
> +{
> + gdb_assert (gdbarch != NULL);
> + gdb_assert (gdbarch->remove_non_address_bits_breakpoint != NULL);
> + if (gdbarch_debug >= 2)
> + gdb_printf (gdb_stdlog, "gdbarch_remove_non_address_bits_breakpoint called\n");
> + return gdbarch->remove_non_address_bits_breakpoint (gdbarch, pointer);
> +}
> +
> +void
> +set_gdbarch_remove_non_address_bits_breakpoint (struct gdbarch *gdbarch,
> + gdbarch_remove_non_address_bits_breakpoint_ftype remove_non_address_bits_breakpoint)
> +{
> + gdbarch->remove_non_address_bits_breakpoint = remove_non_address_bits_breakpoint;
> +}
> +
> +CORE_ADDR
> +gdbarch_remove_non_address_bits_memory (struct gdbarch *gdbarch, CORE_ADDR pointer)
> {
> gdb_assert (gdbarch != NULL);
> - gdb_assert (gdbarch->remove_non_address_bits != NULL);
> + gdb_assert (gdbarch->remove_non_address_bits_memory != NULL);
> if (gdbarch_debug >= 2)
> - gdb_printf (gdb_stdlog, "gdbarch_remove_non_address_bits called\n");
> - return gdbarch->remove_non_address_bits (gdbarch, pointer);
> + gdb_printf (gdb_stdlog, "gdbarch_remove_non_address_bits_memory called\n");
> + return gdbarch->remove_non_address_bits_memory (gdbarch, pointer);
> }
>
> void
> -set_gdbarch_remove_non_address_bits (struct gdbarch *gdbarch,
> - gdbarch_remove_non_address_bits_ftype remove_non_address_bits)
> +set_gdbarch_remove_non_address_bits_memory (struct gdbarch *gdbarch,
> + gdbarch_remove_non_address_bits_memory_ftype remove_non_address_bits_memory)
> {
> - gdbarch->remove_non_address_bits = remove_non_address_bits;
> + gdbarch->remove_non_address_bits_memory = remove_non_address_bits_memory;
> }
>
> std::string
> diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py
> index 4006380076d..cc7c6d8677b 100644
> --- a/gdb/gdbarch_components.py
> +++ b/gdb/gdbarch_components.py
> @@ -1232,18 +1232,55 @@ possible it should be in TARGET_READ_PC instead).
> Method(
> comment="""
> On some architectures, not all bits of a pointer are significant.
> -On AArch64, for example, the top bits of a pointer may carry a "tag", which
> -can be ignored by the kernel and the hardware. The "tag" can be regarded as
> -additional data associated with the pointer, but it is not part of the address.
> +On AArch64 and amd64, for example, the top bits of a pointer may carry a
> +"tag", which can be ignored by the kernel and the hardware. The "tag" can be
> +regarded as additional data associated with the pointer, but it is not part
> +of the address.
>
> Given a pointer for the architecture, this hook removes all the
> -non-significant bits and sign-extends things as needed. It gets used to remove
> -non-address bits from data pointers (for example, removing the AArch64 MTE tag
> -bits from a pointer) and from code pointers (removing the AArch64 PAC signature
> -from a pointer containing the return address).
> +non-significant bits and sign-extends things as needed. It gets used to
> +remove non-address bits from pointers used for watchpoints.
> """,
> type="CORE_ADDR",
> - name="remove_non_address_bits",
> + name="remove_non_address_bits_watchpoint",
> + params=[("CORE_ADDR", "pointer")],
> + predefault="default_remove_non_address_bits",
> + invalid=False,
> +)
> +
> +Method(
> + comment="""
> +On some architectures, not all bits of a pointer are significant.
> +On AArch64 and amd64, for example, the top bits of a pointer may carry a
> +"tag", which can be ignored by the kernel and the hardware. The "tag" can be
> +regarded as additional data associated with the pointer, but it is not part
> +of the address.
> +
> +Given a pointer for the architecture, this hook removes all the
> +non-significant bits and sign-extends things as needed. It gets used to
> +remove non-address bits from pointers used for breakpoints.
> +""",
> + type="CORE_ADDR",
> + name="remove_non_address_bits_breakpoint",
> + params=[("CORE_ADDR", "pointer")],
> + predefault="default_remove_non_address_bits",
> + invalid=False,
> +)
> +
> +Method(
> + comment="""
> +On some architectures, not all bits of a pointer are significant.
> +On AArch64 and amd64, for example, the top bits of a pointer may carry a
> +"tag", which can be ignored by the kernel and the hardware. The "tag" can be
> +regarded as additional data associated with the pointer, but it is not part
> +of the address.
> +
> +Given a pointer for the architecture, this hook removes all the
> +non-significant bits and sign-extends things as needed. It gets used to
> +remove non-address bits from any pointer used to access memory.
> +""",
> + type="CORE_ADDR",
> + name="remove_non_address_bits_memory",
> params=[("CORE_ADDR", "pointer")],
> predefault="default_remove_non_address_bits",
> invalid=False,
> diff --git a/gdb/target.c b/gdb/target.c
> index 1b5aa11ed6f..b622de81e11 100644
> --- a/gdb/target.c
> +++ b/gdb/target.c
> @@ -1608,7 +1608,8 @@ memory_xfer_partial (struct target_ops *ops, enum target_object object,
> if (len == 0)
> return TARGET_XFER_EOF;
>
> - memaddr = gdbarch_remove_non_address_bits (current_inferior ()->arch (),
> + memaddr
> + = gdbarch_remove_non_address_bits_memory (current_inferior ()->arch (),
> memaddr);
>
> /* Fill in READBUF with breakpoint shadows, or WRITEBUF with
FTR, and maybe just stating it again. The aarch64 bits look OK to me.
> -----Original Message-----
> From: Schimpe, Christina <christina.schimpe@intel.com>
> Sent: Tuesday, July 9, 2024 2:17 PM
> To: gdb-patches@sourceware.org
> Cc: Willgerodt, Felix <felix.willgerodt@intel.com>; luis.machado@arm.com;
> eliz@gnu.org
> Subject: [PATCH v5 1/2] gdb: Make tagged pointer support configurable.
>
> From: Christina Schimpe <christina.schimpe@intel.com>
>
> The gdbarch function gdbarch_remove_non_address_bits adjusts addresses
> to enable debugging of programs with tagged pointers on Linux, for instance
> for ARM's feature top byte ignore (TBI).
> Once the function is implemented for an architecture, it adjusts addresses for
> memory access, breakpoints and watchpoints.
>
> Linear address masking (LAM) is Intel's (R) implementation of tagged pointer
> support. It requires certain adaptions to GDB's tagged pointer support due
> to the following:
> - LAM supports address tagging for data accesses only. Thus, specifying
> breakpoints on tagged addresses is not a valid use case.
> - In contrast to the implementation for ARM's TBI, the Linux kernel supports
> tagged pointers for memory access.
>
> This patch makes GDB's tagged pointer support configurable such that it is
> possible to enable the address adjustment for a specific feature only (e.g
> memory access, breakpoints or watchpoints). This way, one can make sure
> that addresses are only adjusted when necessary. In case of LAM, this avoids
> unnecessary parsing of the /proc/<pid>/status file to get the untag mask.
>
> Reviewed-By: Felix Willgerodt <felix.willgerodt@intel.com>
> ---
> gdb/aarch64-linux-nat.c | 2 +-
> gdb/aarch64-linux-tdep.c | 13 ++++----
> gdb/aarch64-tdep.c | 17 ++++++----
> gdb/aarch64-tdep.h | 6 ++++
> gdb/breakpoint.c | 5 +--
> gdb/gdbarch-gen.h | 49 ++++++++++++++++++++++-------
> gdb/gdbarch.c | 66 ++++++++++++++++++++++++++++++++-------
> gdb/gdbarch_components.py | 53 ++++++++++++++++++++++++++-----
> gdb/target.c | 3 +-
> 9 files changed, 168 insertions(+), 46 deletions(-)
>
> diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c index
> 2e6541f53c3..dac42b4f48b 100644
> --- a/gdb/aarch64-linux-nat.c
> +++ b/gdb/aarch64-linux-nat.c
> @@ -945,7 +945,7 @@ aarch64_linux_nat_target::stopped_data_address
> (CORE_ADDR *addr_p)
> kernel can potentially be tagged addresses. */
> struct gdbarch *gdbarch = thread_architecture (inferior_ptid);
> const CORE_ADDR addr_trap
> - = gdbarch_remove_non_address_bits (gdbarch, (CORE_ADDR)
> siginfo.si_addr);
> + = aarch64_remove_non_address_bits (gdbarch, (CORE_ADDR)
> + siginfo.si_addr);
>
> /* Check if the address matches any watched address. */
> state = aarch64_get_debug_reg_state (inferior_ptid.pid ()); diff --git
> a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c index
> a1296a8f0c7..bf5ce72aa5f 100644
> --- a/gdb/aarch64-linux-tdep.c
> +++ b/gdb/aarch64-linux-tdep.c
> @@ -2456,7 +2456,7 @@ static bool
> aarch64_linux_tagged_address_p (struct gdbarch *gdbarch, CORE_ADDR
> address) {
> /* Remove the top byte for the memory range check. */
> - address = gdbarch_remove_non_address_bits (gdbarch, address);
> + address = aarch64_remove_non_address_bits (gdbarch, address);
>
> /* Check if the page that contains ADDRESS is mapped with PROT_MTE. */
> if (!linux_address_in_memtag_page (address)) @@ -2478,7 +2478,7 @@
> aarch64_linux_memtag_matches_p (struct gdbarch *gdbarch,
>
> /* Fetch the allocation tag for ADDRESS. */
> std::optional<CORE_ADDR> atag
> - = aarch64_mte_get_atag (gdbarch_remove_non_address_bits (gdbarch,
> addr));
> + = aarch64_mte_get_atag (aarch64_remove_non_address_bits (gdbarch,
> + addr));
>
> if (!atag.has_value ())
> return true;
> @@ -2517,7 +2517,7 @@ aarch64_linux_set_memtags (struct gdbarch
> *gdbarch, struct value *address,
> else
> {
> /* Remove the top byte. */
> - addr = gdbarch_remove_non_address_bits (gdbarch, addr);
> + addr = aarch64_remove_non_address_bits (gdbarch, addr);
>
> /* With G being the number of tag granules and N the number of tags
> passed in, we can have the following cases:
> @@ -2566,7 +2566,7 @@ aarch64_linux_get_memtag (struct gdbarch
> *gdbarch, struct value *address,
> else
> {
> /* Remove the top byte. */
> - addr = gdbarch_remove_non_address_bits (gdbarch, addr);
> + addr = aarch64_remove_non_address_bits (gdbarch, addr);
> std::optional<CORE_ADDR> atag = aarch64_mte_get_atag (addr);
>
> if (!atag.has_value ())
> @@ -2640,8 +2640,9 @@ aarch64_linux_report_signal_info (struct gdbarch
> *gdbarch,
> uiout->text ("\n");
>
> std::optional<CORE_ADDR> atag
> - = aarch64_mte_get_atag (gdbarch_remove_non_address_bits
> (gdbarch,
> - fault_addr));
> + = aarch64_mte_get_atag (
> + aarch64_remove_non_address_bits (gdbarch, fault_addr));
> +
> gdb_byte ltag = aarch64_mte_get_ltag (fault_addr);
>
> if (!atag.has_value ())
> diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index
> e4bca6c6632..ba1dc3d5844 100644
> --- a/gdb/aarch64-tdep.c
> +++ b/gdb/aarch64-tdep.c
> @@ -4088,10 +4088,9 @@ aarch64_stack_frame_destroyed_p (struct
> gdbarch *gdbarch, CORE_ADDR pc)
> return streq (inst.opcode->name, "ret"); }
>
> -/* AArch64 implementation of the remove_non_address_bits gdbarch hook.
> Remove
> - non address bits from a pointer value. */
> +/* See aarch64-tdep.h. */
>
> -static CORE_ADDR
> +CORE_ADDR
> aarch64_remove_non_address_bits (struct gdbarch *gdbarch, CORE_ADDR
> pointer) {
> /* By default, we assume TBI and discard the top 8 bits plus the VA range
> @@ -4585,9 +4584,15 @@ aarch64_gdbarch_init (struct gdbarch_info info,
> struct gdbarch_list *arches)
> tdep->ra_sign_state_regnum = ra_sign_state_offset + num_regs;
>
> /* Architecture hook to remove bits of a pointer that are not part of the
> - address, like memory tags (MTE) and pointer authentication signatures.
> */
> - set_gdbarch_remove_non_address_bits (gdbarch,
> - aarch64_remove_non_address_bits);
> + address, like memory tags (MTE) and pointer authentication signatures.
> + Configure address adjustment for watch-, breakpoints and memory
> + transfer. */
> + set_gdbarch_remove_non_address_bits_watchpoint
> + (gdbarch, aarch64_remove_non_address_bits);
> + set_gdbarch_remove_non_address_bits_breakpoint
> + (gdbarch, aarch64_remove_non_address_bits);
> + set_gdbarch_remove_non_address_bits_memory
> + (gdbarch, aarch64_remove_non_address_bits);
>
> /* SME pseudo-registers. */
> if (tdep->has_sme ())
> diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h index
> 0e6024bfcbc..a9c8815f8be 100644
> --- a/gdb/aarch64-tdep.h
> +++ b/gdb/aarch64-tdep.h
> @@ -203,4 +203,10 @@ void aarch64_displaced_step_fixup (struct gdbarch
> *gdbarch,
>
> bool aarch64_displaced_step_hw_singlestep (struct gdbarch *gdbarch);
>
> +/* AArch64 implementation of the remove_non_address_bits gdbarch
> hooks.
> + Remove non address bits from a pointer value. */
> +
> +CORE_ADDR aarch64_remove_non_address_bits (struct gdbarch *gdbarch,
> + CORE_ADDR pointer);
> +
> #endif /* aarch64-tdep.h */
> diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index
> a973518ac5f..8c2d9d247ec 100644
> --- a/gdb/breakpoint.c
> +++ b/gdb/breakpoint.c
> @@ -2238,7 +2238,8 @@ update_watchpoint (struct watchpoint *b, bool
> reparse)
> loc->gdbarch = v->type ()->arch ();
> loc->pspace = wp_pspace;
> loc->address
> - = gdbarch_remove_non_address_bits (loc->gdbarch, addr);
> + = gdbarch_remove_non_address_bits_watchpoint (loc-
> >gdbarch,
> + addr);
> b->add_location (*loc);
>
> if (bitsize != 0)
> @@ -7477,7 +7478,7 @@ adjust_breakpoint_address (struct gdbarch
> *gdbarch,
> }
>
> adjusted_bpaddr
> - = gdbarch_remove_non_address_bits (gdbarch, adjusted_bpaddr);
> + = gdbarch_remove_non_address_bits_breakpoint (gdbarch,
> +adjusted_bpaddr);
>
> /* An adjusted breakpoint address can significantly alter
> a user's expectations. Print a warning if an adjustment diff --git
> a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h index b982fd7cd09..9fda85f860f
> 100644
> --- a/gdb/gdbarch-gen.h
> +++ b/gdb/gdbarch-gen.h
> @@ -684,19 +684,46 @@ extern CORE_ADDR gdbarch_addr_bits_remove
> (struct gdbarch *gdbarch, CORE_ADDR ad extern void
> set_gdbarch_addr_bits_remove (struct gdbarch *gdbarch,
> gdbarch_addr_bits_remove_ftype *addr_bits_remove);
>
> /* On some architectures, not all bits of a pointer are significant.
> - On AArch64, for example, the top bits of a pointer may carry a "tag", which
> - can be ignored by the kernel and the hardware. The "tag" can be regarded
> as
> - additional data associated with the pointer, but it is not part of the
> address.
> + On AArch64 and amd64, for example, the top bits of a pointer may carry a
> + "tag", which can be ignored by the kernel and the hardware. The "tag"
> can be
> + regarded as additional data associated with the pointer, but it is not part
> + of the address.
>
> Given a pointer for the architecture, this hook removes all the
> - non-significant bits and sign-extends things as needed. It gets used to
> remove
> - non-address bits from data pointers (for example, removing the AArch64
> MTE tag
> - bits from a pointer) and from code pointers (removing the AArch64 PAC
> signature
> - from a pointer containing the return address). */
> -
> -typedef CORE_ADDR (gdbarch_remove_non_address_bits_ftype) (struct
> gdbarch *gdbarch, CORE_ADDR pointer); -extern CORE_ADDR
> gdbarch_remove_non_address_bits (struct gdbarch *gdbarch, CORE_ADDR
> pointer); -extern void set_gdbarch_remove_non_address_bits (struct gdbarch
> *gdbarch, gdbarch_remove_non_address_bits_ftype
> *remove_non_address_bits);
> + non-significant bits and sign-extends things as needed. It gets used to
> + remove non-address bits from pointers used for watchpoints. */
> +
> +typedef CORE_ADDR
> (gdbarch_remove_non_address_bits_watchpoint_ftype)
> +(struct gdbarch *gdbarch, CORE_ADDR pointer); extern CORE_ADDR
> +gdbarch_remove_non_address_bits_watchpoint (struct gdbarch *gdbarch,
> +CORE_ADDR pointer); extern void
> +set_gdbarch_remove_non_address_bits_watchpoint (struct gdbarch
> +*gdbarch, gdbarch_remove_non_address_bits_watchpoint_ftype
> +*remove_non_address_bits_watchpoint);
> +
> +/* On some architectures, not all bits of a pointer are significant.
> + On AArch64 and amd64, for example, the top bits of a pointer may carry a
> + "tag", which can be ignored by the kernel and the hardware. The "tag"
> can be
> + regarded as additional data associated with the pointer, but it is not part
> + of the address.
> +
> + Given a pointer for the architecture, this hook removes all the
> + non-significant bits and sign-extends things as needed. It gets used to
> + remove non-address bits from pointers used for breakpoints. */
> +
> +typedef CORE_ADDR
> (gdbarch_remove_non_address_bits_breakpoint_ftype)
> +(struct gdbarch *gdbarch, CORE_ADDR pointer); extern CORE_ADDR
> +gdbarch_remove_non_address_bits_breakpoint (struct gdbarch *gdbarch,
> +CORE_ADDR pointer); extern void
> +set_gdbarch_remove_non_address_bits_breakpoint (struct gdbarch
> +*gdbarch, gdbarch_remove_non_address_bits_breakpoint_ftype
> +*remove_non_address_bits_breakpoint);
> +
> +/* On some architectures, not all bits of a pointer are significant.
> + On AArch64 and amd64, for example, the top bits of a pointer may carry a
> + "tag", which can be ignored by the kernel and the hardware. The "tag"
> can be
> + regarded as additional data associated with the pointer, but it is not part
> + of the address.
> +
> + Given a pointer for the architecture, this hook removes all the
> + non-significant bits and sign-extends things as needed. It gets used to
> + remove non-address bits from any pointer used to access memory. */
> +
> +typedef CORE_ADDR (gdbarch_remove_non_address_bits_memory_ftype)
> +(struct gdbarch *gdbarch, CORE_ADDR pointer); extern CORE_ADDR
> +gdbarch_remove_non_address_bits_memory (struct gdbarch *gdbarch,
> +CORE_ADDR pointer); extern void
> +set_gdbarch_remove_non_address_bits_memory (struct gdbarch *gdbarch,
> +gdbarch_remove_non_address_bits_memory_ftype
> +*remove_non_address_bits_memory);
>
> /* Return a string representation of the memory tag TAG. */
>
> diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 58e9ebbdc59..99a54a38d61
> 100644
> --- a/gdb/gdbarch.c
> +++ b/gdb/gdbarch.c
> @@ -143,7 +143,9 @@ struct gdbarch
> int frame_red_zone_size = 0;
> gdbarch_convert_from_func_ptr_addr_ftype *convert_from_func_ptr_addr
> = convert_from_func_ptr_addr_identity;
> gdbarch_addr_bits_remove_ftype *addr_bits_remove = core_addr_identity;
> - gdbarch_remove_non_address_bits_ftype *remove_non_address_bits =
> default_remove_non_address_bits;
> + gdbarch_remove_non_address_bits_watchpoint_ftype
> + *remove_non_address_bits_watchpoint =
> default_remove_non_address_bits;
> + gdbarch_remove_non_address_bits_breakpoint_ftype
> + *remove_non_address_bits_breakpoint =
> default_remove_non_address_bits;
> + gdbarch_remove_non_address_bits_memory_ftype
> + *remove_non_address_bits_memory = default_remove_non_address_bits;
> gdbarch_memtag_to_string_ftype *memtag_to_string =
> default_memtag_to_string;
> gdbarch_tagged_address_p_ftype *tagged_address_p =
> default_tagged_address_p;
> gdbarch_memtag_matches_p_ftype *memtag_matches_p =
> default_memtag_matches_p; @@ -407,7 +409,9 @@ verify_gdbarch (struct
> gdbarch *gdbarch)
> /* Skip verify of frame_red_zone_size, invalid_p == 0 */
> /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */
> /* Skip verify of addr_bits_remove, invalid_p == 0 */
> - /* Skip verify of remove_non_address_bits, invalid_p == 0 */
> + /* Skip verify of remove_non_address_bits_watchpoint, invalid_p == 0
> + */
> + /* Skip verify of remove_non_address_bits_breakpoint, invalid_p == 0
> + */
> + /* Skip verify of remove_non_address_bits_memory, invalid_p == 0 */
> /* Skip verify of memtag_to_string, invalid_p == 0 */
> /* Skip verify of tagged_address_p, invalid_p == 0 */
> /* Skip verify of memtag_matches_p, invalid_p == 0 */ @@ -910,8 +914,14
> @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
> "gdbarch_dump: addr_bits_remove = <%s>\n",
> host_address_to_string (gdbarch->addr_bits_remove));
> gdb_printf (file,
> - "gdbarch_dump: remove_non_address_bits = <%s>\n",
> - host_address_to_string (gdbarch->remove_non_address_bits));
> + "gdbarch_dump: remove_non_address_bits_watchpoint =
> <%s>\n",
> + host_address_to_string
> +(gdbarch->remove_non_address_bits_watchpoint));
> + gdb_printf (file,
> + "gdbarch_dump: remove_non_address_bits_breakpoint =
> <%s>\n",
> + host_address_to_string
> +(gdbarch->remove_non_address_bits_breakpoint));
> + gdb_printf (file,
> + "gdbarch_dump: remove_non_address_bits_memory = <%s>\n",
> + host_address_to_string
> +(gdbarch->remove_non_address_bits_memory));
> gdb_printf (file,
> "gdbarch_dump: memtag_to_string = <%s>\n",
> host_address_to_string (gdbarch->memtag_to_string)); @@ -
> 3198,20 +3208,54 @@ set_gdbarch_addr_bits_remove (struct gdbarch
> *gdbarch, }
>
> CORE_ADDR
> -gdbarch_remove_non_address_bits (struct gdbarch *gdbarch, CORE_ADDR
> pointer)
> +gdbarch_remove_non_address_bits_watchpoint (struct gdbarch *gdbarch,
> +CORE_ADDR pointer) {
> + gdb_assert (gdbarch != NULL);
> + gdb_assert (gdbarch->remove_non_address_bits_watchpoint != NULL);
> + if (gdbarch_debug >= 2)
> + gdb_printf (gdb_stdlog, "gdbarch_remove_non_address_bits_watchpoint
> +called\n");
> + return gdbarch->remove_non_address_bits_watchpoint (gdbarch,
> +pointer); }
> +
> +void
> +set_gdbarch_remove_non_address_bits_watchpoint (struct gdbarch
> *gdbarch,
> +
> gdbarch_remove_non_address_bits_watchpoint_ftype
> +remove_non_address_bits_watchpoint)
> +{
> + gdbarch->remove_non_address_bits_watchpoint =
> +remove_non_address_bits_watchpoint;
> +}
> +
> +CORE_ADDR
> +gdbarch_remove_non_address_bits_breakpoint (struct gdbarch *gdbarch,
> +CORE_ADDR pointer) {
> + gdb_assert (gdbarch != NULL);
> + gdb_assert (gdbarch->remove_non_address_bits_breakpoint != NULL);
> + if (gdbarch_debug >= 2)
> + gdb_printf (gdb_stdlog, "gdbarch_remove_non_address_bits_breakpoint
> +called\n");
> + return gdbarch->remove_non_address_bits_breakpoint (gdbarch,
> +pointer); }
> +
> +void
> +set_gdbarch_remove_non_address_bits_breakpoint (struct gdbarch
> *gdbarch,
> +
> gdbarch_remove_non_address_bits_breakpoint_ftype
> +remove_non_address_bits_breakpoint)
> +{
> + gdbarch->remove_non_address_bits_breakpoint =
> +remove_non_address_bits_breakpoint;
> +}
> +
> +CORE_ADDR
> +gdbarch_remove_non_address_bits_memory (struct gdbarch *gdbarch,
> +CORE_ADDR pointer)
> {
> gdb_assert (gdbarch != NULL);
> - gdb_assert (gdbarch->remove_non_address_bits != NULL);
> + gdb_assert (gdbarch->remove_non_address_bits_memory != NULL);
> if (gdbarch_debug >= 2)
> - gdb_printf (gdb_stdlog, "gdbarch_remove_non_address_bits called\n");
> - return gdbarch->remove_non_address_bits (gdbarch, pointer);
> + gdb_printf (gdb_stdlog, "gdbarch_remove_non_address_bits_memory
> + called\n"); return gdbarch->remove_non_address_bits_memory (gdbarch,
> + pointer);
> }
>
> void
> -set_gdbarch_remove_non_address_bits (struct gdbarch *gdbarch,
> - gdbarch_remove_non_address_bits_ftype
> remove_non_address_bits)
> +set_gdbarch_remove_non_address_bits_memory (struct gdbarch *gdbarch,
> +
> gdbarch_remove_non_address_bits_memory_ftype
> +remove_non_address_bits_memory)
> {
> - gdbarch->remove_non_address_bits = remove_non_address_bits;
> + gdbarch->remove_non_address_bits_memory =
> + remove_non_address_bits_memory;
> }
>
> std::string
> diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py index
> 4006380076d..cc7c6d8677b 100644
> --- a/gdb/gdbarch_components.py
> +++ b/gdb/gdbarch_components.py
> @@ -1232,18 +1232,55 @@ possible it should be in TARGET_READ_PC
> instead).
> Method(
> comment="""
> On some architectures, not all bits of a pointer are significant.
> -On AArch64, for example, the top bits of a pointer may carry a "tag", which -
> can be ignored by the kernel and the hardware. The "tag" can be regarded
> as -additional data associated with the pointer, but it is not part of the
> address.
> +On AArch64 and amd64, for example, the top bits of a pointer may carry
> +a "tag", which can be ignored by the kernel and the hardware. The
> +"tag" can be regarded as additional data associated with the pointer,
> +but it is not part of the address.
>
> Given a pointer for the architecture, this hook removes all the -non-
> significant bits and sign-extends things as needed. It gets used to remove -
> non-address bits from data pointers (for example, removing the AArch64 MTE
> tag -bits from a pointer) and from code pointers (removing the AArch64 PAC
> signature -from a pointer containing the return address).
> +non-significant bits and sign-extends things as needed. It gets used
> +to remove non-address bits from pointers used for watchpoints.
> """,
> type="CORE_ADDR",
> - name="remove_non_address_bits",
> + name="remove_non_address_bits_watchpoint",
> + params=[("CORE_ADDR", "pointer")],
> + predefault="default_remove_non_address_bits",
> + invalid=False,
> +)
> +
> +Method(
> + comment="""
> +On some architectures, not all bits of a pointer are significant.
> +On AArch64 and amd64, for example, the top bits of a pointer may carry
> +a "tag", which can be ignored by the kernel and the hardware. The
> +"tag" can be regarded as additional data associated with the pointer,
> +but it is not part of the address.
> +
> +Given a pointer for the architecture, this hook removes all the
> +non-significant bits and sign-extends things as needed. It gets used
> +to remove non-address bits from pointers used for breakpoints.
> +""",
> + type="CORE_ADDR",
> + name="remove_non_address_bits_breakpoint",
> + params=[("CORE_ADDR", "pointer")],
> + predefault="default_remove_non_address_bits",
> + invalid=False,
> +)
> +
> +Method(
> + comment="""
> +On some architectures, not all bits of a pointer are significant.
> +On AArch64 and amd64, for example, the top bits of a pointer may carry
> +a "tag", which can be ignored by the kernel and the hardware. The
> +"tag" can be regarded as additional data associated with the pointer,
> +but it is not part of the address.
> +
> +Given a pointer for the architecture, this hook removes all the
> +non-significant bits and sign-extends things as needed. It gets used
> +to remove non-address bits from any pointer used to access memory.
> +""",
> + type="CORE_ADDR",
> + name="remove_non_address_bits_memory",
> params=[("CORE_ADDR", "pointer")],
> predefault="default_remove_non_address_bits",
> invalid=False,
> diff --git a/gdb/target.c b/gdb/target.c index 1b5aa11ed6f..b622de81e11
> 100644
> --- a/gdb/target.c
> +++ b/gdb/target.c
> @@ -1608,7 +1608,8 @@ memory_xfer_partial (struct target_ops *ops,
> enum target_object object,
> if (len == 0)
> return TARGET_XFER_EOF;
>
> - memaddr = gdbarch_remove_non_address_bits (current_inferior ()->arch
> (),
> + memaddr
> + = gdbarch_remove_non_address_bits_memory (current_inferior ()->arch
> + (),
> memaddr);
>
> /* Fill in READBUF with breakpoint shadows, or WRITEBUF with
> --
> 2.34.1
>
> Intel Deutschland GmbH
> Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
> Tel: +49 89 99 8853-0, www.intel.de
> Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva
> Chairperson of the Supervisory Board: Nicole Lau Registered Office: Munich
> Commercial Register: Amtsgericht Muenchen HRB 186928
Kindly pinging for feedback.
Patch 2 of this series is already approved by Felix.
BR,
Christina
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
> > -----Original Message-----
> > From: Schimpe, Christina <christina.schimpe@intel.com>
> > Sent: Tuesday, July 9, 2024 2:17 PM
> > To: gdb-patches@sourceware.org
> > Cc: Willgerodt, Felix <felix.willgerodt@intel.com>;
> > luis.machado@arm.com; eliz@gnu.org
> > Subject: [PATCH v5 1/2] gdb: Make tagged pointer support configurable.
> >
> > From: Christina Schimpe <christina.schimpe@intel.com>
> >
> > The gdbarch function gdbarch_remove_non_address_bits adjusts
> addresses
> > to enable debugging of programs with tagged pointers on Linux, for
> > instance for ARM's feature top byte ignore (TBI).
> > Once the function is implemented for an architecture, it adjusts
> > addresses for memory access, breakpoints and watchpoints.
> >
> > Linear address masking (LAM) is Intel's (R) implementation of tagged
> > pointer support. It requires certain adaptions to GDB's tagged
> > pointer support due to the following:
> > - LAM supports address tagging for data accesses only. Thus, specifying
> > breakpoints on tagged addresses is not a valid use case.
> > - In contrast to the implementation for ARM's TBI, the Linux kernel supports
> > tagged pointers for memory access.
> >
> > This patch makes GDB's tagged pointer support configurable such that
> > it is possible to enable the address adjustment for a specific feature
> > only (e.g memory access, breakpoints or watchpoints). This way, one
> > can make sure that addresses are only adjusted when necessary. In
> > case of LAM, this avoids unnecessary parsing of the /proc/<pid>/status file
> to get the untag mask.
> >
> > Reviewed-By: Felix Willgerodt <felix.willgerodt@intel.com>
> > ---
> > gdb/aarch64-linux-nat.c | 2 +-
> > gdb/aarch64-linux-tdep.c | 13 ++++----
> > gdb/aarch64-tdep.c | 17 ++++++----
> > gdb/aarch64-tdep.h | 6 ++++
> > gdb/breakpoint.c | 5 +--
> > gdb/gdbarch-gen.h | 49 ++++++++++++++++++++++-------
> > gdb/gdbarch.c | 66 ++++++++++++++++++++++++++++++++-------
> > gdb/gdbarch_components.py | 53 ++++++++++++++++++++++++++-----
> > gdb/target.c | 3 +-
> > 9 files changed, 168 insertions(+), 46 deletions(-)
> >
> > diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c index
> > 2e6541f53c3..dac42b4f48b 100644
> > --- a/gdb/aarch64-linux-nat.c
> > +++ b/gdb/aarch64-linux-nat.c
> > @@ -945,7 +945,7 @@ aarch64_linux_nat_target::stopped_data_address
> > (CORE_ADDR *addr_p)
> > kernel can potentially be tagged addresses. */
> > struct gdbarch *gdbarch = thread_architecture (inferior_ptid);
> > const CORE_ADDR addr_trap
> > - = gdbarch_remove_non_address_bits (gdbarch, (CORE_ADDR)
> > siginfo.si_addr);
> > + = aarch64_remove_non_address_bits (gdbarch, (CORE_ADDR)
> > + siginfo.si_addr);
> >
> > /* Check if the address matches any watched address. */
> > state = aarch64_get_debug_reg_state (inferior_ptid.pid ()); diff
> > --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c index
> > a1296a8f0c7..bf5ce72aa5f 100644
> > --- a/gdb/aarch64-linux-tdep.c
> > +++ b/gdb/aarch64-linux-tdep.c
> > @@ -2456,7 +2456,7 @@ static bool
> > aarch64_linux_tagged_address_p (struct gdbarch *gdbarch, CORE_ADDR
> > address) {
> > /* Remove the top byte for the memory range check. */
> > - address = gdbarch_remove_non_address_bits (gdbarch, address);
> > + address = aarch64_remove_non_address_bits (gdbarch, address);
> >
> > /* Check if the page that contains ADDRESS is mapped with PROT_MTE.
> */
> > if (!linux_address_in_memtag_page (address)) @@ -2478,7 +2478,7 @@
> > aarch64_linux_memtag_matches_p (struct gdbarch *gdbarch,
> >
> > /* Fetch the allocation tag for ADDRESS. */
> > std::optional<CORE_ADDR> atag
> > - = aarch64_mte_get_atag (gdbarch_remove_non_address_bits (gdbarch,
> > addr));
> > + = aarch64_mte_get_atag (aarch64_remove_non_address_bits (gdbarch,
> > + addr));
> >
> > if (!atag.has_value ())
> > return true;
> > @@ -2517,7 +2517,7 @@ aarch64_linux_set_memtags (struct gdbarch
> > *gdbarch, struct value *address,
> > else
> > {
> > /* Remove the top byte. */
> > - addr = gdbarch_remove_non_address_bits (gdbarch, addr);
> > + addr = aarch64_remove_non_address_bits (gdbarch, addr);
> >
> > /* With G being the number of tag granules and N the number of tags
> > passed in, we can have the following cases:
> > @@ -2566,7 +2566,7 @@ aarch64_linux_get_memtag (struct gdbarch
> > *gdbarch, struct value *address,
> > else
> > {
> > /* Remove the top byte. */
> > - addr = gdbarch_remove_non_address_bits (gdbarch, addr);
> > + addr = aarch64_remove_non_address_bits (gdbarch, addr);
> > std::optional<CORE_ADDR> atag = aarch64_mte_get_atag (addr);
> >
> > if (!atag.has_value ())
> > @@ -2640,8 +2640,9 @@ aarch64_linux_report_signal_info (struct gdbarch
> > *gdbarch,
> > uiout->text ("\n");
> >
> > std::optional<CORE_ADDR> atag
> > - = aarch64_mte_get_atag (gdbarch_remove_non_address_bits
> > (gdbarch,
> > - fault_addr));
> > + = aarch64_mte_get_atag (
> > + aarch64_remove_non_address_bits (gdbarch, fault_addr));
> > +
> > gdb_byte ltag = aarch64_mte_get_ltag (fault_addr);
> >
> > if (!atag.has_value ())
> > diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index
> > e4bca6c6632..ba1dc3d5844 100644
> > --- a/gdb/aarch64-tdep.c
> > +++ b/gdb/aarch64-tdep.c
> > @@ -4088,10 +4088,9 @@ aarch64_stack_frame_destroyed_p (struct
> gdbarch
> > *gdbarch, CORE_ADDR pc)
> > return streq (inst.opcode->name, "ret"); }
> >
> > -/* AArch64 implementation of the remove_non_address_bits gdbarch
> hook.
> > Remove
> > - non address bits from a pointer value. */
> > +/* See aarch64-tdep.h. */
> >
> > -static CORE_ADDR
> > +CORE_ADDR
> > aarch64_remove_non_address_bits (struct gdbarch *gdbarch, CORE_ADDR
> > pointer) {
> > /* By default, we assume TBI and discard the top 8 bits plus the VA
> > range @@ -4585,9 +4584,15 @@ aarch64_gdbarch_init (struct
> gdbarch_info
> > info, struct gdbarch_list *arches)
> > tdep->ra_sign_state_regnum = ra_sign_state_offset + num_regs;
> >
> > /* Architecture hook to remove bits of a pointer that are not part of the
> > - address, like memory tags (MTE) and pointer authentication signatures.
> > */
> > - set_gdbarch_remove_non_address_bits (gdbarch,
> > - aarch64_remove_non_address_bits);
> > + address, like memory tags (MTE) and pointer authentication signatures.
> > + Configure address adjustment for watch-, breakpoints and memory
> > + transfer. */
> > + set_gdbarch_remove_non_address_bits_watchpoint
> > + (gdbarch, aarch64_remove_non_address_bits);
> > + set_gdbarch_remove_non_address_bits_breakpoint
> > + (gdbarch, aarch64_remove_non_address_bits);
> > + set_gdbarch_remove_non_address_bits_memory
> > + (gdbarch, aarch64_remove_non_address_bits);
> >
> > /* SME pseudo-registers. */
> > if (tdep->has_sme ())
> > diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h index
> > 0e6024bfcbc..a9c8815f8be 100644
> > --- a/gdb/aarch64-tdep.h
> > +++ b/gdb/aarch64-tdep.h
> > @@ -203,4 +203,10 @@ void aarch64_displaced_step_fixup (struct gdbarch
> > *gdbarch,
> >
> > bool aarch64_displaced_step_hw_singlestep (struct gdbarch *gdbarch);
> >
> > +/* AArch64 implementation of the remove_non_address_bits gdbarch
> > hooks.
> > + Remove non address bits from a pointer value. */
> > +
> > +CORE_ADDR aarch64_remove_non_address_bits (struct gdbarch *gdbarch,
> > + CORE_ADDR pointer);
> > +
> > #endif /* aarch64-tdep.h */
> > diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index
> > a973518ac5f..8c2d9d247ec 100644
> > --- a/gdb/breakpoint.c
> > +++ b/gdb/breakpoint.c
> > @@ -2238,7 +2238,8 @@ update_watchpoint (struct watchpoint *b, bool
> > reparse)
> > loc->gdbarch = v->type ()->arch ();
> > loc->pspace = wp_pspace;
> > loc->address
> > - = gdbarch_remove_non_address_bits (loc->gdbarch, addr);
> > + = gdbarch_remove_non_address_bits_watchpoint (loc-
> > >gdbarch,
> > + addr);
> > b->add_location (*loc);
> >
> > if (bitsize != 0)
> > @@ -7477,7 +7478,7 @@ adjust_breakpoint_address (struct gdbarch
> > *gdbarch,
> > }
> >
> > adjusted_bpaddr
> > - = gdbarch_remove_non_address_bits (gdbarch, adjusted_bpaddr);
> > + = gdbarch_remove_non_address_bits_breakpoint (gdbarch,
> > +adjusted_bpaddr);
> >
> > /* An adjusted breakpoint address can significantly alter
> > a user's expectations. Print a warning if an adjustment diff --git
> > a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h index b982fd7cd09..9fda85f860f
> > 100644
> > --- a/gdb/gdbarch-gen.h
> > +++ b/gdb/gdbarch-gen.h
> > @@ -684,19 +684,46 @@ extern CORE_ADDR gdbarch_addr_bits_remove
> > (struct gdbarch *gdbarch, CORE_ADDR ad extern void
> > set_gdbarch_addr_bits_remove (struct gdbarch *gdbarch,
> > gdbarch_addr_bits_remove_ftype *addr_bits_remove);
> >
> > /* On some architectures, not all bits of a pointer are significant.
> > - On AArch64, for example, the top bits of a pointer may carry a "tag",
> which
> > - can be ignored by the kernel and the hardware. The "tag" can be
> regarded
> > as
> > - additional data associated with the pointer, but it is not part of the
> > address.
> > + On AArch64 and amd64, for example, the top bits of a pointer may carry
> a
> > + "tag", which can be ignored by the kernel and the hardware. The "tag"
> > can be
> > + regarded as additional data associated with the pointer, but it is not part
> > + of the address.
> >
> > Given a pointer for the architecture, this hook removes all the
> > - non-significant bits and sign-extends things as needed. It gets used to
> > remove
> > - non-address bits from data pointers (for example, removing the AArch64
> > MTE tag
> > - bits from a pointer) and from code pointers (removing the AArch64 PAC
> > signature
> > - from a pointer containing the return address). */
> > -
> > -typedef CORE_ADDR (gdbarch_remove_non_address_bits_ftype) (struct
> > gdbarch *gdbarch, CORE_ADDR pointer); -extern CORE_ADDR
> > gdbarch_remove_non_address_bits (struct gdbarch *gdbarch, CORE_ADDR
> > pointer); -extern void set_gdbarch_remove_non_address_bits (struct
> > gdbarch *gdbarch, gdbarch_remove_non_address_bits_ftype
> > *remove_non_address_bits);
> > + non-significant bits and sign-extends things as needed. It gets used to
> > + remove non-address bits from pointers used for watchpoints. */
> > +
> > +typedef CORE_ADDR
> > (gdbarch_remove_non_address_bits_watchpoint_ftype)
> > +(struct gdbarch *gdbarch, CORE_ADDR pointer); extern CORE_ADDR
> > +gdbarch_remove_non_address_bits_watchpoint (struct gdbarch *gdbarch,
> > +CORE_ADDR pointer); extern void
> > +set_gdbarch_remove_non_address_bits_watchpoint (struct gdbarch
> > +*gdbarch, gdbarch_remove_non_address_bits_watchpoint_ftype
> > +*remove_non_address_bits_watchpoint);
> > +
> > +/* On some architectures, not all bits of a pointer are significant.
> > + On AArch64 and amd64, for example, the top bits of a pointer may carry
> a
> > + "tag", which can be ignored by the kernel and the hardware. The "tag"
> > can be
> > + regarded as additional data associated with the pointer, but it is not part
> > + of the address.
> > +
> > + Given a pointer for the architecture, this hook removes all the
> > + non-significant bits and sign-extends things as needed. It gets used to
> > + remove non-address bits from pointers used for breakpoints. */
> > +
> > +typedef CORE_ADDR
> > (gdbarch_remove_non_address_bits_breakpoint_ftype)
> > +(struct gdbarch *gdbarch, CORE_ADDR pointer); extern CORE_ADDR
> > +gdbarch_remove_non_address_bits_breakpoint (struct gdbarch *gdbarch,
> > +CORE_ADDR pointer); extern void
> > +set_gdbarch_remove_non_address_bits_breakpoint (struct gdbarch
> > +*gdbarch, gdbarch_remove_non_address_bits_breakpoint_ftype
> > +*remove_non_address_bits_breakpoint);
> > +
> > +/* On some architectures, not all bits of a pointer are significant.
> > + On AArch64 and amd64, for example, the top bits of a pointer may carry
> a
> > + "tag", which can be ignored by the kernel and the hardware. The "tag"
> > can be
> > + regarded as additional data associated with the pointer, but it is not part
> > + of the address.
> > +
> > + Given a pointer for the architecture, this hook removes all the
> > + non-significant bits and sign-extends things as needed. It gets used to
> > + remove non-address bits from any pointer used to access memory. */
> > +
> > +typedef CORE_ADDR (gdbarch_remove_non_address_bits_memory_ftype)
> > +(struct gdbarch *gdbarch, CORE_ADDR pointer); extern CORE_ADDR
> > +gdbarch_remove_non_address_bits_memory (struct gdbarch *gdbarch,
> > +CORE_ADDR pointer); extern void
> > +set_gdbarch_remove_non_address_bits_memory (struct gdbarch
> *gdbarch,
> > +gdbarch_remove_non_address_bits_memory_ftype
> > +*remove_non_address_bits_memory);
> >
> > /* Return a string representation of the memory tag TAG. */
> >
> > diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index
> > 58e9ebbdc59..99a54a38d61
> > 100644
> > --- a/gdb/gdbarch.c
> > +++ b/gdb/gdbarch.c
> > @@ -143,7 +143,9 @@ struct gdbarch
> > int frame_red_zone_size = 0;
> > gdbarch_convert_from_func_ptr_addr_ftype
> > *convert_from_func_ptr_addr = convert_from_func_ptr_addr_identity;
> > gdbarch_addr_bits_remove_ftype *addr_bits_remove =
> > core_addr_identity;
> > - gdbarch_remove_non_address_bits_ftype *remove_non_address_bits =
> > default_remove_non_address_bits;
> > + gdbarch_remove_non_address_bits_watchpoint_ftype
> > + *remove_non_address_bits_watchpoint =
> > default_remove_non_address_bits;
> > + gdbarch_remove_non_address_bits_breakpoint_ftype
> > + *remove_non_address_bits_breakpoint =
> > default_remove_non_address_bits;
> > + gdbarch_remove_non_address_bits_memory_ftype
> > + *remove_non_address_bits_memory =
> default_remove_non_address_bits;
> > gdbarch_memtag_to_string_ftype *memtag_to_string =
> > default_memtag_to_string;
> > gdbarch_tagged_address_p_ftype *tagged_address_p =
> > default_tagged_address_p;
> > gdbarch_memtag_matches_p_ftype *memtag_matches_p =
> > default_memtag_matches_p; @@ -407,7 +409,9 @@ verify_gdbarch (struct
> > gdbarch *gdbarch)
> > /* Skip verify of frame_red_zone_size, invalid_p == 0 */
> > /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */
> > /* Skip verify of addr_bits_remove, invalid_p == 0 */
> > - /* Skip verify of remove_non_address_bits, invalid_p == 0 */
> > + /* Skip verify of remove_non_address_bits_watchpoint, invalid_p ==
> > + 0 */
> > + /* Skip verify of remove_non_address_bits_breakpoint, invalid_p ==
> > + 0 */
> > + /* Skip verify of remove_non_address_bits_memory, invalid_p == 0 */
> > /* Skip verify of memtag_to_string, invalid_p == 0 */
> > /* Skip verify of tagged_address_p, invalid_p == 0 */
> > /* Skip verify of memtag_matches_p, invalid_p == 0 */ @@ -910,8
> > +914,14 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
> > "gdbarch_dump: addr_bits_remove = <%s>\n",
> > host_address_to_string (gdbarch->addr_bits_remove));
> > gdb_printf (file,
> > - "gdbarch_dump: remove_non_address_bits = <%s>\n",
> > - host_address_to_string (gdbarch->remove_non_address_bits));
> > + "gdbarch_dump: remove_non_address_bits_watchpoint =
> > <%s>\n",
> > + host_address_to_string
> > +(gdbarch->remove_non_address_bits_watchpoint));
> > + gdb_printf (file,
> > + "gdbarch_dump: remove_non_address_bits_breakpoint =
> > <%s>\n",
> > + host_address_to_string
> > +(gdbarch->remove_non_address_bits_breakpoint));
> > + gdb_printf (file,
> > + "gdbarch_dump: remove_non_address_bits_memory = <%s>\n",
> > + host_address_to_string
> > +(gdbarch->remove_non_address_bits_memory));
> > gdb_printf (file,
> > "gdbarch_dump: memtag_to_string = <%s>\n",
> > host_address_to_string (gdbarch->memtag_to_string)); @@ -
> > 3198,20 +3208,54 @@ set_gdbarch_addr_bits_remove (struct gdbarch
> > *gdbarch, }
> >
> > CORE_ADDR
> > -gdbarch_remove_non_address_bits (struct gdbarch *gdbarch, CORE_ADDR
> > pointer)
> > +gdbarch_remove_non_address_bits_watchpoint (struct gdbarch *gdbarch,
> > +CORE_ADDR pointer) {
> > + gdb_assert (gdbarch != NULL);
> > + gdb_assert (gdbarch->remove_non_address_bits_watchpoint != NULL);
> > + if (gdbarch_debug >= 2)
> > + gdb_printf (gdb_stdlog,
> > +"gdbarch_remove_non_address_bits_watchpoint
> > +called\n");
> > + return gdbarch->remove_non_address_bits_watchpoint (gdbarch,
> > +pointer); }
> > +
> > +void
> > +set_gdbarch_remove_non_address_bits_watchpoint (struct gdbarch
> > *gdbarch,
> > +
> > gdbarch_remove_non_address_bits_watchpoint_ftype
> > +remove_non_address_bits_watchpoint)
> > +{
> > + gdbarch->remove_non_address_bits_watchpoint =
> > +remove_non_address_bits_watchpoint;
> > +}
> > +
> > +CORE_ADDR
> > +gdbarch_remove_non_address_bits_breakpoint (struct gdbarch *gdbarch,
> > +CORE_ADDR pointer) {
> > + gdb_assert (gdbarch != NULL);
> > + gdb_assert (gdbarch->remove_non_address_bits_breakpoint != NULL);
> > + if (gdbarch_debug >= 2)
> > + gdb_printf (gdb_stdlog,
> > +"gdbarch_remove_non_address_bits_breakpoint
> > +called\n");
> > + return gdbarch->remove_non_address_bits_breakpoint (gdbarch,
> > +pointer); }
> > +
> > +void
> > +set_gdbarch_remove_non_address_bits_breakpoint (struct gdbarch
> > *gdbarch,
> > +
> > gdbarch_remove_non_address_bits_breakpoint_ftype
> > +remove_non_address_bits_breakpoint)
> > +{
> > + gdbarch->remove_non_address_bits_breakpoint =
> > +remove_non_address_bits_breakpoint;
> > +}
> > +
> > +CORE_ADDR
> > +gdbarch_remove_non_address_bits_memory (struct gdbarch *gdbarch,
> > +CORE_ADDR pointer)
> > {
> > gdb_assert (gdbarch != NULL);
> > - gdb_assert (gdbarch->remove_non_address_bits != NULL);
> > + gdb_assert (gdbarch->remove_non_address_bits_memory != NULL);
> > if (gdbarch_debug >= 2)
> > - gdb_printf (gdb_stdlog, "gdbarch_remove_non_address_bits called\n");
> > - return gdbarch->remove_non_address_bits (gdbarch, pointer);
> > + gdb_printf (gdb_stdlog, "gdbarch_remove_non_address_bits_memory
> > + called\n"); return gdbarch->remove_non_address_bits_memory
> > + (gdbarch, pointer);
> > }
> >
> > void
> > -set_gdbarch_remove_non_address_bits (struct gdbarch *gdbarch,
> > - gdbarch_remove_non_address_bits_ftype
> > remove_non_address_bits)
> > +set_gdbarch_remove_non_address_bits_memory (struct gdbarch
> *gdbarch,
> > +
> > gdbarch_remove_non_address_bits_memory_ftype
> > +remove_non_address_bits_memory)
> > {
> > - gdbarch->remove_non_address_bits = remove_non_address_bits;
> > + gdbarch->remove_non_address_bits_memory =
> > + remove_non_address_bits_memory;
> > }
> >
> > std::string
> > diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py
> > index 4006380076d..cc7c6d8677b 100644
> > --- a/gdb/gdbarch_components.py
> > +++ b/gdb/gdbarch_components.py
> > @@ -1232,18 +1232,55 @@ possible it should be in TARGET_READ_PC
> > instead).
> > Method(
> > comment="""
> > On some architectures, not all bits of a pointer are significant.
> > -On AArch64, for example, the top bits of a pointer may carry a "tag",
> > which - can be ignored by the kernel and the hardware. The "tag" can
> > be regarded as -additional data associated with the pointer, but it is
> > not part of the address.
> > +On AArch64 and amd64, for example, the top bits of a pointer may
> > +carry a "tag", which can be ignored by the kernel and the hardware.
> > +The "tag" can be regarded as additional data associated with the
> > +pointer, but it is not part of the address.
> >
> > Given a pointer for the architecture, this hook removes all the -non-
> > significant bits and sign-extends things as needed. It gets used to
> > remove - non-address bits from data pointers (for example, removing
> > the AArch64 MTE tag -bits from a pointer) and from code pointers
> > (removing the AArch64 PAC signature -from a pointer containing the return
> address).
> > +non-significant bits and sign-extends things as needed. It gets used
> > +to remove non-address bits from pointers used for watchpoints.
> > """,
> > type="CORE_ADDR",
> > - name="remove_non_address_bits",
> > + name="remove_non_address_bits_watchpoint",
> > + params=[("CORE_ADDR", "pointer")],
> > + predefault="default_remove_non_address_bits",
> > + invalid=False,
> > +)
> > +
> > +Method(
> > + comment="""
> > +On some architectures, not all bits of a pointer are significant.
> > +On AArch64 and amd64, for example, the top bits of a pointer may
> > +carry a "tag", which can be ignored by the kernel and the hardware.
> > +The "tag" can be regarded as additional data associated with the
> > +pointer, but it is not part of the address.
> > +
> > +Given a pointer for the architecture, this hook removes all the
> > +non-significant bits and sign-extends things as needed. It gets used
> > +to remove non-address bits from pointers used for breakpoints.
> > +""",
> > + type="CORE_ADDR",
> > + name="remove_non_address_bits_breakpoint",
> > + params=[("CORE_ADDR", "pointer")],
> > + predefault="default_remove_non_address_bits",
> > + invalid=False,
> > +)
> > +
> > +Method(
> > + comment="""
> > +On some architectures, not all bits of a pointer are significant.
> > +On AArch64 and amd64, for example, the top bits of a pointer may
> > +carry a "tag", which can be ignored by the kernel and the hardware.
> > +The "tag" can be regarded as additional data associated with the
> > +pointer, but it is not part of the address.
> > +
> > +Given a pointer for the architecture, this hook removes all the
> > +non-significant bits and sign-extends things as needed. It gets used
> > +to remove non-address bits from any pointer used to access memory.
> > +""",
> > + type="CORE_ADDR",
> > + name="remove_non_address_bits_memory",
> > params=[("CORE_ADDR", "pointer")],
> > predefault="default_remove_non_address_bits",
> > invalid=False,
> > diff --git a/gdb/target.c b/gdb/target.c index
> > 1b5aa11ed6f..b622de81e11
> > 100644
> > --- a/gdb/target.c
> > +++ b/gdb/target.c
> > @@ -1608,7 +1608,8 @@ memory_xfer_partial (struct target_ops *ops,
> > enum target_object object,
> > if (len == 0)
> > return TARGET_XFER_EOF;
> >
> > - memaddr = gdbarch_remove_non_address_bits (current_inferior
> > ()->arch (),
> > + memaddr
> > + = gdbarch_remove_non_address_bits_memory (current_inferior
> > + ()->arch (),
> > memaddr);
> >
> > /* Fill in READBUF with breakpoint shadows, or WRITEBUF with
> > --
> > 2.34.1
> >
> > Intel Deutschland GmbH
> > Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
> > Tel: +49 89 99 8853-0, www.intel.de
> > Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon
> > Silva Chairperson of the Supervisory Board: Nicole Lau Registered
> > Office: Munich Commercial Register: Amtsgericht Muenchen HRB 186928
>
> Kindly pinging for feedback.
> Patch 2 of this series is already approved by Felix.
>
> BR,
> Christina
Kindly pinging!
BR,
Christina
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
> -----Original Message-----
> From: Schimpe, Christina
> Sent: Monday, August 12, 2024 10:42 AM
> To: 'gdb-patches@sourceware.org' <gdb-patches@sourceware.org>
> Cc: Willgerodt, Felix <FeliX.Willgerodt@intel.com>; 'luis.machado@arm.com'
> <luis.machado@arm.com>; 'eliz@gnu.org' <eliz@gnu.org>
> Subject: RE: [PING*2][PATCH v5 1/2] gdb: Make tagged pointer support
> configurable.
>
> > > -----Original Message-----
> > > From: Schimpe, Christina <christina.schimpe@intel.com>
> > > Sent: Tuesday, July 9, 2024 2:17 PM
> > > To: gdb-patches@sourceware.org
> > > Cc: Willgerodt, Felix <felix.willgerodt@intel.com>;
> > > luis.machado@arm.com; eliz@gnu.org
> > > Subject: [PATCH v5 1/2] gdb: Make tagged pointer support configurable.
> > >
> > > From: Christina Schimpe <christina.schimpe@intel.com>
> > >
> > > The gdbarch function gdbarch_remove_non_address_bits adjusts
> > addresses
> > > to enable debugging of programs with tagged pointers on Linux, for
> > > instance for ARM's feature top byte ignore (TBI).
> > > Once the function is implemented for an architecture, it adjusts
> > > addresses for memory access, breakpoints and watchpoints.
> > >
> > > Linear address masking (LAM) is Intel's (R) implementation of tagged
> > > pointer support. It requires certain adaptions to GDB's tagged
> > > pointer support due to the following:
> > > - LAM supports address tagging for data accesses only. Thus, specifying
> > > breakpoints on tagged addresses is not a valid use case.
> > > - In contrast to the implementation for ARM's TBI, the Linux kernel
> supports
> > > tagged pointers for memory access.
> > >
> > > This patch makes GDB's tagged pointer support configurable such that
> > > it is possible to enable the address adjustment for a specific
> > > feature only (e.g memory access, breakpoints or watchpoints). This
> > > way, one can make sure that addresses are only adjusted when
> > > necessary. In case of LAM, this avoids unnecessary parsing of the
> > > /proc/<pid>/status file
> > to get the untag mask.
> > >
> > > Reviewed-By: Felix Willgerodt <felix.willgerodt@intel.com>
> > > ---
> > > gdb/aarch64-linux-nat.c | 2 +-
> > > gdb/aarch64-linux-tdep.c | 13 ++++----
> > > gdb/aarch64-tdep.c | 17 ++++++----
> > > gdb/aarch64-tdep.h | 6 ++++
> > > gdb/breakpoint.c | 5 +--
> > > gdb/gdbarch-gen.h | 49 ++++++++++++++++++++++-------
> > > gdb/gdbarch.c | 66 ++++++++++++++++++++++++++++++++-------
> > > gdb/gdbarch_components.py | 53 ++++++++++++++++++++++++++-----
> > > gdb/target.c | 3 +-
> > > 9 files changed, 168 insertions(+), 46 deletions(-)
> > >
> > > diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c index
> > > 2e6541f53c3..dac42b4f48b 100644
> > > --- a/gdb/aarch64-linux-nat.c
> > > +++ b/gdb/aarch64-linux-nat.c
> > > @@ -945,7 +945,7 @@ aarch64_linux_nat_target::stopped_data_address
> > > (CORE_ADDR *addr_p)
> > > kernel can potentially be tagged addresses. */
> > > struct gdbarch *gdbarch = thread_architecture (inferior_ptid);
> > > const CORE_ADDR addr_trap
> > > - = gdbarch_remove_non_address_bits (gdbarch, (CORE_ADDR)
> > > siginfo.si_addr);
> > > + = aarch64_remove_non_address_bits (gdbarch, (CORE_ADDR)
> > > + siginfo.si_addr);
> > >
> > > /* Check if the address matches any watched address. */
> > > state = aarch64_get_debug_reg_state (inferior_ptid.pid ()); diff
> > > --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c index
> > > a1296a8f0c7..bf5ce72aa5f 100644
> > > --- a/gdb/aarch64-linux-tdep.c
> > > +++ b/gdb/aarch64-linux-tdep.c
> > > @@ -2456,7 +2456,7 @@ static bool
> > > aarch64_linux_tagged_address_p (struct gdbarch *gdbarch, CORE_ADDR
> > > address) {
> > > /* Remove the top byte for the memory range check. */
> > > - address = gdbarch_remove_non_address_bits (gdbarch, address);
> > > + address = aarch64_remove_non_address_bits (gdbarch, address);
> > >
> > > /* Check if the page that contains ADDRESS is mapped with PROT_MTE.
> > */
> > > if (!linux_address_in_memtag_page (address)) @@ -2478,7 +2478,7
> > > @@ aarch64_linux_memtag_matches_p (struct gdbarch *gdbarch,
> > >
> > > /* Fetch the allocation tag for ADDRESS. */
> > > std::optional<CORE_ADDR> atag
> > > - = aarch64_mte_get_atag (gdbarch_remove_non_address_bits
> (gdbarch,
> > > addr));
> > > + = aarch64_mte_get_atag (aarch64_remove_non_address_bits
> > > + (gdbarch, addr));
> > >
> > > if (!atag.has_value ())
> > > return true;
> > > @@ -2517,7 +2517,7 @@ aarch64_linux_set_memtags (struct gdbarch
> > > *gdbarch, struct value *address,
> > > else
> > > {
> > > /* Remove the top byte. */
> > > - addr = gdbarch_remove_non_address_bits (gdbarch, addr);
> > > + addr = aarch64_remove_non_address_bits (gdbarch, addr);
> > >
> > > /* With G being the number of tag granules and N the number of
> tags
> > > passed in, we can have the following cases:
> > > @@ -2566,7 +2566,7 @@ aarch64_linux_get_memtag (struct gdbarch
> > > *gdbarch, struct value *address,
> > > else
> > > {
> > > /* Remove the top byte. */
> > > - addr = gdbarch_remove_non_address_bits (gdbarch, addr);
> > > + addr = aarch64_remove_non_address_bits (gdbarch, addr);
> > > std::optional<CORE_ADDR> atag = aarch64_mte_get_atag (addr);
> > >
> > > if (!atag.has_value ())
> > > @@ -2640,8 +2640,9 @@ aarch64_linux_report_signal_info (struct
> > > gdbarch *gdbarch,
> > > uiout->text ("\n");
> > >
> > > std::optional<CORE_ADDR> atag
> > > - = aarch64_mte_get_atag (gdbarch_remove_non_address_bits
> > > (gdbarch,
> > > - fault_addr));
> > > + = aarch64_mte_get_atag (
> > > + aarch64_remove_non_address_bits (gdbarch, fault_addr));
> > > +
> > > gdb_byte ltag = aarch64_mte_get_ltag (fault_addr);
> > >
> > > if (!atag.has_value ())
> > > diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index
> > > e4bca6c6632..ba1dc3d5844 100644
> > > --- a/gdb/aarch64-tdep.c
> > > +++ b/gdb/aarch64-tdep.c
> > > @@ -4088,10 +4088,9 @@ aarch64_stack_frame_destroyed_p (struct
> > gdbarch
> > > *gdbarch, CORE_ADDR pc)
> > > return streq (inst.opcode->name, "ret"); }
> > >
> > > -/* AArch64 implementation of the remove_non_address_bits gdbarch
> > hook.
> > > Remove
> > > - non address bits from a pointer value. */
> > > +/* See aarch64-tdep.h. */
> > >
> > > -static CORE_ADDR
> > > +CORE_ADDR
> > > aarch64_remove_non_address_bits (struct gdbarch *gdbarch,
> CORE_ADDR
> > > pointer) {
> > > /* By default, we assume TBI and discard the top 8 bits plus the
> > > VA range @@ -4585,9 +4584,15 @@ aarch64_gdbarch_init (struct
> > gdbarch_info
> > > info, struct gdbarch_list *arches)
> > > tdep->ra_sign_state_regnum = ra_sign_state_offset + num_regs;
> > >
> > > /* Architecture hook to remove bits of a pointer that are not part of the
> > > - address, like memory tags (MTE) and pointer authentication
> signatures.
> > > */
> > > - set_gdbarch_remove_non_address_bits (gdbarch,
> > > - aarch64_remove_non_address_bits);
> > > + address, like memory tags (MTE) and pointer authentication
> signatures.
> > > + Configure address adjustment for watch-, breakpoints and memory
> > > + transfer. */
> > > + set_gdbarch_remove_non_address_bits_watchpoint
> > > + (gdbarch, aarch64_remove_non_address_bits);
> > > + set_gdbarch_remove_non_address_bits_breakpoint
> > > + (gdbarch, aarch64_remove_non_address_bits);
> > > + set_gdbarch_remove_non_address_bits_memory
> > > + (gdbarch, aarch64_remove_non_address_bits);
> > >
> > > /* SME pseudo-registers. */
> > > if (tdep->has_sme ())
> > > diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h index
> > > 0e6024bfcbc..a9c8815f8be 100644
> > > --- a/gdb/aarch64-tdep.h
> > > +++ b/gdb/aarch64-tdep.h
> > > @@ -203,4 +203,10 @@ void aarch64_displaced_step_fixup (struct
> > > gdbarch *gdbarch,
> > >
> > > bool aarch64_displaced_step_hw_singlestep (struct gdbarch
> > > *gdbarch);
> > >
> > > +/* AArch64 implementation of the remove_non_address_bits gdbarch
> > > hooks.
> > > + Remove non address bits from a pointer value. */
> > > +
> > > +CORE_ADDR aarch64_remove_non_address_bits (struct gdbarch
> *gdbarch,
> > > + CORE_ADDR pointer);
> > > +
> > > #endif /* aarch64-tdep.h */
> > > diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index
> > > a973518ac5f..8c2d9d247ec 100644
> > > --- a/gdb/breakpoint.c
> > > +++ b/gdb/breakpoint.c
> > > @@ -2238,7 +2238,8 @@ update_watchpoint (struct watchpoint *b, bool
> > > reparse)
> > > loc->gdbarch = v->type ()->arch ();
> > > loc->pspace = wp_pspace;
> > > loc->address
> > > - = gdbarch_remove_non_address_bits (loc->gdbarch, addr);
> > > + = gdbarch_remove_non_address_bits_watchpoint (loc-
> > > >gdbarch,
> > > + addr);
> > > b->add_location (*loc);
> > >
> > > if (bitsize != 0)
> > > @@ -7477,7 +7478,7 @@ adjust_breakpoint_address (struct gdbarch
> > > *gdbarch,
> > > }
> > >
> > > adjusted_bpaddr
> > > - = gdbarch_remove_non_address_bits (gdbarch, adjusted_bpaddr);
> > > + = gdbarch_remove_non_address_bits_breakpoint (gdbarch,
> > > +adjusted_bpaddr);
> > >
> > > /* An adjusted breakpoint address can significantly alter
> > > a user's expectations. Print a warning if an adjustment diff
> > > --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h index
> > > b982fd7cd09..9fda85f860f
> > > 100644
> > > --- a/gdb/gdbarch-gen.h
> > > +++ b/gdb/gdbarch-gen.h
> > > @@ -684,19 +684,46 @@ extern CORE_ADDR gdbarch_addr_bits_remove
> > > (struct gdbarch *gdbarch, CORE_ADDR ad extern void
> > > set_gdbarch_addr_bits_remove (struct gdbarch *gdbarch,
> > > gdbarch_addr_bits_remove_ftype *addr_bits_remove);
> > >
> > > /* On some architectures, not all bits of a pointer are significant.
> > > - On AArch64, for example, the top bits of a pointer may carry a "tag",
> > which
> > > - can be ignored by the kernel and the hardware. The "tag" can be
> > regarded
> > > as
> > > - additional data associated with the pointer, but it is not part of the
> > > address.
> > > + On AArch64 and amd64, for example, the top bits of a pointer may
> > > + carry
> > a
> > > + "tag", which can be ignored by the kernel and the hardware. The "tag"
> > > can be
> > > + regarded as additional data associated with the pointer, but it is not
> part
> > > + of the address.
> > >
> > > Given a pointer for the architecture, this hook removes all the
> > > - non-significant bits and sign-extends things as needed. It gets used to
> > > remove
> > > - non-address bits from data pointers (for example, removing the
> AArch64
> > > MTE tag
> > > - bits from a pointer) and from code pointers (removing the AArch64 PAC
> > > signature
> > > - from a pointer containing the return address). */
> > > -
> > > -typedef CORE_ADDR (gdbarch_remove_non_address_bits_ftype) (struct
> > > gdbarch *gdbarch, CORE_ADDR pointer); -extern CORE_ADDR
> > > gdbarch_remove_non_address_bits (struct gdbarch *gdbarch,
> CORE_ADDR
> > > pointer); -extern void set_gdbarch_remove_non_address_bits (struct
> > > gdbarch *gdbarch, gdbarch_remove_non_address_bits_ftype
> > > *remove_non_address_bits);
> > > + non-significant bits and sign-extends things as needed. It gets used to
> > > + remove non-address bits from pointers used for watchpoints. */
> > > +
> > > +typedef CORE_ADDR
> > > (gdbarch_remove_non_address_bits_watchpoint_ftype)
> > > +(struct gdbarch *gdbarch, CORE_ADDR pointer); extern CORE_ADDR
> > > +gdbarch_remove_non_address_bits_watchpoint (struct gdbarch
> > > +*gdbarch, CORE_ADDR pointer); extern void
> > > +set_gdbarch_remove_non_address_bits_watchpoint (struct gdbarch
> > > +*gdbarch, gdbarch_remove_non_address_bits_watchpoint_ftype
> > > +*remove_non_address_bits_watchpoint);
> > > +
> > > +/* On some architectures, not all bits of a pointer are significant.
> > > + On AArch64 and amd64, for example, the top bits of a pointer may
> > > +carry
> > a
> > > + "tag", which can be ignored by the kernel and the hardware. The "tag"
> > > can be
> > > + regarded as additional data associated with the pointer, but it is not
> part
> > > + of the address.
> > > +
> > > + Given a pointer for the architecture, this hook removes all the
> > > + non-significant bits and sign-extends things as needed. It gets used to
> > > + remove non-address bits from pointers used for breakpoints. */
> > > +
> > > +typedef CORE_ADDR
> > > (gdbarch_remove_non_address_bits_breakpoint_ftype)
> > > +(struct gdbarch *gdbarch, CORE_ADDR pointer); extern CORE_ADDR
> > > +gdbarch_remove_non_address_bits_breakpoint (struct gdbarch
> > > +*gdbarch, CORE_ADDR pointer); extern void
> > > +set_gdbarch_remove_non_address_bits_breakpoint (struct gdbarch
> > > +*gdbarch, gdbarch_remove_non_address_bits_breakpoint_ftype
> > > +*remove_non_address_bits_breakpoint);
> > > +
> > > +/* On some architectures, not all bits of a pointer are significant.
> > > + On AArch64 and amd64, for example, the top bits of a pointer may
> > > +carry
> > a
> > > + "tag", which can be ignored by the kernel and the hardware. The "tag"
> > > can be
> > > + regarded as additional data associated with the pointer, but it is not
> part
> > > + of the address.
> > > +
> > > + Given a pointer for the architecture, this hook removes all the
> > > + non-significant bits and sign-extends things as needed. It gets used to
> > > + remove non-address bits from any pointer used to access memory.
> > > + */
> > > +
> > > +typedef CORE_ADDR
> (gdbarch_remove_non_address_bits_memory_ftype)
> > > +(struct gdbarch *gdbarch, CORE_ADDR pointer); extern CORE_ADDR
> > > +gdbarch_remove_non_address_bits_memory (struct gdbarch *gdbarch,
> > > +CORE_ADDR pointer); extern void
> > > +set_gdbarch_remove_non_address_bits_memory (struct gdbarch
> > *gdbarch,
> > > +gdbarch_remove_non_address_bits_memory_ftype
> > > +*remove_non_address_bits_memory);
> > >
> > > /* Return a string representation of the memory tag TAG. */
> > >
> > > diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index
> > > 58e9ebbdc59..99a54a38d61
> > > 100644
> > > --- a/gdb/gdbarch.c
> > > +++ b/gdb/gdbarch.c
> > > @@ -143,7 +143,9 @@ struct gdbarch
> > > int frame_red_zone_size = 0;
> > > gdbarch_convert_from_func_ptr_addr_ftype
> > > *convert_from_func_ptr_addr = convert_from_func_ptr_addr_identity;
> > > gdbarch_addr_bits_remove_ftype *addr_bits_remove =
> > > core_addr_identity;
> > > - gdbarch_remove_non_address_bits_ftype *remove_non_address_bits
> =
> > > default_remove_non_address_bits;
> > > + gdbarch_remove_non_address_bits_watchpoint_ftype
> > > + *remove_non_address_bits_watchpoint =
> > > default_remove_non_address_bits;
> > > + gdbarch_remove_non_address_bits_breakpoint_ftype
> > > + *remove_non_address_bits_breakpoint =
> > > default_remove_non_address_bits;
> > > + gdbarch_remove_non_address_bits_memory_ftype
> > > + *remove_non_address_bits_memory =
> > default_remove_non_address_bits;
> > > gdbarch_memtag_to_string_ftype *memtag_to_string =
> > > default_memtag_to_string;
> > > gdbarch_tagged_address_p_ftype *tagged_address_p =
> > > default_tagged_address_p;
> > > gdbarch_memtag_matches_p_ftype *memtag_matches_p =
> > > default_memtag_matches_p; @@ -407,7 +409,9 @@ verify_gdbarch
> (struct
> > > gdbarch *gdbarch)
> > > /* Skip verify of frame_red_zone_size, invalid_p == 0 */
> > > /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */
> > > /* Skip verify of addr_bits_remove, invalid_p == 0 */
> > > - /* Skip verify of remove_non_address_bits, invalid_p == 0 */
> > > + /* Skip verify of remove_non_address_bits_watchpoint, invalid_p
> > > + ==
> > > + 0 */
> > > + /* Skip verify of remove_non_address_bits_breakpoint, invalid_p
> > > + ==
> > > + 0 */
> > > + /* Skip verify of remove_non_address_bits_memory, invalid_p == 0
> > > + */
> > > /* Skip verify of memtag_to_string, invalid_p == 0 */
> > > /* Skip verify of tagged_address_p, invalid_p == 0 */
> > > /* Skip verify of memtag_matches_p, invalid_p == 0 */ @@ -910,8
> > > +914,14 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file
> > > +*file)
> > > "gdbarch_dump: addr_bits_remove = <%s>\n",
> > > host_address_to_string (gdbarch->addr_bits_remove));
> > > gdb_printf (file,
> > > - "gdbarch_dump: remove_non_address_bits = <%s>\n",
> > > - host_address_to_string (gdbarch->remove_non_address_bits));
> > > + "gdbarch_dump: remove_non_address_bits_watchpoint =
> > > <%s>\n",
> > > + host_address_to_string
> > > +(gdbarch->remove_non_address_bits_watchpoint));
> > > + gdb_printf (file,
> > > + "gdbarch_dump: remove_non_address_bits_breakpoint =
> > > <%s>\n",
> > > + host_address_to_string
> > > +(gdbarch->remove_non_address_bits_breakpoint));
> > > + gdb_printf (file,
> > > + "gdbarch_dump: remove_non_address_bits_memory = <%s>\n",
> > > + host_address_to_string
> > > +(gdbarch->remove_non_address_bits_memory));
> > > gdb_printf (file,
> > > "gdbarch_dump: memtag_to_string = <%s>\n",
> > > host_address_to_string (gdbarch->memtag_to_string)); @@ -
> > > 3198,20 +3208,54 @@ set_gdbarch_addr_bits_remove (struct gdbarch
> > > *gdbarch, }
> > >
> > > CORE_ADDR
> > > -gdbarch_remove_non_address_bits (struct gdbarch *gdbarch,
> CORE_ADDR
> > > pointer)
> > > +gdbarch_remove_non_address_bits_watchpoint (struct gdbarch
> > > +*gdbarch, CORE_ADDR pointer) {
> > > + gdb_assert (gdbarch != NULL);
> > > + gdb_assert (gdbarch->remove_non_address_bits_watchpoint != NULL);
> > > + if (gdbarch_debug >= 2)
> > > + gdb_printf (gdb_stdlog,
> > > +"gdbarch_remove_non_address_bits_watchpoint
> > > +called\n");
> > > + return gdbarch->remove_non_address_bits_watchpoint (gdbarch,
> > > +pointer); }
> > > +
> > > +void
> > > +set_gdbarch_remove_non_address_bits_watchpoint (struct gdbarch
> > > *gdbarch,
> > > +
> > > gdbarch_remove_non_address_bits_watchpoint_ftype
> > > +remove_non_address_bits_watchpoint)
> > > +{
> > > + gdbarch->remove_non_address_bits_watchpoint =
> > > +remove_non_address_bits_watchpoint;
> > > +}
> > > +
> > > +CORE_ADDR
> > > +gdbarch_remove_non_address_bits_breakpoint (struct gdbarch
> > > +*gdbarch, CORE_ADDR pointer) {
> > > + gdb_assert (gdbarch != NULL);
> > > + gdb_assert (gdbarch->remove_non_address_bits_breakpoint != NULL);
> > > + if (gdbarch_debug >= 2)
> > > + gdb_printf (gdb_stdlog,
> > > +"gdbarch_remove_non_address_bits_breakpoint
> > > +called\n");
> > > + return gdbarch->remove_non_address_bits_breakpoint (gdbarch,
> > > +pointer); }
> > > +
> > > +void
> > > +set_gdbarch_remove_non_address_bits_breakpoint (struct gdbarch
> > > *gdbarch,
> > > +
> > > gdbarch_remove_non_address_bits_breakpoint_ftype
> > > +remove_non_address_bits_breakpoint)
> > > +{
> > > + gdbarch->remove_non_address_bits_breakpoint =
> > > +remove_non_address_bits_breakpoint;
> > > +}
> > > +
> > > +CORE_ADDR
> > > +gdbarch_remove_non_address_bits_memory (struct gdbarch *gdbarch,
> > > +CORE_ADDR pointer)
> > > {
> > > gdb_assert (gdbarch != NULL);
> > > - gdb_assert (gdbarch->remove_non_address_bits != NULL);
> > > + gdb_assert (gdbarch->remove_non_address_bits_memory != NULL);
> > > if (gdbarch_debug >= 2)
> > > - gdb_printf (gdb_stdlog, "gdbarch_remove_non_address_bits
> called\n");
> > > - return gdbarch->remove_non_address_bits (gdbarch, pointer);
> > > + gdb_printf (gdb_stdlog, "gdbarch_remove_non_address_bits_memory
> > > + called\n"); return gdbarch->remove_non_address_bits_memory
> > > + (gdbarch, pointer);
> > > }
> > >
> > > void
> > > -set_gdbarch_remove_non_address_bits (struct gdbarch *gdbarch,
> > > - gdbarch_remove_non_address_bits_ftype
> > > remove_non_address_bits)
> > > +set_gdbarch_remove_non_address_bits_memory (struct gdbarch
> > *gdbarch,
> > > +
> > > gdbarch_remove_non_address_bits_memory_ftype
> > > +remove_non_address_bits_memory)
> > > {
> > > - gdbarch->remove_non_address_bits = remove_non_address_bits;
> > > + gdbarch->remove_non_address_bits_memory =
> > > + remove_non_address_bits_memory;
> > > }
> > >
> > > std::string
> > > diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py
> > > index 4006380076d..cc7c6d8677b 100644
> > > --- a/gdb/gdbarch_components.py
> > > +++ b/gdb/gdbarch_components.py
> > > @@ -1232,18 +1232,55 @@ possible it should be in TARGET_READ_PC
> > > instead).
> > > Method(
> > > comment="""
> > > On some architectures, not all bits of a pointer are significant.
> > > -On AArch64, for example, the top bits of a pointer may carry a
> > > "tag", which - can be ignored by the kernel and the hardware. The
> > > "tag" can be regarded as -additional data associated with the
> > > pointer, but it is not part of the address.
> > > +On AArch64 and amd64, for example, the top bits of a pointer may
> > > +carry a "tag", which can be ignored by the kernel and the hardware.
> > > +The "tag" can be regarded as additional data associated with the
> > > +pointer, but it is not part of the address.
> > >
> > > Given a pointer for the architecture, this hook removes all the
> > > -non- significant bits and sign-extends things as needed. It gets
> > > used to remove - non-address bits from data pointers (for example,
> > > removing the AArch64 MTE tag -bits from a pointer) and from code
> > > pointers (removing the AArch64 PAC signature -from a pointer
> > > containing the return
> > address).
> > > +non-significant bits and sign-extends things as needed. It gets
> > > +used to remove non-address bits from pointers used for watchpoints.
> > > """,
> > > type="CORE_ADDR",
> > > - name="remove_non_address_bits",
> > > + name="remove_non_address_bits_watchpoint",
> > > + params=[("CORE_ADDR", "pointer")],
> > > + predefault="default_remove_non_address_bits",
> > > + invalid=False,
> > > +)
> > > +
> > > +Method(
> > > + comment="""
> > > +On some architectures, not all bits of a pointer are significant.
> > > +On AArch64 and amd64, for example, the top bits of a pointer may
> > > +carry a "tag", which can be ignored by the kernel and the hardware.
> > > +The "tag" can be regarded as additional data associated with the
> > > +pointer, but it is not part of the address.
> > > +
> > > +Given a pointer for the architecture, this hook removes all the
> > > +non-significant bits and sign-extends things as needed. It gets
> > > +used to remove non-address bits from pointers used for breakpoints.
> > > +""",
> > > + type="CORE_ADDR",
> > > + name="remove_non_address_bits_breakpoint",
> > > + params=[("CORE_ADDR", "pointer")],
> > > + predefault="default_remove_non_address_bits",
> > > + invalid=False,
> > > +)
> > > +
> > > +Method(
> > > + comment="""
> > > +On some architectures, not all bits of a pointer are significant.
> > > +On AArch64 and amd64, for example, the top bits of a pointer may
> > > +carry a "tag", which can be ignored by the kernel and the hardware.
> > > +The "tag" can be regarded as additional data associated with the
> > > +pointer, but it is not part of the address.
> > > +
> > > +Given a pointer for the architecture, this hook removes all the
> > > +non-significant bits and sign-extends things as needed. It gets
> > > +used to remove non-address bits from any pointer used to access
> memory.
> > > +""",
> > > + type="CORE_ADDR",
> > > + name="remove_non_address_bits_memory",
> > > params=[("CORE_ADDR", "pointer")],
> > > predefault="default_remove_non_address_bits",
> > > invalid=False,
> > > diff --git a/gdb/target.c b/gdb/target.c index
> > > 1b5aa11ed6f..b622de81e11
> > > 100644
> > > --- a/gdb/target.c
> > > +++ b/gdb/target.c
> > > @@ -1608,7 +1608,8 @@ memory_xfer_partial (struct target_ops *ops,
> > > enum target_object object,
> > > if (len == 0)
> > > return TARGET_XFER_EOF;
> > >
> > > - memaddr = gdbarch_remove_non_address_bits (current_inferior
> > > ()->arch (),
> > > + memaddr
> > > + = gdbarch_remove_non_address_bits_memory (current_inferior
> > > + ()->arch (),
> > > memaddr);
> > >
> > > /* Fill in READBUF with breakpoint shadows, or WRITEBUF with
> > > --
> > > 2.34.1
> > >
> > > Intel Deutschland GmbH
> > > Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
> > > Tel: +49 89 99 8853-0, www.intel.de
> > > Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany
> > > Doon Silva Chairperson of the Supervisory Board: Nicole Lau
> > > Registered
> > > Office: Munich Commercial Register: Amtsgericht Muenchen HRB 186928
> >
> > Kindly pinging for feedback.
> > Patch 2 of this series is already approved by Felix.
> >
> > BR,
> > Christina
>
> Kindly pinging!
>
> BR,
> Christina
Kindly pinging.
Christina
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
> -----Original Message-----
> From: Schimpe, Christina
> Sent: Tuesday, August 20, 2024 3:06 PM
> To: 'gdb-patches@sourceware.org' <gdb-patches@sourceware.org>
> Cc: Willgerodt, Felix <FeliX.Willgerodt@intel.com>; 'luis.machado@arm.com'
> <luis.machado@arm.com>; 'eliz@gnu.org' <eliz@gnu.org>
> Subject: RE: [PING*3][PATCH v5 1/2] gdb: Make tagged pointer support
> configurable.
>
> > -----Original Message-----
> > From: Schimpe, Christina
> > Sent: Monday, August 12, 2024 10:42 AM
> > To: 'gdb-patches@sourceware.org' <gdb-patches@sourceware.org>
> > Cc: Willgerodt, Felix <FeliX.Willgerodt@intel.com>;
> 'luis.machado@arm.com'
> > <luis.machado@arm.com>; 'eliz@gnu.org' <eliz@gnu.org>
> > Subject: RE: [PING*2][PATCH v5 1/2] gdb: Make tagged pointer support
> > configurable.
> >
> > > > -----Original Message-----
> > > > From: Schimpe, Christina <christina.schimpe@intel.com>
> > > > Sent: Tuesday, July 9, 2024 2:17 PM
> > > > To: gdb-patches@sourceware.org
> > > > Cc: Willgerodt, Felix <felix.willgerodt@intel.com>;
> > > > luis.machado@arm.com; eliz@gnu.org
> > > > Subject: [PATCH v5 1/2] gdb: Make tagged pointer support configurable.
> > > >
> > > > From: Christina Schimpe <christina.schimpe@intel.com>
> > > >
> > > > The gdbarch function gdbarch_remove_non_address_bits adjusts
> > > addresses
> > > > to enable debugging of programs with tagged pointers on Linux, for
> > > > instance for ARM's feature top byte ignore (TBI).
> > > > Once the function is implemented for an architecture, it adjusts
> > > > addresses for memory access, breakpoints and watchpoints.
> > > >
> > > > Linear address masking (LAM) is Intel's (R) implementation of
> > > > tagged pointer support. It requires certain adaptions to GDB's
> > > > tagged pointer support due to the following:
> > > > - LAM supports address tagging for data accesses only. Thus, specifying
> > > > breakpoints on tagged addresses is not a valid use case.
> > > > - In contrast to the implementation for ARM's TBI, the Linux
> > > > kernel
> > supports
> > > > tagged pointers for memory access.
> > > >
> > > > This patch makes GDB's tagged pointer support configurable such
> > > > that it is possible to enable the address adjustment for a
> > > > specific feature only (e.g memory access, breakpoints or
> > > > watchpoints). This way, one can make sure that addresses are only
> > > > adjusted when necessary. In case of LAM, this avoids unnecessary
> > > > parsing of the /proc/<pid>/status file
> > > to get the untag mask.
> > > >
> > > > Reviewed-By: Felix Willgerodt <felix.willgerodt@intel.com>
> > > > ---
> > > > gdb/aarch64-linux-nat.c | 2 +-
> > > > gdb/aarch64-linux-tdep.c | 13 ++++----
> > > > gdb/aarch64-tdep.c | 17 ++++++----
> > > > gdb/aarch64-tdep.h | 6 ++++
> > > > gdb/breakpoint.c | 5 +--
> > > > gdb/gdbarch-gen.h | 49 ++++++++++++++++++++++-------
> > > > gdb/gdbarch.c | 66 ++++++++++++++++++++++++++++++++-------
> > > > gdb/gdbarch_components.py | 53 ++++++++++++++++++++++++++-----
> > > > gdb/target.c | 3 +-
> > > > 9 files changed, 168 insertions(+), 46 deletions(-)
> > > >
> > > > diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
> > > > index 2e6541f53c3..dac42b4f48b 100644
> > > > --- a/gdb/aarch64-linux-nat.c
> > > > +++ b/gdb/aarch64-linux-nat.c
> > > > @@ -945,7 +945,7 @@
> aarch64_linux_nat_target::stopped_data_address
> > > > (CORE_ADDR *addr_p)
> > > > kernel can potentially be tagged addresses. */
> > > > struct gdbarch *gdbarch = thread_architecture (inferior_ptid);
> > > > const CORE_ADDR addr_trap
> > > > - = gdbarch_remove_non_address_bits (gdbarch, (CORE_ADDR)
> > > > siginfo.si_addr);
> > > > + = aarch64_remove_non_address_bits (gdbarch, (CORE_ADDR)
> > > > + siginfo.si_addr);
> > > >
> > > > /* Check if the address matches any watched address. */
> > > > state = aarch64_get_debug_reg_state (inferior_ptid.pid ());
> > > > diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
> > > > index a1296a8f0c7..bf5ce72aa5f 100644
> > > > --- a/gdb/aarch64-linux-tdep.c
> > > > +++ b/gdb/aarch64-linux-tdep.c
> > > > @@ -2456,7 +2456,7 @@ static bool
> > > > aarch64_linux_tagged_address_p (struct gdbarch *gdbarch,
> > > > CORE_ADDR
> > > > address) {
> > > > /* Remove the top byte for the memory range check. */
> > > > - address = gdbarch_remove_non_address_bits (gdbarch, address);
> > > > + address = aarch64_remove_non_address_bits (gdbarch, address);
> > > >
> > > > /* Check if the page that contains ADDRESS is mapped with
> PROT_MTE.
> > > */
> > > > if (!linux_address_in_memtag_page (address)) @@ -2478,7 +2478,7
> > > > @@ aarch64_linux_memtag_matches_p (struct gdbarch *gdbarch,
> > > >
> > > > /* Fetch the allocation tag for ADDRESS. */
> > > > std::optional<CORE_ADDR> atag
> > > > - = aarch64_mte_get_atag (gdbarch_remove_non_address_bits
> > (gdbarch,
> > > > addr));
> > > > + = aarch64_mte_get_atag (aarch64_remove_non_address_bits
> > > > + (gdbarch, addr));
> > > >
> > > > if (!atag.has_value ())
> > > > return true;
> > > > @@ -2517,7 +2517,7 @@ aarch64_linux_set_memtags (struct gdbarch
> > > > *gdbarch, struct value *address,
> > > > else
> > > > {
> > > > /* Remove the top byte. */
> > > > - addr = gdbarch_remove_non_address_bits (gdbarch, addr);
> > > > + addr = aarch64_remove_non_address_bits (gdbarch, addr);
> > > >
> > > > /* With G being the number of tag granules and N the number
> > > > of
> > tags
> > > > passed in, we can have the following cases:
> > > > @@ -2566,7 +2566,7 @@ aarch64_linux_get_memtag (struct gdbarch
> > > > *gdbarch, struct value *address,
> > > > else
> > > > {
> > > > /* Remove the top byte. */
> > > > - addr = gdbarch_remove_non_address_bits (gdbarch, addr);
> > > > + addr = aarch64_remove_non_address_bits (gdbarch, addr);
> > > > std::optional<CORE_ADDR> atag = aarch64_mte_get_atag
> > > > (addr);
> > > >
> > > > if (!atag.has_value ())
> > > > @@ -2640,8 +2640,9 @@ aarch64_linux_report_signal_info (struct
> > > > gdbarch *gdbarch,
> > > > uiout->text ("\n");
> > > >
> > > > std::optional<CORE_ADDR> atag
> > > > - = aarch64_mte_get_atag (gdbarch_remove_non_address_bits
> > > > (gdbarch,
> > > > - fault_addr));
> > > > + = aarch64_mte_get_atag (
> > > > + aarch64_remove_non_address_bits (gdbarch, fault_addr));
> > > > +
> > > > gdb_byte ltag = aarch64_mte_get_ltag (fault_addr);
> > > >
> > > > if (!atag.has_value ())
> > > > diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index
> > > > e4bca6c6632..ba1dc3d5844 100644
> > > > --- a/gdb/aarch64-tdep.c
> > > > +++ b/gdb/aarch64-tdep.c
> > > > @@ -4088,10 +4088,9 @@ aarch64_stack_frame_destroyed_p (struct
> > > gdbarch
> > > > *gdbarch, CORE_ADDR pc)
> > > > return streq (inst.opcode->name, "ret"); }
> > > >
> > > > -/* AArch64 implementation of the remove_non_address_bits gdbarch
> > > hook.
> > > > Remove
> > > > - non address bits from a pointer value. */
> > > > +/* See aarch64-tdep.h. */
> > > >
> > > > -static CORE_ADDR
> > > > +CORE_ADDR
> > > > aarch64_remove_non_address_bits (struct gdbarch *gdbarch,
> > CORE_ADDR
> > > > pointer) {
> > > > /* By default, we assume TBI and discard the top 8 bits plus
> > > > the VA range @@ -4585,9 +4584,15 @@ aarch64_gdbarch_init (struct
> > > gdbarch_info
> > > > info, struct gdbarch_list *arches)
> > > > tdep->ra_sign_state_regnum = ra_sign_state_offset + num_regs;
> > > >
> > > > /* Architecture hook to remove bits of a pointer that are not part of
> the
> > > > - address, like memory tags (MTE) and pointer authentication
> > signatures.
> > > > */
> > > > - set_gdbarch_remove_non_address_bits (gdbarch,
> > > > - aarch64_remove_non_address_bits);
> > > > + address, like memory tags (MTE) and pointer authentication
> > signatures.
> > > > + Configure address adjustment for watch-, breakpoints and memory
> > > > + transfer. */
> > > > + set_gdbarch_remove_non_address_bits_watchpoint
> > > > + (gdbarch, aarch64_remove_non_address_bits);
> > > > + set_gdbarch_remove_non_address_bits_breakpoint
> > > > + (gdbarch, aarch64_remove_non_address_bits);
> > > > + set_gdbarch_remove_non_address_bits_memory
> > > > + (gdbarch, aarch64_remove_non_address_bits);
> > > >
> > > > /* SME pseudo-registers. */
> > > > if (tdep->has_sme ())
> > > > diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h index
> > > > 0e6024bfcbc..a9c8815f8be 100644
> > > > --- a/gdb/aarch64-tdep.h
> > > > +++ b/gdb/aarch64-tdep.h
> > > > @@ -203,4 +203,10 @@ void aarch64_displaced_step_fixup (struct
> > > > gdbarch *gdbarch,
> > > >
> > > > bool aarch64_displaced_step_hw_singlestep (struct gdbarch
> > > > *gdbarch);
> > > >
> > > > +/* AArch64 implementation of the remove_non_address_bits gdbarch
> > > > hooks.
> > > > + Remove non address bits from a pointer value. */
> > > > +
> > > > +CORE_ADDR aarch64_remove_non_address_bits (struct gdbarch
> > *gdbarch,
> > > > + CORE_ADDR pointer);
> > > > +
> > > > #endif /* aarch64-tdep.h */
> > > > diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index
> > > > a973518ac5f..8c2d9d247ec 100644
> > > > --- a/gdb/breakpoint.c
> > > > +++ b/gdb/breakpoint.c
> > > > @@ -2238,7 +2238,8 @@ update_watchpoint (struct watchpoint *b,
> > > > bool
> > > > reparse)
> > > > loc->gdbarch = v->type ()->arch ();
> > > > loc->pspace = wp_pspace;
> > > > loc->address
> > > > - = gdbarch_remove_non_address_bits (loc->gdbarch, addr);
> > > > + = gdbarch_remove_non_address_bits_watchpoint (loc-
> > > > >gdbarch,
> > > > + addr);
> > > > b->add_location (*loc);
> > > >
> > > > if (bitsize != 0)
> > > > @@ -7477,7 +7478,7 @@ adjust_breakpoint_address (struct gdbarch
> > > > *gdbarch,
> > > > }
> > > >
> > > > adjusted_bpaddr
> > > > - = gdbarch_remove_non_address_bits (gdbarch, adjusted_bpaddr);
> > > > + = gdbarch_remove_non_address_bits_breakpoint (gdbarch,
> > > > +adjusted_bpaddr);
> > > >
> > > > /* An adjusted breakpoint address can significantly alter
> > > > a user's expectations. Print a warning if an adjustment diff
> > > > --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h index
> > > > b982fd7cd09..9fda85f860f
> > > > 100644
> > > > --- a/gdb/gdbarch-gen.h
> > > > +++ b/gdb/gdbarch-gen.h
> > > > @@ -684,19 +684,46 @@ extern CORE_ADDR
> gdbarch_addr_bits_remove
> > > > (struct gdbarch *gdbarch, CORE_ADDR ad extern void
> > > > set_gdbarch_addr_bits_remove (struct gdbarch *gdbarch,
> > > > gdbarch_addr_bits_remove_ftype *addr_bits_remove);
> > > >
> > > > /* On some architectures, not all bits of a pointer are significant.
> > > > - On AArch64, for example, the top bits of a pointer may carry a "tag",
> > > which
> > > > - can be ignored by the kernel and the hardware. The "tag" can be
> > > regarded
> > > > as
> > > > - additional data associated with the pointer, but it is not part of the
> > > > address.
> > > > + On AArch64 and amd64, for example, the top bits of a pointer
> > > > + may carry
> > > a
> > > > + "tag", which can be ignored by the kernel and the hardware. The
> "tag"
> > > > can be
> > > > + regarded as additional data associated with the pointer, but
> > > > + it is not
> > part
> > > > + of the address.
> > > >
> > > > Given a pointer for the architecture, this hook removes all the
> > > > - non-significant bits and sign-extends things as needed. It gets used
> to
> > > > remove
> > > > - non-address bits from data pointers (for example, removing the
> > AArch64
> > > > MTE tag
> > > > - bits from a pointer) and from code pointers (removing the AArch64
> PAC
> > > > signature
> > > > - from a pointer containing the return address). */
> > > > -
> > > > -typedef CORE_ADDR (gdbarch_remove_non_address_bits_ftype)
> (struct
> > > > gdbarch *gdbarch, CORE_ADDR pointer); -extern CORE_ADDR
> > > > gdbarch_remove_non_address_bits (struct gdbarch *gdbarch,
> > CORE_ADDR
> > > > pointer); -extern void set_gdbarch_remove_non_address_bits (struct
> > > > gdbarch *gdbarch, gdbarch_remove_non_address_bits_ftype
> > > > *remove_non_address_bits);
> > > > + non-significant bits and sign-extends things as needed. It gets used
> to
> > > > + remove non-address bits from pointers used for watchpoints. */
> > > > +
> > > > +typedef CORE_ADDR
> > > > (gdbarch_remove_non_address_bits_watchpoint_ftype)
> > > > +(struct gdbarch *gdbarch, CORE_ADDR pointer); extern CORE_ADDR
> > > > +gdbarch_remove_non_address_bits_watchpoint (struct gdbarch
> > > > +*gdbarch, CORE_ADDR pointer); extern void
> > > > +set_gdbarch_remove_non_address_bits_watchpoint (struct gdbarch
> > > > +*gdbarch, gdbarch_remove_non_address_bits_watchpoint_ftype
> > > > +*remove_non_address_bits_watchpoint);
> > > > +
> > > > +/* On some architectures, not all bits of a pointer are significant.
> > > > + On AArch64 and amd64, for example, the top bits of a pointer
> > > > +may carry
> > > a
> > > > + "tag", which can be ignored by the kernel and the hardware. The
> "tag"
> > > > can be
> > > > + regarded as additional data associated with the pointer, but
> > > > + it is not
> > part
> > > > + of the address.
> > > > +
> > > > + Given a pointer for the architecture, this hook removes all the
> > > > + non-significant bits and sign-extends things as needed. It gets used
> to
> > > > + remove non-address bits from pointers used for breakpoints. */
> > > > +
> > > > +typedef CORE_ADDR
> > > > (gdbarch_remove_non_address_bits_breakpoint_ftype)
> > > > +(struct gdbarch *gdbarch, CORE_ADDR pointer); extern CORE_ADDR
> > > > +gdbarch_remove_non_address_bits_breakpoint (struct gdbarch
> > > > +*gdbarch, CORE_ADDR pointer); extern void
> > > > +set_gdbarch_remove_non_address_bits_breakpoint (struct gdbarch
> > > > +*gdbarch, gdbarch_remove_non_address_bits_breakpoint_ftype
> > > > +*remove_non_address_bits_breakpoint);
> > > > +
> > > > +/* On some architectures, not all bits of a pointer are significant.
> > > > + On AArch64 and amd64, for example, the top bits of a pointer
> > > > +may carry
> > > a
> > > > + "tag", which can be ignored by the kernel and the hardware. The
> "tag"
> > > > can be
> > > > + regarded as additional data associated with the pointer, but
> > > > + it is not
> > part
> > > > + of the address.
> > > > +
> > > > + Given a pointer for the architecture, this hook removes all the
> > > > + non-significant bits and sign-extends things as needed. It gets used
> to
> > > > + remove non-address bits from any pointer used to access memory.
> > > > + */
> > > > +
> > > > +typedef CORE_ADDR
> > (gdbarch_remove_non_address_bits_memory_ftype)
> > > > +(struct gdbarch *gdbarch, CORE_ADDR pointer); extern CORE_ADDR
> > > > +gdbarch_remove_non_address_bits_memory (struct gdbarch
> *gdbarch,
> > > > +CORE_ADDR pointer); extern void
> > > > +set_gdbarch_remove_non_address_bits_memory (struct gdbarch
> > > *gdbarch,
> > > > +gdbarch_remove_non_address_bits_memory_ftype
> > > > +*remove_non_address_bits_memory);
> > > >
> > > > /* Return a string representation of the memory tag TAG. */
> > > >
> > > > diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index
> > > > 58e9ebbdc59..99a54a38d61
> > > > 100644
> > > > --- a/gdb/gdbarch.c
> > > > +++ b/gdb/gdbarch.c
> > > > @@ -143,7 +143,9 @@ struct gdbarch
> > > > int frame_red_zone_size = 0;
> > > > gdbarch_convert_from_func_ptr_addr_ftype
> > > > *convert_from_func_ptr_addr = convert_from_func_ptr_addr_identity;
> > > > gdbarch_addr_bits_remove_ftype *addr_bits_remove =
> > > > core_addr_identity;
> > > > - gdbarch_remove_non_address_bits_ftype
> *remove_non_address_bits
> > =
> > > > default_remove_non_address_bits;
> > > > + gdbarch_remove_non_address_bits_watchpoint_ftype
> > > > + *remove_non_address_bits_watchpoint =
> > > > default_remove_non_address_bits;
> > > > + gdbarch_remove_non_address_bits_breakpoint_ftype
> > > > + *remove_non_address_bits_breakpoint =
> > > > default_remove_non_address_bits;
> > > > + gdbarch_remove_non_address_bits_memory_ftype
> > > > + *remove_non_address_bits_memory =
> > > default_remove_non_address_bits;
> > > > gdbarch_memtag_to_string_ftype *memtag_to_string =
> > > > default_memtag_to_string;
> > > > gdbarch_tagged_address_p_ftype *tagged_address_p =
> > > > default_tagged_address_p;
> > > > gdbarch_memtag_matches_p_ftype *memtag_matches_p =
> > > > default_memtag_matches_p; @@ -407,7 +409,9 @@ verify_gdbarch
> > (struct
> > > > gdbarch *gdbarch)
> > > > /* Skip verify of frame_red_zone_size, invalid_p == 0 */
> > > > /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */
> > > > /* Skip verify of addr_bits_remove, invalid_p == 0 */
> > > > - /* Skip verify of remove_non_address_bits, invalid_p == 0 */
> > > > + /* Skip verify of remove_non_address_bits_watchpoint, invalid_p
> > > > + ==
> > > > + 0 */
> > > > + /* Skip verify of remove_non_address_bits_breakpoint, invalid_p
> > > > + ==
> > > > + 0 */
> > > > + /* Skip verify of remove_non_address_bits_memory, invalid_p ==
> > > > + 0 */
> > > > /* Skip verify of memtag_to_string, invalid_p == 0 */
> > > > /* Skip verify of tagged_address_p, invalid_p == 0 */
> > > > /* Skip verify of memtag_matches_p, invalid_p == 0 */ @@ -910,8
> > > > +914,14 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file
> > > > +*file)
> > > > "gdbarch_dump: addr_bits_remove = <%s>\n",
> > > > host_address_to_string (gdbarch->addr_bits_remove));
> > > > gdb_printf (file,
> > > > - "gdbarch_dump: remove_non_address_bits = <%s>\n",
> > > > - host_address_to_string (gdbarch->remove_non_address_bits));
> > > > + "gdbarch_dump: remove_non_address_bits_watchpoint =
> > > > <%s>\n",
> > > > + host_address_to_string
> > > > +(gdbarch->remove_non_address_bits_watchpoint));
> > > > + gdb_printf (file,
> > > > + "gdbarch_dump: remove_non_address_bits_breakpoint =
> > > > <%s>\n",
> > > > + host_address_to_string
> > > > +(gdbarch->remove_non_address_bits_breakpoint));
> > > > + gdb_printf (file,
> > > > + "gdbarch_dump: remove_non_address_bits_memory = <%s>\n",
> > > > + host_address_to_string
> > > > +(gdbarch->remove_non_address_bits_memory));
> > > > gdb_printf (file,
> > > > "gdbarch_dump: memtag_to_string = <%s>\n",
> > > > host_address_to_string (gdbarch->memtag_to_string)); @@ -
> > > > 3198,20 +3208,54 @@ set_gdbarch_addr_bits_remove (struct gdbarch
> > > > *gdbarch, }
> > > >
> > > > CORE_ADDR
> > > > -gdbarch_remove_non_address_bits (struct gdbarch *gdbarch,
> > CORE_ADDR
> > > > pointer)
> > > > +gdbarch_remove_non_address_bits_watchpoint (struct gdbarch
> > > > +*gdbarch, CORE_ADDR pointer) {
> > > > + gdb_assert (gdbarch != NULL);
> > > > + gdb_assert (gdbarch->remove_non_address_bits_watchpoint !=
> > > > +NULL);
> > > > + if (gdbarch_debug >= 2)
> > > > + gdb_printf (gdb_stdlog,
> > > > +"gdbarch_remove_non_address_bits_watchpoint
> > > > +called\n");
> > > > + return gdbarch->remove_non_address_bits_watchpoint (gdbarch,
> > > > +pointer); }
> > > > +
> > > > +void
> > > > +set_gdbarch_remove_non_address_bits_watchpoint (struct gdbarch
> > > > *gdbarch,
> > > > +
> > > > gdbarch_remove_non_address_bits_watchpoint_ftype
> > > > +remove_non_address_bits_watchpoint)
> > > > +{
> > > > + gdbarch->remove_non_address_bits_watchpoint =
> > > > +remove_non_address_bits_watchpoint;
> > > > +}
> > > > +
> > > > +CORE_ADDR
> > > > +gdbarch_remove_non_address_bits_breakpoint (struct gdbarch
> > > > +*gdbarch, CORE_ADDR pointer) {
> > > > + gdb_assert (gdbarch != NULL);
> > > > + gdb_assert (gdbarch->remove_non_address_bits_breakpoint !=
> > > > +NULL);
> > > > + if (gdbarch_debug >= 2)
> > > > + gdb_printf (gdb_stdlog,
> > > > +"gdbarch_remove_non_address_bits_breakpoint
> > > > +called\n");
> > > > + return gdbarch->remove_non_address_bits_breakpoint (gdbarch,
> > > > +pointer); }
> > > > +
> > > > +void
> > > > +set_gdbarch_remove_non_address_bits_breakpoint (struct gdbarch
> > > > *gdbarch,
> > > > +
> > > > gdbarch_remove_non_address_bits_breakpoint_ftype
> > > > +remove_non_address_bits_breakpoint)
> > > > +{
> > > > + gdbarch->remove_non_address_bits_breakpoint =
> > > > +remove_non_address_bits_breakpoint;
> > > > +}
> > > > +
> > > > +CORE_ADDR
> > > > +gdbarch_remove_non_address_bits_memory (struct gdbarch
> *gdbarch,
> > > > +CORE_ADDR pointer)
> > > > {
> > > > gdb_assert (gdbarch != NULL);
> > > > - gdb_assert (gdbarch->remove_non_address_bits != NULL);
> > > > + gdb_assert (gdbarch->remove_non_address_bits_memory != NULL);
> > > > if (gdbarch_debug >= 2)
> > > > - gdb_printf (gdb_stdlog, "gdbarch_remove_non_address_bits
> > called\n");
> > > > - return gdbarch->remove_non_address_bits (gdbarch, pointer);
> > > > + gdb_printf (gdb_stdlog,
> > > > + "gdbarch_remove_non_address_bits_memory
> > > > + called\n"); return gdbarch->remove_non_address_bits_memory
> > > > + (gdbarch, pointer);
> > > > }
> > > >
> > > > void
> > > > -set_gdbarch_remove_non_address_bits (struct gdbarch *gdbarch,
> > > > - gdbarch_remove_non_address_bits_ftype
> > > > remove_non_address_bits)
> > > > +set_gdbarch_remove_non_address_bits_memory (struct gdbarch
> > > *gdbarch,
> > > > +
> > > > gdbarch_remove_non_address_bits_memory_ftype
> > > > +remove_non_address_bits_memory)
> > > > {
> > > > - gdbarch->remove_non_address_bits = remove_non_address_bits;
> > > > + gdbarch->remove_non_address_bits_memory =
> > > > + remove_non_address_bits_memory;
> > > > }
> > > >
> > > > std::string
> > > > diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py
> > > > index 4006380076d..cc7c6d8677b 100644
> > > > --- a/gdb/gdbarch_components.py
> > > > +++ b/gdb/gdbarch_components.py
> > > > @@ -1232,18 +1232,55 @@ possible it should be in TARGET_READ_PC
> > > > instead).
> > > > Method(
> > > > comment="""
> > > > On some architectures, not all bits of a pointer are significant.
> > > > -On AArch64, for example, the top bits of a pointer may carry a
> > > > "tag", which - can be ignored by the kernel and the hardware. The
> > > > "tag" can be regarded as -additional data associated with the
> > > > pointer, but it is not part of the address.
> > > > +On AArch64 and amd64, for example, the top bits of a pointer may
> > > > +carry a "tag", which can be ignored by the kernel and the hardware.
> > > > +The "tag" can be regarded as additional data associated with the
> > > > +pointer, but it is not part of the address.
> > > >
> > > > Given a pointer for the architecture, this hook removes all the
> > > > -non- significant bits and sign-extends things as needed. It gets
> > > > used to remove - non-address bits from data pointers (for example,
> > > > removing the AArch64 MTE tag -bits from a pointer) and from code
> > > > pointers (removing the AArch64 PAC signature -from a pointer
> > > > containing the return
> > > address).
> > > > +non-significant bits and sign-extends things as needed. It gets
> > > > +used to remove non-address bits from pointers used for watchpoints.
> > > > """,
> > > > type="CORE_ADDR",
> > > > - name="remove_non_address_bits",
> > > > + name="remove_non_address_bits_watchpoint",
> > > > + params=[("CORE_ADDR", "pointer")],
> > > > + predefault="default_remove_non_address_bits",
> > > > + invalid=False,
> > > > +)
> > > > +
> > > > +Method(
> > > > + comment="""
> > > > +On some architectures, not all bits of a pointer are significant.
> > > > +On AArch64 and amd64, for example, the top bits of a pointer may
> > > > +carry a "tag", which can be ignored by the kernel and the hardware.
> > > > +The "tag" can be regarded as additional data associated with the
> > > > +pointer, but it is not part of the address.
> > > > +
> > > > +Given a pointer for the architecture, this hook removes all the
> > > > +non-significant bits and sign-extends things as needed. It gets
> > > > +used to remove non-address bits from pointers used for breakpoints.
> > > > +""",
> > > > + type="CORE_ADDR",
> > > > + name="remove_non_address_bits_breakpoint",
> > > > + params=[("CORE_ADDR", "pointer")],
> > > > + predefault="default_remove_non_address_bits",
> > > > + invalid=False,
> > > > +)
> > > > +
> > > > +Method(
> > > > + comment="""
> > > > +On some architectures, not all bits of a pointer are significant.
> > > > +On AArch64 and amd64, for example, the top bits of a pointer may
> > > > +carry a "tag", which can be ignored by the kernel and the hardware.
> > > > +The "tag" can be regarded as additional data associated with the
> > > > +pointer, but it is not part of the address.
> > > > +
> > > > +Given a pointer for the architecture, this hook removes all the
> > > > +non-significant bits and sign-extends things as needed. It gets
> > > > +used to remove non-address bits from any pointer used to access
> > memory.
> > > > +""",
> > > > + type="CORE_ADDR",
> > > > + name="remove_non_address_bits_memory",
> > > > params=[("CORE_ADDR", "pointer")],
> > > > predefault="default_remove_non_address_bits",
> > > > invalid=False,
> > > > diff --git a/gdb/target.c b/gdb/target.c index
> > > > 1b5aa11ed6f..b622de81e11
> > > > 100644
> > > > --- a/gdb/target.c
> > > > +++ b/gdb/target.c
> > > > @@ -1608,7 +1608,8 @@ memory_xfer_partial (struct target_ops *ops,
> > > > enum target_object object,
> > > > if (len == 0)
> > > > return TARGET_XFER_EOF;
> > > >
> > > > - memaddr = gdbarch_remove_non_address_bits (current_inferior
> > > > ()->arch (),
> > > > + memaddr
> > > > + = gdbarch_remove_non_address_bits_memory (current_inferior
> > > > + ()->arch (),
> > > > memaddr);
> > > >
> > > > /* Fill in READBUF with breakpoint shadows, or WRITEBUF with
> > > > --
> > > > 2.34.1
> > > >
> > > > Intel Deutschland GmbH
> > > > Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
> > > > Tel: +49 89 99 8853-0, www.intel.de Managing Directors: Sean
> > > > Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva Chairperson of
> > > > the Supervisory Board: Nicole Lau Registered
> > > > Office: Munich Commercial Register: Amtsgericht Muenchen HRB
> > > > 186928
> > >
> > > Kindly pinging for feedback.
> > > Patch 2 of this series is already approved by Felix.
> > >
> > > BR,
> > > Christina
> >
> > Kindly pinging!
> >
> > BR,
> > Christina
>
> Kindly pinging.
Kindly pinging.
BR,
Christina
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
> -----Original Message-----
> From: Schimpe, Christina
> Sent: Thursday, August 29, 2024 3:26 PM
> To: gdb-patches@sourceware.org
> Cc: Willgerodt, Felix <FeliX.Willgerodt@intel.com>; luis.machado@arm.com;
> eliz@gnu.org
> Subject: RE: [PING*4][PATCH v5 1/2] gdb: Make tagged pointer support
> configurable.
>
> > -----Original Message-----
> > From: Schimpe, Christina
> > Sent: Tuesday, August 20, 2024 3:06 PM
> > To: 'gdb-patches@sourceware.org' <gdb-patches@sourceware.org>
> > Cc: Willgerodt, Felix <FeliX.Willgerodt@intel.com>;
> 'luis.machado@arm.com'
> > <luis.machado@arm.com>; 'eliz@gnu.org' <eliz@gnu.org>
> > Subject: RE: [PING*3][PATCH v5 1/2] gdb: Make tagged pointer support
> > configurable.
> >
> > > -----Original Message-----
> > > From: Schimpe, Christina
> > > Sent: Monday, August 12, 2024 10:42 AM
> > > To: 'gdb-patches@sourceware.org' <gdb-patches@sourceware.org>
> > > Cc: Willgerodt, Felix <FeliX.Willgerodt@intel.com>;
> > 'luis.machado@arm.com'
> > > <luis.machado@arm.com>; 'eliz@gnu.org' <eliz@gnu.org>
> > > Subject: RE: [PING*2][PATCH v5 1/2] gdb: Make tagged pointer support
> > > configurable.
> > >
> > > > > -----Original Message-----
> > > > > From: Schimpe, Christina <christina.schimpe@intel.com>
> > > > > Sent: Tuesday, July 9, 2024 2:17 PM
> > > > > To: gdb-patches@sourceware.org
> > > > > Cc: Willgerodt, Felix <felix.willgerodt@intel.com>;
> > > > > luis.machado@arm.com; eliz@gnu.org
> > > > > Subject: [PATCH v5 1/2] gdb: Make tagged pointer support
> configurable.
> > > > >
> > > > > From: Christina Schimpe <christina.schimpe@intel.com>
> > > > >
> > > > > The gdbarch function gdbarch_remove_non_address_bits adjusts
> > > > addresses
> > > > > to enable debugging of programs with tagged pointers on Linux,
> > > > > for instance for ARM's feature top byte ignore (TBI).
> > > > > Once the function is implemented for an architecture, it adjusts
> > > > > addresses for memory access, breakpoints and watchpoints.
> > > > >
> > > > > Linear address masking (LAM) is Intel's (R) implementation of
> > > > > tagged pointer support. It requires certain adaptions to GDB's
> > > > > tagged pointer support due to the following:
> > > > > - LAM supports address tagging for data accesses only. Thus,
> specifying
> > > > > breakpoints on tagged addresses is not a valid use case.
> > > > > - In contrast to the implementation for ARM's TBI, the Linux
> > > > > kernel
> > > supports
> > > > > tagged pointers for memory access.
> > > > >
> > > > > This patch makes GDB's tagged pointer support configurable such
> > > > > that it is possible to enable the address adjustment for a
> > > > > specific feature only (e.g memory access, breakpoints or
> > > > > watchpoints). This way, one can make sure that addresses are
> > > > > only adjusted when necessary. In case of LAM, this avoids
> > > > > unnecessary parsing of the /proc/<pid>/status file
> > > > to get the untag mask.
> > > > >
> > > > > Reviewed-By: Felix Willgerodt <felix.willgerodt@intel.com>
> > > > > ---
> > > > > gdb/aarch64-linux-nat.c | 2 +-
> > > > > gdb/aarch64-linux-tdep.c | 13 ++++----
> > > > > gdb/aarch64-tdep.c | 17 ++++++----
> > > > > gdb/aarch64-tdep.h | 6 ++++
> > > > > gdb/breakpoint.c | 5 +--
> > > > > gdb/gdbarch-gen.h | 49 ++++++++++++++++++++++-------
> > > > > gdb/gdbarch.c | 66 ++++++++++++++++++++++++++++++++------
> -
> > > > > gdb/gdbarch_components.py | 53 ++++++++++++++++++++++++++-----
> > > > > gdb/target.c | 3 +-
> > > > > 9 files changed, 168 insertions(+), 46 deletions(-)
> > > > >
> > > > > diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
> > > > > index 2e6541f53c3..dac42b4f48b 100644
> > > > > --- a/gdb/aarch64-linux-nat.c
> > > > > +++ b/gdb/aarch64-linux-nat.c
> > > > > @@ -945,7 +945,7 @@
> > aarch64_linux_nat_target::stopped_data_address
> > > > > (CORE_ADDR *addr_p)
> > > > > kernel can potentially be tagged addresses. */
> > > > > struct gdbarch *gdbarch = thread_architecture (inferior_ptid);
> > > > > const CORE_ADDR addr_trap
> > > > > - = gdbarch_remove_non_address_bits (gdbarch, (CORE_ADDR)
> > > > > siginfo.si_addr);
> > > > > + = aarch64_remove_non_address_bits (gdbarch, (CORE_ADDR)
> > > > > + siginfo.si_addr);
> > > > >
> > > > > /* Check if the address matches any watched address. */
> > > > > state = aarch64_get_debug_reg_state (inferior_ptid.pid ());
> > > > > diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
> > > > > index a1296a8f0c7..bf5ce72aa5f 100644
> > > > > --- a/gdb/aarch64-linux-tdep.c
> > > > > +++ b/gdb/aarch64-linux-tdep.c
> > > > > @@ -2456,7 +2456,7 @@ static bool
> > > > > aarch64_linux_tagged_address_p (struct gdbarch *gdbarch,
> > > > > CORE_ADDR
> > > > > address) {
> > > > > /* Remove the top byte for the memory range check. */
> > > > > - address = gdbarch_remove_non_address_bits (gdbarch, address);
> > > > > + address = aarch64_remove_non_address_bits (gdbarch, address);
> > > > >
> > > > > /* Check if the page that contains ADDRESS is mapped with
> > PROT_MTE.
> > > > */
> > > > > if (!linux_address_in_memtag_page (address)) @@ -2478,7
> > > > > +2478,7 @@ aarch64_linux_memtag_matches_p (struct gdbarch
> > > > > *gdbarch,
> > > > >
> > > > > /* Fetch the allocation tag for ADDRESS. */
> > > > > std::optional<CORE_ADDR> atag
> > > > > - = aarch64_mte_get_atag (gdbarch_remove_non_address_bits
> > > (gdbarch,
> > > > > addr));
> > > > > + = aarch64_mte_get_atag (aarch64_remove_non_address_bits
> > > > > + (gdbarch, addr));
> > > > >
> > > > > if (!atag.has_value ())
> > > > > return true;
> > > > > @@ -2517,7 +2517,7 @@ aarch64_linux_set_memtags (struct gdbarch
> > > > > *gdbarch, struct value *address,
> > > > > else
> > > > > {
> > > > > /* Remove the top byte. */
> > > > > - addr = gdbarch_remove_non_address_bits (gdbarch, addr);
> > > > > + addr = aarch64_remove_non_address_bits (gdbarch, addr);
> > > > >
> > > > > /* With G being the number of tag granules and N the
> > > > > number of
> > > tags
> > > > > passed in, we can have the following cases:
> > > > > @@ -2566,7 +2566,7 @@ aarch64_linux_get_memtag (struct gdbarch
> > > > > *gdbarch, struct value *address,
> > > > > else
> > > > > {
> > > > > /* Remove the top byte. */
> > > > > - addr = gdbarch_remove_non_address_bits (gdbarch, addr);
> > > > > + addr = aarch64_remove_non_address_bits (gdbarch, addr);
> > > > > std::optional<CORE_ADDR> atag = aarch64_mte_get_atag
> > > > > (addr);
> > > > >
> > > > > if (!atag.has_value ())
> > > > > @@ -2640,8 +2640,9 @@ aarch64_linux_report_signal_info (struct
> > > > > gdbarch *gdbarch,
> > > > > uiout->text ("\n");
> > > > >
> > > > > std::optional<CORE_ADDR> atag
> > > > > - = aarch64_mte_get_atag (gdbarch_remove_non_address_bits
> > > > > (gdbarch,
> > > > > -
> fault_addr));
> > > > > + = aarch64_mte_get_atag (
> > > > > + aarch64_remove_non_address_bits (gdbarch, fault_addr));
> > > > > +
> > > > > gdb_byte ltag = aarch64_mte_get_ltag (fault_addr);
> > > > >
> > > > > if (!atag.has_value ())
> > > > > diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index
> > > > > e4bca6c6632..ba1dc3d5844 100644
> > > > > --- a/gdb/aarch64-tdep.c
> > > > > +++ b/gdb/aarch64-tdep.c
> > > > > @@ -4088,10 +4088,9 @@ aarch64_stack_frame_destroyed_p (struct
> > > > gdbarch
> > > > > *gdbarch, CORE_ADDR pc)
> > > > > return streq (inst.opcode->name, "ret"); }
> > > > >
> > > > > -/* AArch64 implementation of the remove_non_address_bits
> > > > > gdbarch
> > > > hook.
> > > > > Remove
> > > > > - non address bits from a pointer value. */
> > > > > +/* See aarch64-tdep.h. */
> > > > >
> > > > > -static CORE_ADDR
> > > > > +CORE_ADDR
> > > > > aarch64_remove_non_address_bits (struct gdbarch *gdbarch,
> > > CORE_ADDR
> > > > > pointer) {
> > > > > /* By default, we assume TBI and discard the top 8 bits plus
> > > > > the VA range @@ -4585,9 +4584,15 @@ aarch64_gdbarch_init (struct
> > > > gdbarch_info
> > > > > info, struct gdbarch_list *arches)
> > > > > tdep->ra_sign_state_regnum = ra_sign_state_offset +
> > > > > num_regs;
> > > > >
> > > > > /* Architecture hook to remove bits of a pointer that are not
> > > > > part of
> > the
> > > > > - address, like memory tags (MTE) and pointer authentication
> > > signatures.
> > > > > */
> > > > > - set_gdbarch_remove_non_address_bits (gdbarch,
> > > > > -
> aarch64_remove_non_address_bits);
> > > > > + address, like memory tags (MTE) and pointer authentication
> > > signatures.
> > > > > + Configure address adjustment for watch-, breakpoints and
> memory
> > > > > + transfer. */
> > > > > + set_gdbarch_remove_non_address_bits_watchpoint
> > > > > + (gdbarch, aarch64_remove_non_address_bits);
> > > > > + set_gdbarch_remove_non_address_bits_breakpoint
> > > > > + (gdbarch, aarch64_remove_non_address_bits);
> > > > > + set_gdbarch_remove_non_address_bits_memory
> > > > > + (gdbarch, aarch64_remove_non_address_bits);
> > > > >
> > > > > /* SME pseudo-registers. */
> > > > > if (tdep->has_sme ())
> > > > > diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h index
> > > > > 0e6024bfcbc..a9c8815f8be 100644
> > > > > --- a/gdb/aarch64-tdep.h
> > > > > +++ b/gdb/aarch64-tdep.h
> > > > > @@ -203,4 +203,10 @@ void aarch64_displaced_step_fixup (struct
> > > > > gdbarch *gdbarch,
> > > > >
> > > > > bool aarch64_displaced_step_hw_singlestep (struct gdbarch
> > > > > *gdbarch);
> > > > >
> > > > > +/* AArch64 implementation of the remove_non_address_bits
> > > > > +gdbarch
> > > > > hooks.
> > > > > + Remove non address bits from a pointer value. */
> > > > > +
> > > > > +CORE_ADDR aarch64_remove_non_address_bits (struct gdbarch
> > > *gdbarch,
> > > > > + CORE_ADDR pointer);
> > > > > +
> > > > > #endif /* aarch64-tdep.h */
> > > > > diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index
> > > > > a973518ac5f..8c2d9d247ec 100644
> > > > > --- a/gdb/breakpoint.c
> > > > > +++ b/gdb/breakpoint.c
> > > > > @@ -2238,7 +2238,8 @@ update_watchpoint (struct watchpoint *b,
> > > > > bool
> > > > > reparse)
> > > > > loc->gdbarch = v->type ()->arch ();
> > > > > loc->pspace = wp_pspace;
> > > > > loc->address
> > > > > - = gdbarch_remove_non_address_bits (loc-
> >gdbarch, addr);
> > > > > + = gdbarch_remove_non_address_bits_watchpoint
> (loc-
> > > > > >gdbarch,
> > > > > +
> addr);
> > > > > b->add_location (*loc);
> > > > >
> > > > > if (bitsize != 0)
> > > > > @@ -7477,7 +7478,7 @@ adjust_breakpoint_address (struct gdbarch
> > > > > *gdbarch,
> > > > > }
> > > > >
> > > > > adjusted_bpaddr
> > > > > - = gdbarch_remove_non_address_bits (gdbarch,
> adjusted_bpaddr);
> > > > > + = gdbarch_remove_non_address_bits_breakpoint (gdbarch,
> > > > > +adjusted_bpaddr);
> > > > >
> > > > > /* An adjusted breakpoint address can significantly alter
> > > > > a user's expectations. Print a warning if an adjustment diff
> > > > > --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h index
> > > > > b982fd7cd09..9fda85f860f
> > > > > 100644
> > > > > --- a/gdb/gdbarch-gen.h
> > > > > +++ b/gdb/gdbarch-gen.h
> > > > > @@ -684,19 +684,46 @@ extern CORE_ADDR
> > gdbarch_addr_bits_remove
> > > > > (struct gdbarch *gdbarch, CORE_ADDR ad extern void
> > > > > set_gdbarch_addr_bits_remove (struct gdbarch *gdbarch,
> > > > > gdbarch_addr_bits_remove_ftype *addr_bits_remove);
> > > > >
> > > > > /* On some architectures, not all bits of a pointer are significant.
> > > > > - On AArch64, for example, the top bits of a pointer may carry a
> "tag",
> > > > which
> > > > > - can be ignored by the kernel and the hardware. The "tag" can be
> > > > regarded
> > > > > as
> > > > > - additional data associated with the pointer, but it is not part of the
> > > > > address.
> > > > > + On AArch64 and amd64, for example, the top bits of a pointer
> > > > > + may carry
> > > > a
> > > > > + "tag", which can be ignored by the kernel and the hardware.
> > > > > + The
> > "tag"
> > > > > can be
> > > > > + regarded as additional data associated with the pointer, but
> > > > > + it is not
> > > part
> > > > > + of the address.
> > > > >
> > > > > Given a pointer for the architecture, this hook removes all the
> > > > > - non-significant bits and sign-extends things as needed. It gets used
> > to
> > > > > remove
> > > > > - non-address bits from data pointers (for example, removing the
> > > AArch64
> > > > > MTE tag
> > > > > - bits from a pointer) and from code pointers (removing the AArch64
> > PAC
> > > > > signature
> > > > > - from a pointer containing the return address). */
> > > > > -
> > > > > -typedef CORE_ADDR (gdbarch_remove_non_address_bits_ftype)
> > (struct
> > > > > gdbarch *gdbarch, CORE_ADDR pointer); -extern CORE_ADDR
> > > > > gdbarch_remove_non_address_bits (struct gdbarch *gdbarch,
> > > CORE_ADDR
> > > > > pointer); -extern void set_gdbarch_remove_non_address_bits
> > > > > (struct gdbarch *gdbarch, gdbarch_remove_non_address_bits_ftype
> > > > > *remove_non_address_bits);
> > > > > + non-significant bits and sign-extends things as needed. It
> > > > > + gets used
> > to
> > > > > + remove non-address bits from pointers used for watchpoints.
> > > > > + */
> > > > > +
> > > > > +typedef CORE_ADDR
> > > > > (gdbarch_remove_non_address_bits_watchpoint_ftype)
> > > > > +(struct gdbarch *gdbarch, CORE_ADDR pointer); extern CORE_ADDR
> > > > > +gdbarch_remove_non_address_bits_watchpoint (struct gdbarch
> > > > > +*gdbarch, CORE_ADDR pointer); extern void
> > > > > +set_gdbarch_remove_non_address_bits_watchpoint (struct gdbarch
> > > > > +*gdbarch, gdbarch_remove_non_address_bits_watchpoint_ftype
> > > > > +*remove_non_address_bits_watchpoint);
> > > > > +
> > > > > +/* On some architectures, not all bits of a pointer are significant.
> > > > > + On AArch64 and amd64, for example, the top bits of a pointer
> > > > > +may carry
> > > > a
> > > > > + "tag", which can be ignored by the kernel and the hardware.
> > > > > + The
> > "tag"
> > > > > can be
> > > > > + regarded as additional data associated with the pointer, but
> > > > > + it is not
> > > part
> > > > > + of the address.
> > > > > +
> > > > > + Given a pointer for the architecture, this hook removes all the
> > > > > + non-significant bits and sign-extends things as needed. It
> > > > > + gets used
> > to
> > > > > + remove non-address bits from pointers used for breakpoints.
> > > > > + */
> > > > > +
> > > > > +typedef CORE_ADDR
> > > > > (gdbarch_remove_non_address_bits_breakpoint_ftype)
> > > > > +(struct gdbarch *gdbarch, CORE_ADDR pointer); extern CORE_ADDR
> > > > > +gdbarch_remove_non_address_bits_breakpoint (struct gdbarch
> > > > > +*gdbarch, CORE_ADDR pointer); extern void
> > > > > +set_gdbarch_remove_non_address_bits_breakpoint (struct gdbarch
> > > > > +*gdbarch, gdbarch_remove_non_address_bits_breakpoint_ftype
> > > > > +*remove_non_address_bits_breakpoint);
> > > > > +
> > > > > +/* On some architectures, not all bits of a pointer are significant.
> > > > > + On AArch64 and amd64, for example, the top bits of a pointer
> > > > > +may carry
> > > > a
> > > > > + "tag", which can be ignored by the kernel and the hardware.
> > > > > + The
> > "tag"
> > > > > can be
> > > > > + regarded as additional data associated with the pointer, but
> > > > > + it is not
> > > part
> > > > > + of the address.
> > > > > +
> > > > > + Given a pointer for the architecture, this hook removes all the
> > > > > + non-significant bits and sign-extends things as needed. It
> > > > > + gets used
> > to
> > > > > + remove non-address bits from any pointer used to access memory.
> > > > > + */
> > > > > +
> > > > > +typedef CORE_ADDR
> > > (gdbarch_remove_non_address_bits_memory_ftype)
> > > > > +(struct gdbarch *gdbarch, CORE_ADDR pointer); extern CORE_ADDR
> > > > > +gdbarch_remove_non_address_bits_memory (struct gdbarch
> > *gdbarch,
> > > > > +CORE_ADDR pointer); extern void
> > > > > +set_gdbarch_remove_non_address_bits_memory (struct gdbarch
> > > > *gdbarch,
> > > > > +gdbarch_remove_non_address_bits_memory_ftype
> > > > > +*remove_non_address_bits_memory);
> > > > >
> > > > > /* Return a string representation of the memory tag TAG. */
> > > > >
> > > > > diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index
> > > > > 58e9ebbdc59..99a54a38d61
> > > > > 100644
> > > > > --- a/gdb/gdbarch.c
> > > > > +++ b/gdb/gdbarch.c
> > > > > @@ -143,7 +143,9 @@ struct gdbarch
> > > > > int frame_red_zone_size = 0;
> > > > > gdbarch_convert_from_func_ptr_addr_ftype
> > > > > *convert_from_func_ptr_addr =
> convert_from_func_ptr_addr_identity;
> > > > > gdbarch_addr_bits_remove_ftype *addr_bits_remove =
> > > > > core_addr_identity;
> > > > > - gdbarch_remove_non_address_bits_ftype
> > *remove_non_address_bits
> > > =
> > > > > default_remove_non_address_bits;
> > > > > + gdbarch_remove_non_address_bits_watchpoint_ftype
> > > > > + *remove_non_address_bits_watchpoint =
> > > > > default_remove_non_address_bits;
> > > > > + gdbarch_remove_non_address_bits_breakpoint_ftype
> > > > > + *remove_non_address_bits_breakpoint =
> > > > > default_remove_non_address_bits;
> > > > > + gdbarch_remove_non_address_bits_memory_ftype
> > > > > + *remove_non_address_bits_memory =
> > > > default_remove_non_address_bits;
> > > > > gdbarch_memtag_to_string_ftype *memtag_to_string =
> > > > > default_memtag_to_string;
> > > > > gdbarch_tagged_address_p_ftype *tagged_address_p =
> > > > > default_tagged_address_p;
> > > > > gdbarch_memtag_matches_p_ftype *memtag_matches_p =
> > > > > default_memtag_matches_p; @@ -407,7 +409,9 @@ verify_gdbarch
> > > (struct
> > > > > gdbarch *gdbarch)
> > > > > /* Skip verify of frame_red_zone_size, invalid_p == 0 */
> > > > > /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */
> > > > > /* Skip verify of addr_bits_remove, invalid_p == 0 */
> > > > > - /* Skip verify of remove_non_address_bits, invalid_p == 0 */
> > > > > + /* Skip verify of remove_non_address_bits_watchpoint,
> > > > > + invalid_p ==
> > > > > + 0 */
> > > > > + /* Skip verify of remove_non_address_bits_breakpoint,
> > > > > + invalid_p ==
> > > > > + 0 */
> > > > > + /* Skip verify of remove_non_address_bits_memory, invalid_p
> > > > > + ==
> > > > > + 0 */
> > > > > /* Skip verify of memtag_to_string, invalid_p == 0 */
> > > > > /* Skip verify of tagged_address_p, invalid_p == 0 */
> > > > > /* Skip verify of memtag_matches_p, invalid_p == 0 */ @@
> > > > > -910,8
> > > > > +914,14 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file
> > > > > +*file)
> > > > > "gdbarch_dump: addr_bits_remove = <%s>\n",
> > > > > host_address_to_string (gdbarch->addr_bits_remove));
> > > > > gdb_printf (file,
> > > > > - "gdbarch_dump: remove_non_address_bits = <%s>\n",
> > > > > - host_address_to_string (gdbarch-
> >remove_non_address_bits));
> > > > > + "gdbarch_dump: remove_non_address_bits_watchpoint =
> > > > > <%s>\n",
> > > > > + host_address_to_string
> > > > > +(gdbarch->remove_non_address_bits_watchpoint));
> > > > > + gdb_printf (file,
> > > > > + "gdbarch_dump: remove_non_address_bits_breakpoint =
> > > > > <%s>\n",
> > > > > + host_address_to_string
> > > > > +(gdbarch->remove_non_address_bits_breakpoint));
> > > > > + gdb_printf (file,
> > > > > + "gdbarch_dump: remove_non_address_bits_memory =
> <%s>\n",
> > > > > + host_address_to_string
> > > > > +(gdbarch->remove_non_address_bits_memory));
> > > > > gdb_printf (file,
> > > > > "gdbarch_dump: memtag_to_string = <%s>\n",
> > > > > host_address_to_string (gdbarch->memtag_to_string));
> @@
> > > > > -
> > > > > 3198,20 +3208,54 @@ set_gdbarch_addr_bits_remove (struct gdbarch
> > > > > *gdbarch, }
> > > > >
> > > > > CORE_ADDR
> > > > > -gdbarch_remove_non_address_bits (struct gdbarch *gdbarch,
> > > CORE_ADDR
> > > > > pointer)
> > > > > +gdbarch_remove_non_address_bits_watchpoint (struct gdbarch
> > > > > +*gdbarch, CORE_ADDR pointer) {
> > > > > + gdb_assert (gdbarch != NULL);
> > > > > + gdb_assert (gdbarch->remove_non_address_bits_watchpoint !=
> > > > > +NULL);
> > > > > + if (gdbarch_debug >= 2)
> > > > > + gdb_printf (gdb_stdlog,
> > > > > +"gdbarch_remove_non_address_bits_watchpoint
> > > > > +called\n");
> > > > > + return gdbarch->remove_non_address_bits_watchpoint (gdbarch,
> > > > > +pointer); }
> > > > > +
> > > > > +void
> > > > > +set_gdbarch_remove_non_address_bits_watchpoint (struct gdbarch
> > > > > *gdbarch,
> > > > > +
> > > > > gdbarch_remove_non_address_bits_watchpoint_ftype
> > > > > +remove_non_address_bits_watchpoint)
> > > > > +{
> > > > > + gdbarch->remove_non_address_bits_watchpoint =
> > > > > +remove_non_address_bits_watchpoint;
> > > > > +}
> > > > > +
> > > > > +CORE_ADDR
> > > > > +gdbarch_remove_non_address_bits_breakpoint (struct gdbarch
> > > > > +*gdbarch, CORE_ADDR pointer) {
> > > > > + gdb_assert (gdbarch != NULL);
> > > > > + gdb_assert (gdbarch->remove_non_address_bits_breakpoint !=
> > > > > +NULL);
> > > > > + if (gdbarch_debug >= 2)
> > > > > + gdb_printf (gdb_stdlog,
> > > > > +"gdbarch_remove_non_address_bits_breakpoint
> > > > > +called\n");
> > > > > + return gdbarch->remove_non_address_bits_breakpoint (gdbarch,
> > > > > +pointer); }
> > > > > +
> > > > > +void
> > > > > +set_gdbarch_remove_non_address_bits_breakpoint (struct gdbarch
> > > > > *gdbarch,
> > > > > +
> > > > > gdbarch_remove_non_address_bits_breakpoint_ftype
> > > > > +remove_non_address_bits_breakpoint)
> > > > > +{
> > > > > + gdbarch->remove_non_address_bits_breakpoint =
> > > > > +remove_non_address_bits_breakpoint;
> > > > > +}
> > > > > +
> > > > > +CORE_ADDR
> > > > > +gdbarch_remove_non_address_bits_memory (struct gdbarch
> > *gdbarch,
> > > > > +CORE_ADDR pointer)
> > > > > {
> > > > > gdb_assert (gdbarch != NULL);
> > > > > - gdb_assert (gdbarch->remove_non_address_bits != NULL);
> > > > > + gdb_assert (gdbarch->remove_non_address_bits_memory != NULL);
> > > > > if (gdbarch_debug >= 2)
> > > > > - gdb_printf (gdb_stdlog, "gdbarch_remove_non_address_bits
> > > called\n");
> > > > > - return gdbarch->remove_non_address_bits (gdbarch, pointer);
> > > > > + gdb_printf (gdb_stdlog,
> > > > > + "gdbarch_remove_non_address_bits_memory
> > > > > + called\n"); return gdbarch->remove_non_address_bits_memory
> > > > > + (gdbarch, pointer);
> > > > > }
> > > > >
> > > > > void
> > > > > -set_gdbarch_remove_non_address_bits (struct gdbarch *gdbarch,
> > > > > -
> gdbarch_remove_non_address_bits_ftype
> > > > > remove_non_address_bits)
> > > > > +set_gdbarch_remove_non_address_bits_memory (struct gdbarch
> > > > *gdbarch,
> > > > > +
> > > > > gdbarch_remove_non_address_bits_memory_ftype
> > > > > +remove_non_address_bits_memory)
> > > > > {
> > > > > - gdbarch->remove_non_address_bits = remove_non_address_bits;
> > > > > + gdbarch->remove_non_address_bits_memory =
> > > > > + remove_non_address_bits_memory;
> > > > > }
> > > > >
> > > > > std::string
> > > > > diff --git a/gdb/gdbarch_components.py
> > > > > b/gdb/gdbarch_components.py index 4006380076d..cc7c6d8677b
> > > > > 100644
> > > > > --- a/gdb/gdbarch_components.py
> > > > > +++ b/gdb/gdbarch_components.py
> > > > > @@ -1232,18 +1232,55 @@ possible it should be in
> TARGET_READ_PC
> > > > > instead).
> > > > > Method(
> > > > > comment="""
> > > > > On some architectures, not all bits of a pointer are significant.
> > > > > -On AArch64, for example, the top bits of a pointer may carry a
> > > > > "tag", which - can be ignored by the kernel and the hardware.
> > > > > The "tag" can be regarded as -additional data associated with
> > > > > the pointer, but it is not part of the address.
> > > > > +On AArch64 and amd64, for example, the top bits of a pointer
> > > > > +may carry a "tag", which can be ignored by the kernel and the
> hardware.
> > > > > +The "tag" can be regarded as additional data associated with
> > > > > +the pointer, but it is not part of the address.
> > > > >
> > > > > Given a pointer for the architecture, this hook removes all the
> > > > > -non- significant bits and sign-extends things as needed. It
> > > > > gets used to remove - non-address bits from data pointers (for
> > > > > example, removing the AArch64 MTE tag -bits from a pointer) and
> > > > > from code pointers (removing the AArch64 PAC signature -from a
> > > > > pointer containing the return
> > > > address).
> > > > > +non-significant bits and sign-extends things as needed. It
> > > > > +gets used to remove non-address bits from pointers used for
> watchpoints.
> > > > > """,
> > > > > type="CORE_ADDR",
> > > > > - name="remove_non_address_bits",
> > > > > + name="remove_non_address_bits_watchpoint",
> > > > > + params=[("CORE_ADDR", "pointer")],
> > > > > + predefault="default_remove_non_address_bits",
> > > > > + invalid=False,
> > > > > +)
> > > > > +
> > > > > +Method(
> > > > > + comment="""
> > > > > +On some architectures, not all bits of a pointer are significant.
> > > > > +On AArch64 and amd64, for example, the top bits of a pointer
> > > > > +may carry a "tag", which can be ignored by the kernel and the
> hardware.
> > > > > +The "tag" can be regarded as additional data associated with
> > > > > +the pointer, but it is not part of the address.
> > > > > +
> > > > > +Given a pointer for the architecture, this hook removes all the
> > > > > +non-significant bits and sign-extends things as needed. It
> > > > > +gets used to remove non-address bits from pointers used for
> breakpoints.
> > > > > +""",
> > > > > + type="CORE_ADDR",
> > > > > + name="remove_non_address_bits_breakpoint",
> > > > > + params=[("CORE_ADDR", "pointer")],
> > > > > + predefault="default_remove_non_address_bits",
> > > > > + invalid=False,
> > > > > +)
> > > > > +
> > > > > +Method(
> > > > > + comment="""
> > > > > +On some architectures, not all bits of a pointer are significant.
> > > > > +On AArch64 and amd64, for example, the top bits of a pointer
> > > > > +may carry a "tag", which can be ignored by the kernel and the
> hardware.
> > > > > +The "tag" can be regarded as additional data associated with
> > > > > +the pointer, but it is not part of the address.
> > > > > +
> > > > > +Given a pointer for the architecture, this hook removes all the
> > > > > +non-significant bits and sign-extends things as needed. It
> > > > > +gets used to remove non-address bits from any pointer used to
> > > > > +access
> > > memory.
> > > > > +""",
> > > > > + type="CORE_ADDR",
> > > > > + name="remove_non_address_bits_memory",
> > > > > params=[("CORE_ADDR", "pointer")],
> > > > > predefault="default_remove_non_address_bits",
> > > > > invalid=False,
> > > > > diff --git a/gdb/target.c b/gdb/target.c index
> > > > > 1b5aa11ed6f..b622de81e11
> > > > > 100644
> > > > > --- a/gdb/target.c
> > > > > +++ b/gdb/target.c
> > > > > @@ -1608,7 +1608,8 @@ memory_xfer_partial (struct target_ops
> > > > > *ops, enum target_object object,
> > > > > if (len == 0)
> > > > > return TARGET_XFER_EOF;
> > > > >
> > > > > - memaddr = gdbarch_remove_non_address_bits (current_inferior
> > > > > ()->arch (),
> > > > > + memaddr
> > > > > + = gdbarch_remove_non_address_bits_memory (current_inferior
> > > > > + ()->arch (),
> > > > > memaddr);
> > > > >
> > > > > /* Fill in READBUF with breakpoint shadows, or WRITEBUF with
> > > > > --
> > > > > 2.34.1
> > > > >
> > > > > Intel Deutschland GmbH
> > > > > Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
> > > > > Tel: +49 89 99 8853-0, www.intel.de Managing Directors: Sean
> > > > > Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva Chairperson
> > > > > of the Supervisory Board: Nicole Lau Registered
> > > > > Office: Munich Commercial Register: Amtsgericht Muenchen HRB
> > > > > 186928
> > > >
> > > > Kindly pinging for feedback.
> > > > Patch 2 of this series is already approved by Felix.
> > > >
> > > > BR,
> > > > Christina
> > >
> > > Kindly pinging!
> > >
> > > BR,
> > > Christina
> >
> > Kindly pinging.
>
> Kindly pinging.
>
> BR,
> Christina
Kindly pinging.
BR,
Christina
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
> -----Original Message-----
> From: Schimpe, Christina
> Sent: Friday, September 6, 2024 11:42 AM
> To: 'gdb-patches@sourceware.org' <gdb-patches@sourceware.org>
> Cc: Willgerodt, Felix <FeliX.Willgerodt@intel.com>; 'luis.machado@arm.com'
> <luis.machado@arm.com>; 'eliz@gnu.org' <eliz@gnu.org>
> Subject: RE: [PING*5][PATCH v5 1/2] gdb: Make tagged pointer support
> configurable.
>
> > -----Original Message-----
> > From: Schimpe, Christina
> > Sent: Thursday, August 29, 2024 3:26 PM
> > To: gdb-patches@sourceware.org
> > Cc: Willgerodt, Felix <FeliX.Willgerodt@intel.com>;
> > luis.machado@arm.com; eliz@gnu.org
> > Subject: RE: [PING*4][PATCH v5 1/2] gdb: Make tagged pointer support
> > configurable.
> >
> > > -----Original Message-----
> > > From: Schimpe, Christina
> > > Sent: Tuesday, August 20, 2024 3:06 PM
> > > To: 'gdb-patches@sourceware.org' <gdb-patches@sourceware.org>
> > > Cc: Willgerodt, Felix <FeliX.Willgerodt@intel.com>;
> > 'luis.machado@arm.com'
> > > <luis.machado@arm.com>; 'eliz@gnu.org' <eliz@gnu.org>
> > > Subject: RE: [PING*3][PATCH v5 1/2] gdb: Make tagged pointer support
> > > configurable.
> > >
> > > > -----Original Message-----
> > > > From: Schimpe, Christina
> > > > Sent: Monday, August 12, 2024 10:42 AM
> > > > To: 'gdb-patches@sourceware.org' <gdb-patches@sourceware.org>
> > > > Cc: Willgerodt, Felix <FeliX.Willgerodt@intel.com>;
> > > 'luis.machado@arm.com'
> > > > <luis.machado@arm.com>; 'eliz@gnu.org' <eliz@gnu.org>
> > > > Subject: RE: [PING*2][PATCH v5 1/2] gdb: Make tagged pointer
> > > > support configurable.
> > > >
> > > > > > -----Original Message-----
> > > > > > From: Schimpe, Christina <christina.schimpe@intel.com>
> > > > > > Sent: Tuesday, July 9, 2024 2:17 PM
> > > > > > To: gdb-patches@sourceware.org
> > > > > > Cc: Willgerodt, Felix <felix.willgerodt@intel.com>;
> > > > > > luis.machado@arm.com; eliz@gnu.org
> > > > > > Subject: [PATCH v5 1/2] gdb: Make tagged pointer support
> > configurable.
> > > > > >
> > > > > > From: Christina Schimpe <christina.schimpe@intel.com>
> > > > > >
> > > > > > The gdbarch function gdbarch_remove_non_address_bits adjusts
> > > > > addresses
> > > > > > to enable debugging of programs with tagged pointers on Linux,
> > > > > > for instance for ARM's feature top byte ignore (TBI).
> > > > > > Once the function is implemented for an architecture, it
> > > > > > adjusts addresses for memory access, breakpoints and watchpoints.
> > > > > >
> > > > > > Linear address masking (LAM) is Intel's (R) implementation of
> > > > > > tagged pointer support. It requires certain adaptions to
> > > > > > GDB's tagged pointer support due to the following:
> > > > > > - LAM supports address tagging for data accesses only. Thus,
> > specifying
> > > > > > breakpoints on tagged addresses is not a valid use case.
> > > > > > - In contrast to the implementation for ARM's TBI, the Linux
> > > > > > kernel
> > > > supports
> > > > > > tagged pointers for memory access.
> > > > > >
> > > > > > This patch makes GDB's tagged pointer support configurable
> > > > > > such that it is possible to enable the address adjustment for
> > > > > > a specific feature only (e.g memory access, breakpoints or
> > > > > > watchpoints). This way, one can make sure that addresses are
> > > > > > only adjusted when necessary. In case of LAM, this avoids
> > > > > > unnecessary parsing of the /proc/<pid>/status file
> > > > > to get the untag mask.
> > > > > >
> > > > > > Reviewed-By: Felix Willgerodt <felix.willgerodt@intel.com>
> > > > > > ---
> > > > > > gdb/aarch64-linux-nat.c | 2 +-
> > > > > > gdb/aarch64-linux-tdep.c | 13 ++++----
> > > > > > gdb/aarch64-tdep.c | 17 ++++++----
> > > > > > gdb/aarch64-tdep.h | 6 ++++
> > > > > > gdb/breakpoint.c | 5 +--
> > > > > > gdb/gdbarch-gen.h | 49 ++++++++++++++++++++++-------
> > > > > > gdb/gdbarch.c | 66 ++++++++++++++++++++++++++++++++----
> --
> > -
> > > > > > gdb/gdbarch_components.py | 53 ++++++++++++++++++++++++++---
> --
> > > > > > gdb/target.c | 3 +-
> > > > > > 9 files changed, 168 insertions(+), 46 deletions(-)
> > > > > >
> > > > > > diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
> > > > > > index 2e6541f53c3..dac42b4f48b 100644
> > > > > > --- a/gdb/aarch64-linux-nat.c
> > > > > > +++ b/gdb/aarch64-linux-nat.c
> > > > > > @@ -945,7 +945,7 @@
> > > aarch64_linux_nat_target::stopped_data_address
> > > > > > (CORE_ADDR *addr_p)
> > > > > > kernel can potentially be tagged addresses. */
> > > > > > struct gdbarch *gdbarch = thread_architecture (inferior_ptid);
> > > > > > const CORE_ADDR addr_trap
> > > > > > - = gdbarch_remove_non_address_bits (gdbarch, (CORE_ADDR)
> > > > > > siginfo.si_addr);
> > > > > > + = aarch64_remove_non_address_bits (gdbarch, (CORE_ADDR)
> > > > > > + siginfo.si_addr);
> > > > > >
> > > > > > /* Check if the address matches any watched address. */
> > > > > > state = aarch64_get_debug_reg_state (inferior_ptid.pid ());
> > > > > > diff --git a/gdb/aarch64-linux-tdep.c
> > > > > > b/gdb/aarch64-linux-tdep.c index a1296a8f0c7..bf5ce72aa5f
> > > > > > 100644
> > > > > > --- a/gdb/aarch64-linux-tdep.c
> > > > > > +++ b/gdb/aarch64-linux-tdep.c
> > > > > > @@ -2456,7 +2456,7 @@ static bool
> > > > > > aarch64_linux_tagged_address_p (struct gdbarch *gdbarch,
> > > > > > CORE_ADDR
> > > > > > address) {
> > > > > > /* Remove the top byte for the memory range check. */
> > > > > > - address = gdbarch_remove_non_address_bits (gdbarch,
> > > > > > address);
> > > > > > + address = aarch64_remove_non_address_bits (gdbarch,
> > > > > > + address);
> > > > > >
> > > > > > /* Check if the page that contains ADDRESS is mapped with
> > > PROT_MTE.
> > > > > */
> > > > > > if (!linux_address_in_memtag_page (address)) @@ -2478,7
> > > > > > +2478,7 @@ aarch64_linux_memtag_matches_p (struct gdbarch
> > > > > > *gdbarch,
> > > > > >
> > > > > > /* Fetch the allocation tag for ADDRESS. */
> > > > > > std::optional<CORE_ADDR> atag
> > > > > > - = aarch64_mte_get_atag (gdbarch_remove_non_address_bits
> > > > (gdbarch,
> > > > > > addr));
> > > > > > + = aarch64_mte_get_atag (aarch64_remove_non_address_bits
> > > > > > + (gdbarch, addr));
> > > > > >
> > > > > > if (!atag.has_value ())
> > > > > > return true;
> > > > > > @@ -2517,7 +2517,7 @@ aarch64_linux_set_memtags (struct
> > > > > > gdbarch *gdbarch, struct value *address,
> > > > > > else
> > > > > > {
> > > > > > /* Remove the top byte. */
> > > > > > - addr = gdbarch_remove_non_address_bits (gdbarch, addr);
> > > > > > + addr = aarch64_remove_non_address_bits (gdbarch, addr);
> > > > > >
> > > > > > /* With G being the number of tag granules and N the
> > > > > > number of
> > > > tags
> > > > > > passed in, we can have the following cases:
> > > > > > @@ -2566,7 +2566,7 @@ aarch64_linux_get_memtag (struct
> gdbarch
> > > > > > *gdbarch, struct value *address,
> > > > > > else
> > > > > > {
> > > > > > /* Remove the top byte. */
> > > > > > - addr = gdbarch_remove_non_address_bits (gdbarch, addr);
> > > > > > + addr = aarch64_remove_non_address_bits (gdbarch, addr);
> > > > > > std::optional<CORE_ADDR> atag = aarch64_mte_get_atag
> > > > > > (addr);
> > > > > >
> > > > > > if (!atag.has_value ()) @@ -2640,8 +2640,9 @@
> > > > > > aarch64_linux_report_signal_info (struct gdbarch *gdbarch,
> > > > > > uiout->text ("\n");
> > > > > >
> > > > > > std::optional<CORE_ADDR> atag
> > > > > > - = aarch64_mte_get_atag (gdbarch_remove_non_address_bits
> > > > > > (gdbarch,
> > > > > > -
> > fault_addr));
> > > > > > + = aarch64_mte_get_atag (
> > > > > > + aarch64_remove_non_address_bits (gdbarch, fault_addr));
> > > > > > +
> > > > > > gdb_byte ltag = aarch64_mte_get_ltag (fault_addr);
> > > > > >
> > > > > > if (!atag.has_value ()) diff --git a/gdb/aarch64-tdep.c
> > > > > > b/gdb/aarch64-tdep.c index
> > > > > > e4bca6c6632..ba1dc3d5844 100644
> > > > > > --- a/gdb/aarch64-tdep.c
> > > > > > +++ b/gdb/aarch64-tdep.c
> > > > > > @@ -4088,10 +4088,9 @@ aarch64_stack_frame_destroyed_p
> (struct
> > > > > gdbarch
> > > > > > *gdbarch, CORE_ADDR pc)
> > > > > > return streq (inst.opcode->name, "ret"); }
> > > > > >
> > > > > > -/* AArch64 implementation of the remove_non_address_bits
> > > > > > gdbarch
> > > > > hook.
> > > > > > Remove
> > > > > > - non address bits from a pointer value. */
> > > > > > +/* See aarch64-tdep.h. */
> > > > > >
> > > > > > -static CORE_ADDR
> > > > > > +CORE_ADDR
> > > > > > aarch64_remove_non_address_bits (struct gdbarch *gdbarch,
> > > > CORE_ADDR
> > > > > > pointer) {
> > > > > > /* By default, we assume TBI and discard the top 8 bits
> > > > > > plus the VA range @@ -4585,9 +4584,15 @@ aarch64_gdbarch_init
> > > > > > (struct
> > > > > gdbarch_info
> > > > > > info, struct gdbarch_list *arches)
> > > > > > tdep->ra_sign_state_regnum = ra_sign_state_offset +
> > > > > > num_regs;
> > > > > >
> > > > > > /* Architecture hook to remove bits of a pointer that are
> > > > > > not part of
> > > the
> > > > > > - address, like memory tags (MTE) and pointer authentication
> > > > signatures.
> > > > > > */
> > > > > > - set_gdbarch_remove_non_address_bits (gdbarch,
> > > > > > -
> > aarch64_remove_non_address_bits);
> > > > > > + address, like memory tags (MTE) and pointer
> > > > > > + authentication
> > > > signatures.
> > > > > > + Configure address adjustment for watch-, breakpoints and
> > memory
> > > > > > + transfer. */
> > > > > > + set_gdbarch_remove_non_address_bits_watchpoint
> > > > > > + (gdbarch, aarch64_remove_non_address_bits);
> > > > > > + set_gdbarch_remove_non_address_bits_breakpoint
> > > > > > + (gdbarch, aarch64_remove_non_address_bits);
> > > > > > + set_gdbarch_remove_non_address_bits_memory
> > > > > > + (gdbarch, aarch64_remove_non_address_bits);
> > > > > >
> > > > > > /* SME pseudo-registers. */
> > > > > > if (tdep->has_sme ())
> > > > > > diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h index
> > > > > > 0e6024bfcbc..a9c8815f8be 100644
> > > > > > --- a/gdb/aarch64-tdep.h
> > > > > > +++ b/gdb/aarch64-tdep.h
> > > > > > @@ -203,4 +203,10 @@ void aarch64_displaced_step_fixup (struct
> > > > > > gdbarch *gdbarch,
> > > > > >
> > > > > > bool aarch64_displaced_step_hw_singlestep (struct gdbarch
> > > > > > *gdbarch);
> > > > > >
> > > > > > +/* AArch64 implementation of the remove_non_address_bits
> > > > > > +gdbarch
> > > > > > hooks.
> > > > > > + Remove non address bits from a pointer value. */
> > > > > > +
> > > > > > +CORE_ADDR aarch64_remove_non_address_bits (struct gdbarch
> > > > *gdbarch,
> > > > > > + CORE_ADDR pointer);
> > > > > > +
> > > > > > #endif /* aarch64-tdep.h */
> > > > > > diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index
> > > > > > a973518ac5f..8c2d9d247ec 100644
> > > > > > --- a/gdb/breakpoint.c
> > > > > > +++ b/gdb/breakpoint.c
> > > > > > @@ -2238,7 +2238,8 @@ update_watchpoint (struct watchpoint *b,
> > > > > > bool
> > > > > > reparse)
> > > > > > loc->gdbarch = v->type ()->arch ();
> > > > > > loc->pspace = wp_pspace;
> > > > > > loc->address
> > > > > > - = gdbarch_remove_non_address_bits (loc-
> > >gdbarch, addr);
> > > > > > + = gdbarch_remove_non_address_bits_watchpoint
> > (loc-
> > > > > > >gdbarch,
> > > > > > +
> > addr);
> > > > > > b->add_location (*loc);
> > > > > >
> > > > > > if (bitsize != 0)
> > > > > > @@ -7477,7 +7478,7 @@ adjust_breakpoint_address (struct
> > > > > > gdbarch *gdbarch,
> > > > > > }
> > > > > >
> > > > > > adjusted_bpaddr
> > > > > > - = gdbarch_remove_non_address_bits (gdbarch,
> > adjusted_bpaddr);
> > > > > > + = gdbarch_remove_non_address_bits_breakpoint (gdbarch,
> > > > > > +adjusted_bpaddr);
> > > > > >
> > > > > > /* An adjusted breakpoint address can significantly alter
> > > > > > a user's expectations. Print a warning if an adjustment
> > > > > > diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h index
> > > > > > b982fd7cd09..9fda85f860f
> > > > > > 100644
> > > > > > --- a/gdb/gdbarch-gen.h
> > > > > > +++ b/gdb/gdbarch-gen.h
> > > > > > @@ -684,19 +684,46 @@ extern CORE_ADDR
> > > gdbarch_addr_bits_remove
> > > > > > (struct gdbarch *gdbarch, CORE_ADDR ad extern void
> > > > > > set_gdbarch_addr_bits_remove (struct gdbarch *gdbarch,
> > > > > > gdbarch_addr_bits_remove_ftype *addr_bits_remove);
> > > > > >
> > > > > > /* On some architectures, not all bits of a pointer are significant.
> > > > > > - On AArch64, for example, the top bits of a pointer may carry a
> > "tag",
> > > > > which
> > > > > > - can be ignored by the kernel and the hardware. The "tag" can be
> > > > > regarded
> > > > > > as
> > > > > > - additional data associated with the pointer, but it is not part of
> the
> > > > > > address.
> > > > > > + On AArch64 and amd64, for example, the top bits of a
> > > > > > + pointer may carry
> > > > > a
> > > > > > + "tag", which can be ignored by the kernel and the hardware.
> > > > > > + The
> > > "tag"
> > > > > > can be
> > > > > > + regarded as additional data associated with the pointer,
> > > > > > + but it is not
> > > > part
> > > > > > + of the address.
> > > > > >
> > > > > > Given a pointer for the architecture, this hook removes all the
> > > > > > - non-significant bits and sign-extends things as needed. It gets
> used
> > > to
> > > > > > remove
> > > > > > - non-address bits from data pointers (for example, removing the
> > > > AArch64
> > > > > > MTE tag
> > > > > > - bits from a pointer) and from code pointers (removing the
> AArch64
> > > PAC
> > > > > > signature
> > > > > > - from a pointer containing the return address). */
> > > > > > -
> > > > > > -typedef CORE_ADDR (gdbarch_remove_non_address_bits_ftype)
> > > (struct
> > > > > > gdbarch *gdbarch, CORE_ADDR pointer); -extern CORE_ADDR
> > > > > > gdbarch_remove_non_address_bits (struct gdbarch *gdbarch,
> > > > CORE_ADDR
> > > > > > pointer); -extern void set_gdbarch_remove_non_address_bits
> > > > > > (struct gdbarch *gdbarch,
> > > > > > gdbarch_remove_non_address_bits_ftype
> > > > > > *remove_non_address_bits);
> > > > > > + non-significant bits and sign-extends things as needed.
> > > > > > + It gets used
> > > to
> > > > > > + remove non-address bits from pointers used for watchpoints.
> > > > > > + */
> > > > > > +
> > > > > > +typedef CORE_ADDR
> > > > > > (gdbarch_remove_non_address_bits_watchpoint_ftype)
> > > > > > +(struct gdbarch *gdbarch, CORE_ADDR pointer); extern
> > > > > > +CORE_ADDR gdbarch_remove_non_address_bits_watchpoint
> (struct
> > > > > > +gdbarch *gdbarch, CORE_ADDR pointer); extern void
> > > > > > +set_gdbarch_remove_non_address_bits_watchpoint (struct
> > > > > > +gdbarch *gdbarch,
> > > > > > +gdbarch_remove_non_address_bits_watchpoint_ftype
> > > > > > +*remove_non_address_bits_watchpoint);
> > > > > > +
> > > > > > +/* On some architectures, not all bits of a pointer are significant.
> > > > > > + On AArch64 and amd64, for example, the top bits of a
> > > > > > +pointer may carry
> > > > > a
> > > > > > + "tag", which can be ignored by the kernel and the hardware.
> > > > > > + The
> > > "tag"
> > > > > > can be
> > > > > > + regarded as additional data associated with the pointer,
> > > > > > + but it is not
> > > > part
> > > > > > + of the address.
> > > > > > +
> > > > > > + Given a pointer for the architecture, this hook removes all the
> > > > > > + non-significant bits and sign-extends things as needed.
> > > > > > + It gets used
> > > to
> > > > > > + remove non-address bits from pointers used for breakpoints.
> > > > > > + */
> > > > > > +
> > > > > > +typedef CORE_ADDR
> > > > > > (gdbarch_remove_non_address_bits_breakpoint_ftype)
> > > > > > +(struct gdbarch *gdbarch, CORE_ADDR pointer); extern
> > > > > > +CORE_ADDR gdbarch_remove_non_address_bits_breakpoint
> (struct
> > > > > > +gdbarch *gdbarch, CORE_ADDR pointer); extern void
> > > > > > +set_gdbarch_remove_non_address_bits_breakpoint (struct
> > > > > > +gdbarch *gdbarch,
> > > > > > +gdbarch_remove_non_address_bits_breakpoint_ftype
> > > > > > +*remove_non_address_bits_breakpoint);
> > > > > > +
> > > > > > +/* On some architectures, not all bits of a pointer are significant.
> > > > > > + On AArch64 and amd64, for example, the top bits of a
> > > > > > +pointer may carry
> > > > > a
> > > > > > + "tag", which can be ignored by the kernel and the hardware.
> > > > > > + The
> > > "tag"
> > > > > > can be
> > > > > > + regarded as additional data associated with the pointer,
> > > > > > + but it is not
> > > > part
> > > > > > + of the address.
> > > > > > +
> > > > > > + Given a pointer for the architecture, this hook removes all the
> > > > > > + non-significant bits and sign-extends things as needed.
> > > > > > + It gets used
> > > to
> > > > > > + remove non-address bits from any pointer used to access
> memory.
> > > > > > + */
> > > > > > +
> > > > > > +typedef CORE_ADDR
> > > > (gdbarch_remove_non_address_bits_memory_ftype)
> > > > > > +(struct gdbarch *gdbarch, CORE_ADDR pointer); extern
> > > > > > +CORE_ADDR gdbarch_remove_non_address_bits_memory (struct
> > > > > > +gdbarch
> > > *gdbarch,
> > > > > > +CORE_ADDR pointer); extern void
> > > > > > +set_gdbarch_remove_non_address_bits_memory (struct gdbarch
> > > > > *gdbarch,
> > > > > > +gdbarch_remove_non_address_bits_memory_ftype
> > > > > > +*remove_non_address_bits_memory);
> > > > > >
> > > > > > /* Return a string representation of the memory tag TAG. */
> > > > > >
> > > > > > diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index
> > > > > > 58e9ebbdc59..99a54a38d61
> > > > > > 100644
> > > > > > --- a/gdb/gdbarch.c
> > > > > > +++ b/gdb/gdbarch.c
> > > > > > @@ -143,7 +143,9 @@ struct gdbarch
> > > > > > int frame_red_zone_size = 0;
> > > > > > gdbarch_convert_from_func_ptr_addr_ftype
> > > > > > *convert_from_func_ptr_addr =
> > convert_from_func_ptr_addr_identity;
> > > > > > gdbarch_addr_bits_remove_ftype *addr_bits_remove =
> > > > > > core_addr_identity;
> > > > > > - gdbarch_remove_non_address_bits_ftype
> > > *remove_non_address_bits
> > > > =
> > > > > > default_remove_non_address_bits;
> > > > > > + gdbarch_remove_non_address_bits_watchpoint_ftype
> > > > > > + *remove_non_address_bits_watchpoint =
> > > > > > default_remove_non_address_bits;
> > > > > > + gdbarch_remove_non_address_bits_breakpoint_ftype
> > > > > > + *remove_non_address_bits_breakpoint =
> > > > > > default_remove_non_address_bits;
> > > > > > + gdbarch_remove_non_address_bits_memory_ftype
> > > > > > + *remove_non_address_bits_memory =
> > > > > default_remove_non_address_bits;
> > > > > > gdbarch_memtag_to_string_ftype *memtag_to_string =
> > > > > > default_memtag_to_string;
> > > > > > gdbarch_tagged_address_p_ftype *tagged_address_p =
> > > > > > default_tagged_address_p;
> > > > > > gdbarch_memtag_matches_p_ftype *memtag_matches_p =
> > > > > > default_memtag_matches_p; @@ -407,7 +409,9 @@ verify_gdbarch
> > > > (struct
> > > > > > gdbarch *gdbarch)
> > > > > > /* Skip verify of frame_red_zone_size, invalid_p == 0 */
> > > > > > /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */
> > > > > > /* Skip verify of addr_bits_remove, invalid_p == 0 */
> > > > > > - /* Skip verify of remove_non_address_bits, invalid_p == 0
> > > > > > */
> > > > > > + /* Skip verify of remove_non_address_bits_watchpoint,
> > > > > > + invalid_p ==
> > > > > > + 0 */
> > > > > > + /* Skip verify of remove_non_address_bits_breakpoint,
> > > > > > + invalid_p ==
> > > > > > + 0 */
> > > > > > + /* Skip verify of remove_non_address_bits_memory, invalid_p
> > > > > > + ==
> > > > > > + 0 */
> > > > > > /* Skip verify of memtag_to_string, invalid_p == 0 */
> > > > > > /* Skip verify of tagged_address_p, invalid_p == 0 */
> > > > > > /* Skip verify of memtag_matches_p, invalid_p == 0 */ @@
> > > > > > -910,8
> > > > > > +914,14 @@ gdbarch_dump (struct gdbarch *gdbarch, struct
> > > > > > +ui_file
> > > > > > +*file)
> > > > > > "gdbarch_dump: addr_bits_remove = <%s>\n",
> > > > > > host_address_to_string (gdbarch->addr_bits_remove));
> > > > > > gdb_printf (file,
> > > > > > - "gdbarch_dump: remove_non_address_bits = <%s>\n",
> > > > > > - host_address_to_string (gdbarch-
> > >remove_non_address_bits));
> > > > > > + "gdbarch_dump: remove_non_address_bits_watchpoint =
> > > > > > <%s>\n",
> > > > > > + host_address_to_string
> > > > > > +(gdbarch->remove_non_address_bits_watchpoint));
> > > > > > + gdb_printf (file,
> > > > > > + "gdbarch_dump: remove_non_address_bits_breakpoint =
> > > > > > <%s>\n",
> > > > > > + host_address_to_string
> > > > > > +(gdbarch->remove_non_address_bits_breakpoint));
> > > > > > + gdb_printf (file,
> > > > > > + "gdbarch_dump: remove_non_address_bits_memory =
> > <%s>\n",
> > > > > > + host_address_to_string
> > > > > > +(gdbarch->remove_non_address_bits_memory));
> > > > > > gdb_printf (file,
> > > > > > "gdbarch_dump: memtag_to_string = <%s>\n",
> > > > > > host_address_to_string (gdbarch->memtag_to_string));
> > @@
> > > > > > -
> > > > > > 3198,20 +3208,54 @@ set_gdbarch_addr_bits_remove (struct
> > > > > > gdbarch *gdbarch, }
> > > > > >
> > > > > > CORE_ADDR
> > > > > > -gdbarch_remove_non_address_bits (struct gdbarch *gdbarch,
> > > > CORE_ADDR
> > > > > > pointer)
> > > > > > +gdbarch_remove_non_address_bits_watchpoint (struct gdbarch
> > > > > > +*gdbarch, CORE_ADDR pointer) {
> > > > > > + gdb_assert (gdbarch != NULL);
> > > > > > + gdb_assert (gdbarch->remove_non_address_bits_watchpoint !=
> > > > > > +NULL);
> > > > > > + if (gdbarch_debug >= 2)
> > > > > > + gdb_printf (gdb_stdlog,
> > > > > > +"gdbarch_remove_non_address_bits_watchpoint
> > > > > > +called\n");
> > > > > > + return gdbarch->remove_non_address_bits_watchpoint
> > > > > > +(gdbarch, pointer); }
> > > > > > +
> > > > > > +void
> > > > > > +set_gdbarch_remove_non_address_bits_watchpoint (struct
> > > > > > +gdbarch
> > > > > > *gdbarch,
> > > > > > +
> > > > > > gdbarch_remove_non_address_bits_watchpoint_ftype
> > > > > > +remove_non_address_bits_watchpoint)
> > > > > > +{
> > > > > > + gdbarch->remove_non_address_bits_watchpoint =
> > > > > > +remove_non_address_bits_watchpoint;
> > > > > > +}
> > > > > > +
> > > > > > +CORE_ADDR
> > > > > > +gdbarch_remove_non_address_bits_breakpoint (struct gdbarch
> > > > > > +*gdbarch, CORE_ADDR pointer) {
> > > > > > + gdb_assert (gdbarch != NULL);
> > > > > > + gdb_assert (gdbarch->remove_non_address_bits_breakpoint !=
> > > > > > +NULL);
> > > > > > + if (gdbarch_debug >= 2)
> > > > > > + gdb_printf (gdb_stdlog,
> > > > > > +"gdbarch_remove_non_address_bits_breakpoint
> > > > > > +called\n");
> > > > > > + return gdbarch->remove_non_address_bits_breakpoint
> > > > > > +(gdbarch, pointer); }
> > > > > > +
> > > > > > +void
> > > > > > +set_gdbarch_remove_non_address_bits_breakpoint (struct
> > > > > > +gdbarch
> > > > > > *gdbarch,
> > > > > > +
> > > > > > gdbarch_remove_non_address_bits_breakpoint_ftype
> > > > > > +remove_non_address_bits_breakpoint)
> > > > > > +{
> > > > > > + gdbarch->remove_non_address_bits_breakpoint =
> > > > > > +remove_non_address_bits_breakpoint;
> > > > > > +}
> > > > > > +
> > > > > > +CORE_ADDR
> > > > > > +gdbarch_remove_non_address_bits_memory (struct gdbarch
> > > *gdbarch,
> > > > > > +CORE_ADDR pointer)
> > > > > > {
> > > > > > gdb_assert (gdbarch != NULL);
> > > > > > - gdb_assert (gdbarch->remove_non_address_bits != NULL);
> > > > > > + gdb_assert (gdbarch->remove_non_address_bits_memory !=
> > > > > > + NULL);
> > > > > > if (gdbarch_debug >= 2)
> > > > > > - gdb_printf (gdb_stdlog, "gdbarch_remove_non_address_bits
> > > > called\n");
> > > > > > - return gdbarch->remove_non_address_bits (gdbarch, pointer);
> > > > > > + gdb_printf (gdb_stdlog,
> > > > > > + "gdbarch_remove_non_address_bits_memory
> > > > > > + called\n"); return gdbarch->remove_non_address_bits_memory
> > > > > > + (gdbarch, pointer);
> > > > > > }
> > > > > >
> > > > > > void
> > > > > > -set_gdbarch_remove_non_address_bits (struct gdbarch *gdbarch,
> > > > > > -
> > gdbarch_remove_non_address_bits_ftype
> > > > > > remove_non_address_bits)
> > > > > > +set_gdbarch_remove_non_address_bits_memory (struct gdbarch
> > > > > *gdbarch,
> > > > > > +
> > > > > > gdbarch_remove_non_address_bits_memory_ftype
> > > > > > +remove_non_address_bits_memory)
> > > > > > {
> > > > > > - gdbarch->remove_non_address_bits = remove_non_address_bits;
> > > > > > + gdbarch->remove_non_address_bits_memory =
> > > > > > + remove_non_address_bits_memory;
> > > > > > }
> > > > > >
> > > > > > std::string
> > > > > > diff --git a/gdb/gdbarch_components.py
> > > > > > b/gdb/gdbarch_components.py index 4006380076d..cc7c6d8677b
> > > > > > 100644
> > > > > > --- a/gdb/gdbarch_components.py
> > > > > > +++ b/gdb/gdbarch_components.py
> > > > > > @@ -1232,18 +1232,55 @@ possible it should be in
> > TARGET_READ_PC
> > > > > > instead).
> > > > > > Method(
> > > > > > comment="""
> > > > > > On some architectures, not all bits of a pointer are significant.
> > > > > > -On AArch64, for example, the top bits of a pointer may carry
> > > > > > a "tag", which - can be ignored by the kernel and the hardware.
> > > > > > The "tag" can be regarded as -additional data associated with
> > > > > > the pointer, but it is not part of the address.
> > > > > > +On AArch64 and amd64, for example, the top bits of a pointer
> > > > > > +may carry a "tag", which can be ignored by the kernel and the
> > hardware.
> > > > > > +The "tag" can be regarded as additional data associated with
> > > > > > +the pointer, but it is not part of the address.
> > > > > >
> > > > > > Given a pointer for the architecture, this hook removes all
> > > > > > the
> > > > > > -non- significant bits and sign-extends things as needed. It
> > > > > > gets used to remove - non-address bits from data pointers (for
> > > > > > example, removing the AArch64 MTE tag -bits from a pointer)
> > > > > > and from code pointers (removing the AArch64 PAC signature
> > > > > > -from a pointer containing the return
> > > > > address).
> > > > > > +non-significant bits and sign-extends things as needed. It
> > > > > > +gets used to remove non-address bits from pointers used for
> > watchpoints.
> > > > > > """,
> > > > > > type="CORE_ADDR",
> > > > > > - name="remove_non_address_bits",
> > > > > > + name="remove_non_address_bits_watchpoint",
> > > > > > + params=[("CORE_ADDR", "pointer")],
> > > > > > + predefault="default_remove_non_address_bits",
> > > > > > + invalid=False,
> > > > > > +)
> > > > > > +
> > > > > > +Method(
> > > > > > + comment="""
> > > > > > +On some architectures, not all bits of a pointer are significant.
> > > > > > +On AArch64 and amd64, for example, the top bits of a pointer
> > > > > > +may carry a "tag", which can be ignored by the kernel and the
> > hardware.
> > > > > > +The "tag" can be regarded as additional data associated with
> > > > > > +the pointer, but it is not part of the address.
> > > > > > +
> > > > > > +Given a pointer for the architecture, this hook removes all
> > > > > > +the non-significant bits and sign-extends things as needed.
> > > > > > +It gets used to remove non-address bits from pointers used
> > > > > > +for
> > breakpoints.
> > > > > > +""",
> > > > > > + type="CORE_ADDR",
> > > > > > + name="remove_non_address_bits_breakpoint",
> > > > > > + params=[("CORE_ADDR", "pointer")],
> > > > > > + predefault="default_remove_non_address_bits",
> > > > > > + invalid=False,
> > > > > > +)
> > > > > > +
> > > > > > +Method(
> > > > > > + comment="""
> > > > > > +On some architectures, not all bits of a pointer are significant.
> > > > > > +On AArch64 and amd64, for example, the top bits of a pointer
> > > > > > +may carry a "tag", which can be ignored by the kernel and the
> > hardware.
> > > > > > +The "tag" can be regarded as additional data associated with
> > > > > > +the pointer, but it is not part of the address.
> > > > > > +
> > > > > > +Given a pointer for the architecture, this hook removes all
> > > > > > +the non-significant bits and sign-extends things as needed.
> > > > > > +It gets used to remove non-address bits from any pointer used
> > > > > > +to access
> > > > memory.
> > > > > > +""",
> > > > > > + type="CORE_ADDR",
> > > > > > + name="remove_non_address_bits_memory",
> > > > > > params=[("CORE_ADDR", "pointer")],
> > > > > > predefault="default_remove_non_address_bits",
> > > > > > invalid=False,
> > > > > > diff --git a/gdb/target.c b/gdb/target.c index
> > > > > > 1b5aa11ed6f..b622de81e11
> > > > > > 100644
> > > > > > --- a/gdb/target.c
> > > > > > +++ b/gdb/target.c
> > > > > > @@ -1608,7 +1608,8 @@ memory_xfer_partial (struct target_ops
> > > > > > *ops, enum target_object object,
> > > > > > if (len == 0)
> > > > > > return TARGET_XFER_EOF;
> > > > > >
> > > > > > - memaddr = gdbarch_remove_non_address_bits (current_inferior
> > > > > > ()->arch (),
> > > > > > + memaddr
> > > > > > + = gdbarch_remove_non_address_bits_memory (current_inferior
> > > > > > + ()->arch (),
> > > > > > memaddr);
> > > > > >
> > > > > > /* Fill in READBUF with breakpoint shadows, or WRITEBUF
> > > > > > with
> > > > > > --
> > > > > > 2.34.1
> > > > > >
> > > > > > Intel Deutschland GmbH
> > > > > > Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
> > > > > > Tel: +49 89 99 8853-0, www.intel.de Managing Directors: Sean
> > > > > > Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva Chairperson
> > > > > > of the Supervisory Board: Nicole Lau Registered
> > > > > > Office: Munich Commercial Register: Amtsgericht Muenchen HRB
> > > > > > 186928
> > > > >
> > > > > Kindly pinging for feedback.
> > > > > Patch 2 of this series is already approved by Felix.
> > > > >
> > > > > BR,
> > > > > Christina
> > > >
> > > > Kindly pinging!
> > > >
> > > > BR,
> > > > Christina
> > >
> > > Kindly pinging.
> >
> > Kindly pinging.
> >
> > BR,
> > Christina
>
> Kindly pinging.
>
> BR,
> Christina
Kindly pinging.
BR,
Christina
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
@@ -945,7 +945,7 @@ aarch64_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
kernel can potentially be tagged addresses. */
struct gdbarch *gdbarch = thread_architecture (inferior_ptid);
const CORE_ADDR addr_trap
- = gdbarch_remove_non_address_bits (gdbarch, (CORE_ADDR) siginfo.si_addr);
+ = aarch64_remove_non_address_bits (gdbarch, (CORE_ADDR) siginfo.si_addr);
/* Check if the address matches any watched address. */
state = aarch64_get_debug_reg_state (inferior_ptid.pid ());
@@ -2456,7 +2456,7 @@ static bool
aarch64_linux_tagged_address_p (struct gdbarch *gdbarch, CORE_ADDR address)
{
/* Remove the top byte for the memory range check. */
- address = gdbarch_remove_non_address_bits (gdbarch, address);
+ address = aarch64_remove_non_address_bits (gdbarch, address);
/* Check if the page that contains ADDRESS is mapped with PROT_MTE. */
if (!linux_address_in_memtag_page (address))
@@ -2478,7 +2478,7 @@ aarch64_linux_memtag_matches_p (struct gdbarch *gdbarch,
/* Fetch the allocation tag for ADDRESS. */
std::optional<CORE_ADDR> atag
- = aarch64_mte_get_atag (gdbarch_remove_non_address_bits (gdbarch, addr));
+ = aarch64_mte_get_atag (aarch64_remove_non_address_bits (gdbarch, addr));
if (!atag.has_value ())
return true;
@@ -2517,7 +2517,7 @@ aarch64_linux_set_memtags (struct gdbarch *gdbarch, struct value *address,
else
{
/* Remove the top byte. */
- addr = gdbarch_remove_non_address_bits (gdbarch, addr);
+ addr = aarch64_remove_non_address_bits (gdbarch, addr);
/* With G being the number of tag granules and N the number of tags
passed in, we can have the following cases:
@@ -2566,7 +2566,7 @@ aarch64_linux_get_memtag (struct gdbarch *gdbarch, struct value *address,
else
{
/* Remove the top byte. */
- addr = gdbarch_remove_non_address_bits (gdbarch, addr);
+ addr = aarch64_remove_non_address_bits (gdbarch, addr);
std::optional<CORE_ADDR> atag = aarch64_mte_get_atag (addr);
if (!atag.has_value ())
@@ -2640,8 +2640,9 @@ aarch64_linux_report_signal_info (struct gdbarch *gdbarch,
uiout->text ("\n");
std::optional<CORE_ADDR> atag
- = aarch64_mte_get_atag (gdbarch_remove_non_address_bits (gdbarch,
- fault_addr));
+ = aarch64_mte_get_atag (
+ aarch64_remove_non_address_bits (gdbarch, fault_addr));
+
gdb_byte ltag = aarch64_mte_get_ltag (fault_addr);
if (!atag.has_value ())
@@ -4088,10 +4088,9 @@ aarch64_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
return streq (inst.opcode->name, "ret");
}
-/* AArch64 implementation of the remove_non_address_bits gdbarch hook. Remove
- non address bits from a pointer value. */
+/* See aarch64-tdep.h. */
-static CORE_ADDR
+CORE_ADDR
aarch64_remove_non_address_bits (struct gdbarch *gdbarch, CORE_ADDR pointer)
{
/* By default, we assume TBI and discard the top 8 bits plus the VA range
@@ -4585,9 +4584,15 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep->ra_sign_state_regnum = ra_sign_state_offset + num_regs;
/* Architecture hook to remove bits of a pointer that are not part of the
- address, like memory tags (MTE) and pointer authentication signatures. */
- set_gdbarch_remove_non_address_bits (gdbarch,
- aarch64_remove_non_address_bits);
+ address, like memory tags (MTE) and pointer authentication signatures.
+ Configure address adjustment for watch-, breakpoints and memory
+ transfer. */
+ set_gdbarch_remove_non_address_bits_watchpoint
+ (gdbarch, aarch64_remove_non_address_bits);
+ set_gdbarch_remove_non_address_bits_breakpoint
+ (gdbarch, aarch64_remove_non_address_bits);
+ set_gdbarch_remove_non_address_bits_memory
+ (gdbarch, aarch64_remove_non_address_bits);
/* SME pseudo-registers. */
if (tdep->has_sme ())
@@ -203,4 +203,10 @@ void aarch64_displaced_step_fixup (struct gdbarch *gdbarch,
bool aarch64_displaced_step_hw_singlestep (struct gdbarch *gdbarch);
+/* AArch64 implementation of the remove_non_address_bits gdbarch hooks.
+ Remove non address bits from a pointer value. */
+
+CORE_ADDR aarch64_remove_non_address_bits (struct gdbarch *gdbarch,
+ CORE_ADDR pointer);
+
#endif /* aarch64-tdep.h */
@@ -2238,7 +2238,8 @@ update_watchpoint (struct watchpoint *b, bool reparse)
loc->gdbarch = v->type ()->arch ();
loc->pspace = wp_pspace;
loc->address
- = gdbarch_remove_non_address_bits (loc->gdbarch, addr);
+ = gdbarch_remove_non_address_bits_watchpoint (loc->gdbarch,
+ addr);
b->add_location (*loc);
if (bitsize != 0)
@@ -7477,7 +7478,7 @@ adjust_breakpoint_address (struct gdbarch *gdbarch,
}
adjusted_bpaddr
- = gdbarch_remove_non_address_bits (gdbarch, adjusted_bpaddr);
+ = gdbarch_remove_non_address_bits_breakpoint (gdbarch, adjusted_bpaddr);
/* An adjusted breakpoint address can significantly alter
a user's expectations. Print a warning if an adjustment
@@ -684,19 +684,46 @@ extern CORE_ADDR gdbarch_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR ad
extern void set_gdbarch_addr_bits_remove (struct gdbarch *gdbarch, gdbarch_addr_bits_remove_ftype *addr_bits_remove);
/* On some architectures, not all bits of a pointer are significant.
- On AArch64, for example, the top bits of a pointer may carry a "tag", which
- can be ignored by the kernel and the hardware. The "tag" can be regarded as
- additional data associated with the pointer, but it is not part of the address.
+ On AArch64 and amd64, for example, the top bits of a pointer may carry a
+ "tag", which can be ignored by the kernel and the hardware. The "tag" can be
+ regarded as additional data associated with the pointer, but it is not part
+ of the address.
Given a pointer for the architecture, this hook removes all the
- non-significant bits and sign-extends things as needed. It gets used to remove
- non-address bits from data pointers (for example, removing the AArch64 MTE tag
- bits from a pointer) and from code pointers (removing the AArch64 PAC signature
- from a pointer containing the return address). */
-
-typedef CORE_ADDR (gdbarch_remove_non_address_bits_ftype) (struct gdbarch *gdbarch, CORE_ADDR pointer);
-extern CORE_ADDR gdbarch_remove_non_address_bits (struct gdbarch *gdbarch, CORE_ADDR pointer);
-extern void set_gdbarch_remove_non_address_bits (struct gdbarch *gdbarch, gdbarch_remove_non_address_bits_ftype *remove_non_address_bits);
+ non-significant bits and sign-extends things as needed. It gets used to
+ remove non-address bits from pointers used for watchpoints. */
+
+typedef CORE_ADDR (gdbarch_remove_non_address_bits_watchpoint_ftype) (struct gdbarch *gdbarch, CORE_ADDR pointer);
+extern CORE_ADDR gdbarch_remove_non_address_bits_watchpoint (struct gdbarch *gdbarch, CORE_ADDR pointer);
+extern void set_gdbarch_remove_non_address_bits_watchpoint (struct gdbarch *gdbarch, gdbarch_remove_non_address_bits_watchpoint_ftype *remove_non_address_bits_watchpoint);
+
+/* On some architectures, not all bits of a pointer are significant.
+ On AArch64 and amd64, for example, the top bits of a pointer may carry a
+ "tag", which can be ignored by the kernel and the hardware. The "tag" can be
+ regarded as additional data associated with the pointer, but it is not part
+ of the address.
+
+ Given a pointer for the architecture, this hook removes all the
+ non-significant bits and sign-extends things as needed. It gets used to
+ remove non-address bits from pointers used for breakpoints. */
+
+typedef CORE_ADDR (gdbarch_remove_non_address_bits_breakpoint_ftype) (struct gdbarch *gdbarch, CORE_ADDR pointer);
+extern CORE_ADDR gdbarch_remove_non_address_bits_breakpoint (struct gdbarch *gdbarch, CORE_ADDR pointer);
+extern void set_gdbarch_remove_non_address_bits_breakpoint (struct gdbarch *gdbarch, gdbarch_remove_non_address_bits_breakpoint_ftype *remove_non_address_bits_breakpoint);
+
+/* On some architectures, not all bits of a pointer are significant.
+ On AArch64 and amd64, for example, the top bits of a pointer may carry a
+ "tag", which can be ignored by the kernel and the hardware. The "tag" can be
+ regarded as additional data associated with the pointer, but it is not part
+ of the address.
+
+ Given a pointer for the architecture, this hook removes all the
+ non-significant bits and sign-extends things as needed. It gets used to
+ remove non-address bits from any pointer used to access memory. */
+
+typedef CORE_ADDR (gdbarch_remove_non_address_bits_memory_ftype) (struct gdbarch *gdbarch, CORE_ADDR pointer);
+extern CORE_ADDR gdbarch_remove_non_address_bits_memory (struct gdbarch *gdbarch, CORE_ADDR pointer);
+extern void set_gdbarch_remove_non_address_bits_memory (struct gdbarch *gdbarch, gdbarch_remove_non_address_bits_memory_ftype *remove_non_address_bits_memory);
/* Return a string representation of the memory tag TAG. */
@@ -143,7 +143,9 @@ struct gdbarch
int frame_red_zone_size = 0;
gdbarch_convert_from_func_ptr_addr_ftype *convert_from_func_ptr_addr = convert_from_func_ptr_addr_identity;
gdbarch_addr_bits_remove_ftype *addr_bits_remove = core_addr_identity;
- gdbarch_remove_non_address_bits_ftype *remove_non_address_bits = default_remove_non_address_bits;
+ gdbarch_remove_non_address_bits_watchpoint_ftype *remove_non_address_bits_watchpoint = default_remove_non_address_bits;
+ gdbarch_remove_non_address_bits_breakpoint_ftype *remove_non_address_bits_breakpoint = default_remove_non_address_bits;
+ gdbarch_remove_non_address_bits_memory_ftype *remove_non_address_bits_memory = default_remove_non_address_bits;
gdbarch_memtag_to_string_ftype *memtag_to_string = default_memtag_to_string;
gdbarch_tagged_address_p_ftype *tagged_address_p = default_tagged_address_p;
gdbarch_memtag_matches_p_ftype *memtag_matches_p = default_memtag_matches_p;
@@ -407,7 +409,9 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of frame_red_zone_size, invalid_p == 0 */
/* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */
/* Skip verify of addr_bits_remove, invalid_p == 0 */
- /* Skip verify of remove_non_address_bits, invalid_p == 0 */
+ /* Skip verify of remove_non_address_bits_watchpoint, invalid_p == 0 */
+ /* Skip verify of remove_non_address_bits_breakpoint, invalid_p == 0 */
+ /* Skip verify of remove_non_address_bits_memory, invalid_p == 0 */
/* Skip verify of memtag_to_string, invalid_p == 0 */
/* Skip verify of tagged_address_p, invalid_p == 0 */
/* Skip verify of memtag_matches_p, invalid_p == 0 */
@@ -910,8 +914,14 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
"gdbarch_dump: addr_bits_remove = <%s>\n",
host_address_to_string (gdbarch->addr_bits_remove));
gdb_printf (file,
- "gdbarch_dump: remove_non_address_bits = <%s>\n",
- host_address_to_string (gdbarch->remove_non_address_bits));
+ "gdbarch_dump: remove_non_address_bits_watchpoint = <%s>\n",
+ host_address_to_string (gdbarch->remove_non_address_bits_watchpoint));
+ gdb_printf (file,
+ "gdbarch_dump: remove_non_address_bits_breakpoint = <%s>\n",
+ host_address_to_string (gdbarch->remove_non_address_bits_breakpoint));
+ gdb_printf (file,
+ "gdbarch_dump: remove_non_address_bits_memory = <%s>\n",
+ host_address_to_string (gdbarch->remove_non_address_bits_memory));
gdb_printf (file,
"gdbarch_dump: memtag_to_string = <%s>\n",
host_address_to_string (gdbarch->memtag_to_string));
@@ -3198,20 +3208,54 @@ set_gdbarch_addr_bits_remove (struct gdbarch *gdbarch,
}
CORE_ADDR
-gdbarch_remove_non_address_bits (struct gdbarch *gdbarch, CORE_ADDR pointer)
+gdbarch_remove_non_address_bits_watchpoint (struct gdbarch *gdbarch, CORE_ADDR pointer)
+{
+ gdb_assert (gdbarch != NULL);
+ gdb_assert (gdbarch->remove_non_address_bits_watchpoint != NULL);
+ if (gdbarch_debug >= 2)
+ gdb_printf (gdb_stdlog, "gdbarch_remove_non_address_bits_watchpoint called\n");
+ return gdbarch->remove_non_address_bits_watchpoint (gdbarch, pointer);
+}
+
+void
+set_gdbarch_remove_non_address_bits_watchpoint (struct gdbarch *gdbarch,
+ gdbarch_remove_non_address_bits_watchpoint_ftype remove_non_address_bits_watchpoint)
+{
+ gdbarch->remove_non_address_bits_watchpoint = remove_non_address_bits_watchpoint;
+}
+
+CORE_ADDR
+gdbarch_remove_non_address_bits_breakpoint (struct gdbarch *gdbarch, CORE_ADDR pointer)
+{
+ gdb_assert (gdbarch != NULL);
+ gdb_assert (gdbarch->remove_non_address_bits_breakpoint != NULL);
+ if (gdbarch_debug >= 2)
+ gdb_printf (gdb_stdlog, "gdbarch_remove_non_address_bits_breakpoint called\n");
+ return gdbarch->remove_non_address_bits_breakpoint (gdbarch, pointer);
+}
+
+void
+set_gdbarch_remove_non_address_bits_breakpoint (struct gdbarch *gdbarch,
+ gdbarch_remove_non_address_bits_breakpoint_ftype remove_non_address_bits_breakpoint)
+{
+ gdbarch->remove_non_address_bits_breakpoint = remove_non_address_bits_breakpoint;
+}
+
+CORE_ADDR
+gdbarch_remove_non_address_bits_memory (struct gdbarch *gdbarch, CORE_ADDR pointer)
{
gdb_assert (gdbarch != NULL);
- gdb_assert (gdbarch->remove_non_address_bits != NULL);
+ gdb_assert (gdbarch->remove_non_address_bits_memory != NULL);
if (gdbarch_debug >= 2)
- gdb_printf (gdb_stdlog, "gdbarch_remove_non_address_bits called\n");
- return gdbarch->remove_non_address_bits (gdbarch, pointer);
+ gdb_printf (gdb_stdlog, "gdbarch_remove_non_address_bits_memory called\n");
+ return gdbarch->remove_non_address_bits_memory (gdbarch, pointer);
}
void
-set_gdbarch_remove_non_address_bits (struct gdbarch *gdbarch,
- gdbarch_remove_non_address_bits_ftype remove_non_address_bits)
+set_gdbarch_remove_non_address_bits_memory (struct gdbarch *gdbarch,
+ gdbarch_remove_non_address_bits_memory_ftype remove_non_address_bits_memory)
{
- gdbarch->remove_non_address_bits = remove_non_address_bits;
+ gdbarch->remove_non_address_bits_memory = remove_non_address_bits_memory;
}
std::string
@@ -1232,18 +1232,55 @@ possible it should be in TARGET_READ_PC instead).
Method(
comment="""
On some architectures, not all bits of a pointer are significant.
-On AArch64, for example, the top bits of a pointer may carry a "tag", which
-can be ignored by the kernel and the hardware. The "tag" can be regarded as
-additional data associated with the pointer, but it is not part of the address.
+On AArch64 and amd64, for example, the top bits of a pointer may carry a
+"tag", which can be ignored by the kernel and the hardware. The "tag" can be
+regarded as additional data associated with the pointer, but it is not part
+of the address.
Given a pointer for the architecture, this hook removes all the
-non-significant bits and sign-extends things as needed. It gets used to remove
-non-address bits from data pointers (for example, removing the AArch64 MTE tag
-bits from a pointer) and from code pointers (removing the AArch64 PAC signature
-from a pointer containing the return address).
+non-significant bits and sign-extends things as needed. It gets used to
+remove non-address bits from pointers used for watchpoints.
""",
type="CORE_ADDR",
- name="remove_non_address_bits",
+ name="remove_non_address_bits_watchpoint",
+ params=[("CORE_ADDR", "pointer")],
+ predefault="default_remove_non_address_bits",
+ invalid=False,
+)
+
+Method(
+ comment="""
+On some architectures, not all bits of a pointer are significant.
+On AArch64 and amd64, for example, the top bits of a pointer may carry a
+"tag", which can be ignored by the kernel and the hardware. The "tag" can be
+regarded as additional data associated with the pointer, but it is not part
+of the address.
+
+Given a pointer for the architecture, this hook removes all the
+non-significant bits and sign-extends things as needed. It gets used to
+remove non-address bits from pointers used for breakpoints.
+""",
+ type="CORE_ADDR",
+ name="remove_non_address_bits_breakpoint",
+ params=[("CORE_ADDR", "pointer")],
+ predefault="default_remove_non_address_bits",
+ invalid=False,
+)
+
+Method(
+ comment="""
+On some architectures, not all bits of a pointer are significant.
+On AArch64 and amd64, for example, the top bits of a pointer may carry a
+"tag", which can be ignored by the kernel and the hardware. The "tag" can be
+regarded as additional data associated with the pointer, but it is not part
+of the address.
+
+Given a pointer for the architecture, this hook removes all the
+non-significant bits and sign-extends things as needed. It gets used to
+remove non-address bits from any pointer used to access memory.
+""",
+ type="CORE_ADDR",
+ name="remove_non_address_bits_memory",
params=[("CORE_ADDR", "pointer")],
predefault="default_remove_non_address_bits",
invalid=False,
@@ -1608,7 +1608,8 @@ memory_xfer_partial (struct target_ops *ops, enum target_object object,
if (len == 0)
return TARGET_XFER_EOF;
- memaddr = gdbarch_remove_non_address_bits (current_inferior ()->arch (),
+ memaddr
+ = gdbarch_remove_non_address_bits_memory (current_inferior ()->arch (),
memaddr);
/* Fill in READBUF with breakpoint shadows, or WRITEBUF with