From: Ezra Sitorus Date: Mon, 17 Nov 2025 12:45:58 +0000 (+0000) Subject: gdb/aarch64: signal frame support for fpmr X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=192e93087e24150e46bd03879e3041d1ef5415af;p=thirdparty%2Fbinutils-gdb.git gdb/aarch64: signal frame support for fpmr Add support for FPMR in signal frames and restore contents of FPMR. Approved-By: Luis Machado --- diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c index 10b44d978af..5346ae39eda 100644 --- a/gdb/aarch64-linux-tdep.c +++ b/gdb/aarch64-linux-tdep.c @@ -167,6 +167,7 @@ #define AARCH64_TPIDR2_MAGIC 0x54504902 #define AARCH64_ZT_MAGIC 0x5a544e01 #define AARCH64_GCS_MAGIC 0x47435300 +#define AARCH64_FPMR_MAGIC 0x46504d52 /* Defines for the extra_context that follows an AARCH64_EXTRA_MAGIC. */ #define AARCH64_EXTRA_DATAP_OFFSET 8 @@ -213,6 +214,9 @@ /* features_enabled value offset in the GCS signal frame context. */ #define AARCH64_GCS_CONTEXT_FEATURES_ENABLED_OFFSET 16 +/* FPMR constants. */ +#define AARCH64_FPMR_OFFSET 8 + /* Holds information about the signal frame. */ struct aarch64_linux_sigframe { @@ -260,6 +264,12 @@ struct aarch64_linux_sigframe uint64_t gcspr; /* Flags indicating which GCS features are enabled for the thread. */ uint64_t gcs_features_enabled; + + /* True if we have an FPMR entry in the signal context, false otherwise. */ + bool fpmr_available = false; + /* FPMR value. */ + CORE_ADDR fpmr = 0; + }; /* Read an aarch64_ctx, returning the magic value, and setting *SIZE to the @@ -576,6 +586,22 @@ aarch64_linux_read_signal_frame_info (const frame_info_ptr &this_frame, section += size; break; } + case AARCH64_FPMR_MAGIC: + { + gdb_byte buf[8]; + if (target_read_memory (section + AARCH64_FPMR_OFFSET, + buf, 8) != 0) + { + warning (_("Failed to read the FPMR section address from the" + " signal frame context.")); + section += size; + break; + } + signal_frame.fpmr = extract_unsigned_integer (buf, 8, byte_order); + signal_frame.fpmr_available = true; + section += size; + break; + } case AARCH64_EXTRA_MAGIC: { /* Extra is always the last valid section in reserved and points to @@ -739,6 +765,13 @@ aarch64_linux_sigframe_init (const struct tramp_frame *self, } } + /* Handle FPMR. */ + if (tdep->has_fpmr () && signal_frame.fpmr_available != 0) + { + trad_frame_set_reg_value (this_cache, tdep->fpmr_regnum, + signal_frame.fpmr); + } + /* Restore the tpidr2 register, if the target supports it and if there is an entry for it. */ if (signal_frame.tpidr2_section != 0 && tdep->has_tls () @@ -791,6 +824,7 @@ aarch64_linux_sigframe_prev_arch (const frame_info_ptr &this_frame, aarch64_features features = aarch64_features_from_target_desc (tdesc); features.vq = sve_vq_from_vl (signal_frame.vl); features.svq = (uint8_t) sve_vq_from_vl (signal_frame.svl); + features.fpmr = signal_frame.fpmr_available; struct gdbarch_info info; info.bfd_arch_info = bfd_lookup_arch (bfd_arch_aarch64, bfd_mach_aarch64);