* [PATCH v5] gdb: align siginfo_t with the Linux kernel definition
@ 2026-07-28 12:32 Matthieu Longo
2026-08-03 8:23 ` Matthieu Longo
2026-08-12 19:08 ` Simon Marchi
0 siblings, 2 replies; 11+ messages in thread
From: Matthieu Longo @ 2026-07-28 12:32 UTC (permalink / raw)
To: gdb-patches
Cc: Luis Machado, Luis Machado, Thiago Jung Bauermann,
Srinath Parvathaneni, Maciej W . Rozycki, Andreas Schwab,
Matthieu Longo
GDB's current definition of siginfo_t is missing many fields present in
the Linux kernel definition [1].
These fields are useful for providing detailed, user-friendly diagnostics
when a fault occurs. Some new AArch64 extensions, such as Permission
Overlay Enhancement used to implement Protection Keys [2], require the
debugger to inspect 'si_pkey' alongside 'si_addr' to help the user identify
the problematic key.
This patch aligns GDB's definition of the __sifields._sigfault member of
siginfo_t with the definition from the Linux kernel master branch.
To avoid hardcoding the field access paths throughout the codebase, this
patch also introduces compile-time accessors for the siginfo_t attributes,
centralizing their definitions in a single location and making future
updates easier.
Finally, extend the testsuite to verify access to the new si_pkey field
and its preservation when modifying $_siginfo and when reading core files.
The tests in siginfo-obj.exp rely on the siginfo_t definition provided by
glibc's <signal.h>, which does not yet expose all of the fields present in
the kernel definition. As a result, the tests cannot exercise every newly
added field and therefore focus on si_pkey, the field motivating this change.
The test validates that GDB can read and modify the field correctly; it does
not attempt to generate a real protection-key fault.
[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
tree/include/uapi/asm-generic/siginfo.h#n69
[2]: https://lore.kernel.org/all/20160212210213.ABC488FA@viggo.jf.intel.com/
Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
---
gdb/aarch64-linux-tdep.c | 8 ++--
gdb/linux-tdep.c | 52 +++++++++++++++++++---
gdb/linux-tdep.h | 60 ++++++++++++++++++++++++++
gdb/sparc64-linux-tdep.c | 6 ++-
gdb/testsuite/gdb.base/siginfo-obj.c | 1 +
gdb/testsuite/gdb.base/siginfo-obj.exp | 14 ++++++
6 files changed, 131 insertions(+), 10 deletions(-)
diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index f11eccc1bc1..235b35bcfb4 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -2683,13 +2683,15 @@ aarch64_linux_report_signal_info (struct gdbarch *gdbarch,
try
{
+ using gdb_si = gdb::siginfo_type;
+ using si_key = gdb::siginfo_type::key;
/* Sigcode tells us if the segfault is actually a memory tag
violation. */
- si_code = parse_and_eval_long ("$_siginfo.si_code");
- si_errno = parse_and_eval_long ("$_siginfo.si_errno");
+ si_code = parse_and_eval_long (gdb_si::get (si_key::siginfo_code));
+ si_errno = parse_and_eval_long (gdb_si::get (si_key::siginfo_errno));
fault_addr
- = parse_and_eval_long ("$_siginfo._sifields._sigfault.si_addr");
+ = parse_and_eval_long (gdb_si::get (si_key::siginfo_addr));
}
catch (const gdb_exception_error &exception)
{
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 25d625db595..740043a9292 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -272,10 +272,9 @@ static struct type *
linux_get_siginfo_type (struct gdbarch *gdbarch)
{
struct linux_gdbarch_data *linux_gdbarch_data;
- struct type *void_ptr_type;
struct type *uid_type, *pid_type;
struct type *sigval_type, *clock_type;
- struct type *siginfo_type, *sifields_type;
+ struct type *siginfo_type, *sifields_type, *sigfault_union_type;
struct type *type;
linux_gdbarch_data = get_linux_gdbarch_data (gdbarch);
@@ -285,11 +284,22 @@ linux_get_siginfo_type (struct gdbarch *gdbarch)
type_allocator alloc (gdbarch);
const struct builtin_type *builtin_types = builtin_type (gdbarch);
+ struct type *short_type = builtin_types->builtin_short;
struct type *int_type = builtin_types->builtin_int;
struct type *uint_type = builtin_types->builtin_unsigned_int;
struct type *long_type = builtin_types->builtin_long;
-
- void_ptr_type = lookup_pointer_type (builtin_type (gdbarch)->builtin_void);
+ struct type *unsigned_long_type = builtin_types->builtin_unsigned_long;
+ struct type *uint32_type = builtin_types->builtin_uint32;
+ struct type *void_ptr_type
+ = lookup_pointer_type (builtin_type (gdbarch)->builtin_void);
+
+ /* Compute padding length, i.e. __ADDR_BND_PKEY_PAD. */
+ unsigned alignof_void_ptr = type_align (void_ptr_type);
+ unsigned padding_size = (alignof_void_ptr < short_type->length ()
+ ? short_type->length ()
+ : alignof_void_ptr);
+ struct type *addr_bnd_pkey_padding_type
+ = init_vector_type (builtin_types->builtin_uint8, padding_size);
/* sival_t */
sigval_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
@@ -364,9 +374,41 @@ linux_get_siginfo_type (struct gdbarch *gdbarch)
append_composite_type_field (type, "si_stime", clock_type);
append_composite_type_field (sifields_type, "_sigchld", type);
- /* _sigfault */
+ /* Begin _sigfault's anonymous union. */
+ sigfault_union_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+ /* used on alpha and sparc */
+ append_composite_type_field (sigfault_union_type, "si_trapno", int_type);
+ /* used when si_code is BUS_MCEERR_AR or BUS_MCEERR_AO. */
+ append_composite_type_field (sigfault_union_type, "si_addr_lsb", short_type);
+
+ /* used when si_code=SEGV_BNDERR */
+ type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+ append_composite_type_field (type, "_dummy_bnd", addr_bnd_pkey_padding_type);
+ append_composite_type_field (type, "si_lower", void_ptr_type);
+ append_composite_type_field (type, "si_upper", void_ptr_type);
+ append_composite_type_field (sigfault_union_type, "_addr_bnd", type);
+
+ /* used when si_code=SEGV_PKUERR */
+ type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+ append_composite_type_field (type, "_dummy_pkey", addr_bnd_pkey_padding_type);
+ append_composite_type_field (type, "si_pkey", uint32_type);
+ append_composite_type_field (sigfault_union_type, "_addr_pkey", type);
+
+ /* used when si_code=TRAP_PERF */
+ type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+ append_composite_type_field (type, "si_perf_data", unsigned_long_type);
+ append_composite_type_field (type, "si_perf_type", uint32_type);
+ append_composite_type_field (type, "si_perf_flags", uint32_type);
+ append_composite_type_field (sigfault_union_type, "_perf", type);
+
+ /* End _sigfault's anonymous union. */
+
+ /* _sigfault is set by SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */
type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
append_composite_type_field (type, "si_addr", void_ptr_type);
+ /* Since there is no possibility to declare an anonymous union,
+ using '_anon_union' instead. */
+ append_composite_type_field (type, "_anon_union", sigfault_union_type);
append_composite_type_field (sifields_type, "_sigfault", type);
/* _sigpoll */
diff --git a/gdb/linux-tdep.h b/gdb/linux-tdep.h
index c19839fde2c..43ed38c6633 100644
--- a/gdb/linux-tdep.h
+++ b/gdb/linux-tdep.h
@@ -98,4 +98,64 @@ extern CORE_ADDR linux_get_hwcap2 ();
extern bool linux_address_in_shadow_stack_mem_range
(CORE_ADDR addr, std::pair<CORE_ADDR, CORE_ADDR> *range);
+namespace gdb {
+
+/* Maps each siginfo_type::key to the corresponding field-access expression
+ in $_siginfo.
+
+ Keep the order of key values synchronized with the entries in get()'s
+ paths array. Each key is used directly as an array index. */
+
+struct siginfo_type
+{
+ /* Identifies a field within siginfo_t that may be referenced by name. */
+ enum class key
+ {
+ siginfo_signo = 0,
+ siginfo_errno,
+ siginfo_code,
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */
+ siginfo_addr,
+ siginfo_trapno,
+ siginfo_addr_lsb,
+ siginfo_lower,
+ siginfo_upper,
+ siginfo_pkey,
+ siginfo_perf_data,
+ siginfo_perf_type,
+ siginfo_perf_flags,
+
+ /* Sentinel used to determine the number of mapped fields. */
+ SIGINFO_ATTR_END
+ };
+
+ /* Return the $_siginfo access expression associated with ATTR_.
+
+ ATTR_ must be a valid si_* key other than SIGINFO_ATTR_END. The array
+ order must exactly match the declaration order of the keys above. */
+ static constexpr const char *get (key attr_)
+ {
+ const char *paths[static_cast<size_t> (key::SIGINFO_ATTR_END)] = {
+ "$_siginfo.si_signo",
+ "$_siginfo.si_errno",
+ "$_siginfo.si_code",
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */
+ "$_siginfo._sifields._sigfault.si_addr",
+ "$_siginfo._sifields._sigfault._anon_union.si_trapno",
+ "$_siginfo._sifields._sigfault._anon_union.si_addr_lsb",
+ "$_siginfo._sifields._sigfault._anon_union._addr_bnd.si_lower",
+ "$_siginfo._sifields._sigfault._anon_union._addr_bnd.si_upper",
+ "$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey",
+ "$_siginfo._sifields._sigfault._anon_union._perf.si_perf_data",
+ "$_siginfo._sifields._sigfault._anon_union._perf.si_perf_type",
+ "$_siginfo._sifields._sigfault._anon_union._perf.si_perf_flags",
+ };
+ return paths[static_cast<size_t> (attr_)];
+ }
+};
+
+} /* namespace gdb */
+
#endif /* GDB_LINUX_TDEP_H */
diff --git a/gdb/sparc64-linux-tdep.c b/gdb/sparc64-linux-tdep.c
index cb7ce41e5cb..b6245f64bae 100644
--- a/gdb/sparc64-linux-tdep.c
+++ b/gdb/sparc64-linux-tdep.c
@@ -134,11 +134,13 @@ sparc64_linux_report_signal_info (struct gdbarch *gdbarch, struct ui_out *uiout,
try
{
+ using gdb_si = gdb::siginfo_type;
+ using si_key = gdb::siginfo_type::key;
/* Evaluate si_code to see if the segfault is ADI related. */
- si_code = parse_and_eval_long ("$_siginfo.si_code\n");
+ si_code = parse_and_eval_long (gdb_si::get (si_key::siginfo_code));
if (si_code >= SEGV_ACCADI && si_code <= SEGV_ADIPERR)
- addr = parse_and_eval_long ("$_siginfo._sifields._sigfault.si_addr");
+ addr = parse_and_eval_long (gdb_si::get (si_key::siginfo_addr));
}
catch (const gdb_exception_error &exception)
{
diff --git a/gdb/testsuite/gdb.base/siginfo-obj.c b/gdb/testsuite/gdb.base/siginfo-obj.c
index 43dc979bc50..960e5b8e9cd 100644
--- a/gdb/testsuite/gdb.base/siginfo-obj.c
+++ b/gdb/testsuite/gdb.base/siginfo-obj.c
@@ -35,6 +35,7 @@ handler (int sig, siginfo_t *info, void *context)
int ssi_signo = info->si_signo;
int ssi_code = info->si_code;
void *ssi_addr = info->si_addr;
+ unsigned int ssi_pkey = info->si_pkey;
_exit (0); /* set breakpoint here */
}
diff --git a/gdb/testsuite/gdb.base/siginfo-obj.exp b/gdb/testsuite/gdb.base/siginfo-obj.exp
index a94bf0e33ba..5e36b334068 100644
--- a/gdb/testsuite/gdb.base/siginfo-obj.exp
+++ b/gdb/testsuite/gdb.base/siginfo-obj.exp
@@ -78,6 +78,14 @@ gdb_test_multiple "p \$_siginfo" "$test" {
}
}
+set test "extract si_pkey"
+gdb_test_multiple "p \$_siginfo" "$test" {
+ -re "si_pkey = (\[0-9\]\+).*$gdb_prompt $" {
+ set ssi_pkey $expect_out(1,string)
+ pass "$test"
+ }
+}
+
set bp_location [gdb_get_line_number "set breakpoint here"]
with_test_prefix "validate siginfo fields" {
@@ -87,6 +95,7 @@ with_test_prefix "validate siginfo fields" {
gdb_test "p ssi_errno" " = $ssi_errno"
gdb_test "p ssi_code" " = $ssi_code"
gdb_test "p ssi_signo" " = $ssi_signo"
+ gdb_test "p ssi_pkey" " = $ssi_pkey"
}
# Again, but this time, patch si_addr and check that the inferior sees
@@ -106,6 +115,7 @@ gdb_test "p \$_siginfo._sifields._sigfault.si_addr = 0x666" " = \\(void \\*\\) 0
gdb_test "p \$_siginfo.si_errno = 666" " = 666"
gdb_test "p \$_siginfo.si_code = 999" " = 999"
gdb_test "p \$_siginfo.si_signo = 11" " = 11"
+gdb_test "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey = 123" " = 123"
with_test_prefix "validate modified siginfo fields" {
gdb_test "break $bp_location"
@@ -114,6 +124,7 @@ with_test_prefix "validate modified siginfo fields" {
gdb_test "p ssi_errno" " = 666"
gdb_test "p ssi_code" " = 999"
gdb_test "p ssi_signo" " = 11"
+ gdb_test "p ssi_pkey" " = 123"
}
# Test siginfo preservation in core files.
@@ -132,4 +143,7 @@ if {$gcore_created} {
gdb_test "p \$_siginfo._sifields._sigfault.si_addr" \
" = \\(void \\*\\) $ssi_addr" \
"p \$_siginfo._sifields._sigfault.si_addr from core file"
+ gdb_test "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey" \
+ " = $ssi_pkey" \
+ "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey from core file"
}
--
2.55.0
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH v5] gdb: align siginfo_t with the Linux kernel definition 2026-07-28 12:32 [PATCH v5] gdb: align siginfo_t with the Linux kernel definition Matthieu Longo @ 2026-08-03 8:23 ` Matthieu Longo 2026-08-12 21:55 ` Luis 2026-08-12 19:08 ` Simon Marchi 1 sibling, 1 reply; 11+ messages in thread From: Matthieu Longo @ 2026-08-03 8:23 UTC (permalink / raw) To: gdb-patches Cc: Luis Machado, Luis Machado, Thiago Jung Bauermann, Srinath Parvathaneni, Maciej W . Rozycki, Andreas Schwab On 28/07/2026 13:32, Matthieu Longo wrote: > GDB's current definition of siginfo_t is missing many fields present in > the Linux kernel definition [1]. > > These fields are useful for providing detailed, user-friendly diagnostics > when a fault occurs. Some new AArch64 extensions, such as Permission > Overlay Enhancement used to implement Protection Keys [2], require the > debugger to inspect 'si_pkey' alongside 'si_addr' to help the user identify > the problematic key. > > This patch aligns GDB's definition of the __sifields._sigfault member of > siginfo_t with the definition from the Linux kernel master branch. > > To avoid hardcoding the field access paths throughout the codebase, this > patch also introduces compile-time accessors for the siginfo_t attributes, > centralizing their definitions in a single location and making future > updates easier. > > Finally, extend the testsuite to verify access to the new si_pkey field > and its preservation when modifying $_siginfo and when reading core files. > The tests in siginfo-obj.exp rely on the siginfo_t definition provided by > glibc's <signal.h>, which does not yet expose all of the fields present in > the kernel definition. As a result, the tests cannot exercise every newly > added field and therefore focus on si_pkey, the field motivating this change. > The test validates that GDB can read and modify the field correctly; it does > not attempt to generate a real protection-key fault. > > [1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/ > tree/include/uapi/asm-generic/siginfo.h#n69 > [2]: https://lore.kernel.org/all/20160212210213.ABC488FA@viggo.jf.intel.com/ > > Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org> Ping. @Luis: I addressed your suggestion for compile time accessors. I think that it is cleaner than a hard-coded string anyway. Please let me know what you if you are happy with the current state. Regarding the GDB users' accessors, I haven't implemented them because the scope of this patch would increase too much. Please see my response in v3 [1]. [1]: https://inbox.sourceware.org/gdb-patches/5c623005-2b19-48a6-9bd5-bb3dfb3166b0@arm.com/ Matthieu ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v5] gdb: align siginfo_t with the Linux kernel definition 2026-08-03 8:23 ` Matthieu Longo @ 2026-08-12 21:55 ` Luis 0 siblings, 0 replies; 11+ messages in thread From: Luis @ 2026-08-12 21:55 UTC (permalink / raw) To: Matthieu Longo, gdb-patches Cc: Luis Machado, Thiago Jung Bauermann, Srinath Parvathaneni, Maciej W . Rozycki, Andreas Schwab On 03/08/2026 09:23, Matthieu Longo wrote: > On 28/07/2026 13:32, Matthieu Longo wrote: >> GDB's current definition of siginfo_t is missing many fields present in >> the Linux kernel definition [1]. >> >> These fields are useful for providing detailed, user-friendly diagnostics >> when a fault occurs. Some new AArch64 extensions, such as Permission >> Overlay Enhancement used to implement Protection Keys [2], require the >> debugger to inspect 'si_pkey' alongside 'si_addr' to help the user identify >> the problematic key. >> >> This patch aligns GDB's definition of the __sifields._sigfault member of >> siginfo_t with the definition from the Linux kernel master branch. >> >> To avoid hardcoding the field access paths throughout the codebase, this >> patch also introduces compile-time accessors for the siginfo_t attributes, >> centralizing their definitions in a single location and making future >> updates easier. >> >> Finally, extend the testsuite to verify access to the new si_pkey field >> and its preservation when modifying $_siginfo and when reading core files. >> The tests in siginfo-obj.exp rely on the siginfo_t definition provided by >> glibc's <signal.h>, which does not yet expose all of the fields present in >> the kernel definition. As a result, the tests cannot exercise every newly >> added field and therefore focus on si_pkey, the field motivating this change. >> The test validates that GDB can read and modify the field correctly; it does >> not attempt to generate a real protection-key fault. >> >> [1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/ >> tree/include/uapi/asm-generic/siginfo.h#n69 >> [2]: https://lore.kernel.org/all/20160212210213.ABC488FA@viggo.jf.intel.com/ >> >> Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org> > Ping. > > @Luis: I addressed your suggestion for compile time accessors. I think that it is cleaner than a > hard-coded string anyway. Please let me know what you if you are happy with the current state. Thanks. It looks cleaner indeed. The aarch64 parts look OK to me, as does the test. I see Simon has made comments on the anonymous struct access. > > Regarding the GDB users' accessors, I haven't implemented them because the scope of this patch would > increase too much. Please see my response in v3 [1]. That's fine by me. > > [1]: https://inbox.sourceware.org/gdb-patches/5c623005-2b19-48a6-9bd5-bb3dfb3166b0@arm.com/ > > Matthieu ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v5] gdb: align siginfo_t with the Linux kernel definition 2026-07-28 12:32 [PATCH v5] gdb: align siginfo_t with the Linux kernel definition Matthieu Longo 2026-08-03 8:23 ` Matthieu Longo @ 2026-08-12 19:08 ` Simon Marchi 2026-08-13 14:48 ` Matthieu Longo 1 sibling, 1 reply; 11+ messages in thread From: Simon Marchi @ 2026-08-12 19:08 UTC (permalink / raw) To: Matthieu Longo, gdb-patches Cc: Luis Machado, Luis Machado, Thiago Jung Bauermann, Srinath Parvathaneni, Maciej W . Rozycki, Andreas Schwab On 7/28/26 8:32 AM, Matthieu Longo wrote: > GDB's current definition of siginfo_t is missing many fields present in > the Linux kernel definition [1]. > > These fields are useful for providing detailed, user-friendly diagnostics > when a fault occurs. Some new AArch64 extensions, such as Permission > Overlay Enhancement used to implement Protection Keys [2], require the > debugger to inspect 'si_pkey' alongside 'si_addr' to help the user identify > the problematic key. > > This patch aligns GDB's definition of the __sifields._sigfault member of > siginfo_t with the definition from the Linux kernel master branch. > > To avoid hardcoding the field access paths throughout the codebase, this > patch also introduces compile-time accessors for the siginfo_t attributes, > centralizing their definitions in a single location and making future > updates easier. > > Finally, extend the testsuite to verify access to the new si_pkey field > and its preservation when modifying $_siginfo and when reading core files. > The tests in siginfo-obj.exp rely on the siginfo_t definition provided by > glibc's <signal.h>, which does not yet expose all of the fields present in > the kernel definition. As a result, the tests cannot exercise every newly > added field and therefore focus on si_pkey, the field motivating this change. > The test validates that GDB can read and modify the field correctly; it does > not attempt to generate a real protection-key fault. > > [1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/ > tree/include/uapi/asm-generic/siginfo.h#n69 > [2]: https://lore.kernel.org/all/20160212210213.ABC488FA@viggo.jf.intel.com/ > > Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org> > --- > gdb/aarch64-linux-tdep.c | 8 ++-- > gdb/linux-tdep.c | 52 +++++++++++++++++++--- > gdb/linux-tdep.h | 60 ++++++++++++++++++++++++++ > gdb/sparc64-linux-tdep.c | 6 ++- > gdb/testsuite/gdb.base/siginfo-obj.c | 1 + > gdb/testsuite/gdb.base/siginfo-obj.exp | 14 ++++++ > 6 files changed, 131 insertions(+), 10 deletions(-) > > diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c > index f11eccc1bc1..235b35bcfb4 100644 > --- a/gdb/aarch64-linux-tdep.c > +++ b/gdb/aarch64-linux-tdep.c > @@ -2683,13 +2683,15 @@ aarch64_linux_report_signal_info (struct gdbarch *gdbarch, > > try > { > + using gdb_si = gdb::siginfo_type; > + using si_key = gdb::siginfo_type::key; > /* Sigcode tells us if the segfault is actually a memory tag > violation. */ > - si_code = parse_and_eval_long ("$_siginfo.si_code"); > - si_errno = parse_and_eval_long ("$_siginfo.si_errno"); > + si_code = parse_and_eval_long (gdb_si::get (si_key::siginfo_code)); > + si_errno = parse_and_eval_long (gdb_si::get (si_key::siginfo_errno)); > > fault_addr > - = parse_and_eval_long ("$_siginfo._sifields._sigfault.si_addr"); > + = parse_and_eval_long (gdb_si::get (si_key::siginfo_addr)); > } > catch (const gdb_exception_error &exception) > { > diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c > index 25d625db595..740043a9292 100644 > --- a/gdb/linux-tdep.c > +++ b/gdb/linux-tdep.c > @@ -272,10 +272,9 @@ static struct type * > linux_get_siginfo_type (struct gdbarch *gdbarch) > { > struct linux_gdbarch_data *linux_gdbarch_data; > - struct type *void_ptr_type; > struct type *uid_type, *pid_type; > struct type *sigval_type, *clock_type; > - struct type *siginfo_type, *sifields_type; > + struct type *siginfo_type, *sifields_type, *sigfault_union_type; > struct type *type; > > linux_gdbarch_data = get_linux_gdbarch_data (gdbarch); > @@ -285,11 +284,22 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) > type_allocator alloc (gdbarch); > > const struct builtin_type *builtin_types = builtin_type (gdbarch); > + struct type *short_type = builtin_types->builtin_short; > struct type *int_type = builtin_types->builtin_int; > struct type *uint_type = builtin_types->builtin_unsigned_int; > struct type *long_type = builtin_types->builtin_long; > - > - void_ptr_type = lookup_pointer_type (builtin_type (gdbarch)->builtin_void); > + struct type *unsigned_long_type = builtin_types->builtin_unsigned_long; > + struct type *uint32_type = builtin_types->builtin_uint32; > + struct type *void_ptr_type > + = lookup_pointer_type (builtin_type (gdbarch)->builtin_void); > + > + /* Compute padding length, i.e. __ADDR_BND_PKEY_PAD. */ > + unsigned alignof_void_ptr = type_align (void_ptr_type); > + unsigned padding_size = (alignof_void_ptr < short_type->length () > + ? short_type->length () > + : alignof_void_ptr); > + struct type *addr_bnd_pkey_padding_type > + = init_vector_type (builtin_types->builtin_uint8, padding_size); > > /* sival_t */ > sigval_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); > @@ -364,9 +374,41 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) > append_composite_type_field (type, "si_stime", clock_type); > append_composite_type_field (sifields_type, "_sigchld", type); > > - /* _sigfault */ > + /* Begin _sigfault's anonymous union. */ > + sigfault_union_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); > + /* used on alpha and sparc */ > + append_composite_type_field (sigfault_union_type, "si_trapno", int_type); > + /* used when si_code is BUS_MCEERR_AR or BUS_MCEERR_AO. */ > + append_composite_type_field (sigfault_union_type, "si_addr_lsb", short_type); > + > + /* used when si_code=SEGV_BNDERR */ > + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); > + append_composite_type_field (type, "_dummy_bnd", addr_bnd_pkey_padding_type); > + append_composite_type_field (type, "si_lower", void_ptr_type); > + append_composite_type_field (type, "si_upper", void_ptr_type); > + append_composite_type_field (sigfault_union_type, "_addr_bnd", type); > + > + /* used when si_code=SEGV_PKUERR */ > + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); > + append_composite_type_field (type, "_dummy_pkey", addr_bnd_pkey_padding_type); > + append_composite_type_field (type, "si_pkey", uint32_type); > + append_composite_type_field (sigfault_union_type, "_addr_pkey", type); > + > + /* used when si_code=TRAP_PERF */ > + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); > + append_composite_type_field (type, "si_perf_data", unsigned_long_type); > + append_composite_type_field (type, "si_perf_type", uint32_type); > + append_composite_type_field (type, "si_perf_flags", uint32_type); > + append_composite_type_field (sigfault_union_type, "_perf", type); > + > + /* End _sigfault's anonymous union. */ > + > + /* _sigfault is set by SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */ > type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); > append_composite_type_field (type, "si_addr", void_ptr_type); > + /* Since there is no possibility to declare an anonymous union, > + using '_anon_union' instead. */ > + append_composite_type_field (type, "_anon_union", sigfault_union_type); Can you expand on why it's not possible to have an anonymous union? It is certainly possible to have anonymous unions described in DWARF, which are then translated to struct types. I think that the ideal user experience would be for users to be able to access fields the same way that they do in the code, that is `si.si_pkey`. All the _sigfault/_addr_pkey/etc parts are implementation details that could change. On top of your patch, if I just delete all the internal field names, it seems to work just fine, see patch below. In the end it models something like this in C: struct siginto_t { union { // kill struct { int si_pid; int si_uid; }; // timer struct { int si_tid; int si_overrun; int si_sys_private; }; ... }; }; diff --git i/gdb/linux-tdep.c w/gdb/linux-tdep.c index 4660772752d6..f21fa1e18578 100644 --- i/gdb/linux-tdep.c +++ w/gdb/linux-tdep.c @@ -349,21 +349,21 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); append_composite_type_field (type, "si_pid", pid_type); append_composite_type_field (type, "si_uid", uid_type); - append_composite_type_field (sifields_type, "_kill", type); + append_composite_type_field (sifields_type, "", type); /* _timer */ type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); append_composite_type_field (type, "si_tid", int_type); append_composite_type_field (type, "si_overrun", int_type); append_composite_type_field (type, "si_sigval", sigval_type); - append_composite_type_field (sifields_type, "_timer", type); + append_composite_type_field (sifields_type, "", type); /* _rt */ type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); append_composite_type_field (type, "si_pid", pid_type); append_composite_type_field (type, "si_uid", uid_type); append_composite_type_field (type, "si_sigval", sigval_type); - append_composite_type_field (sifields_type, "_rt", type); + append_composite_type_field (sifields_type, "", type); /* _sigchld */ type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); @@ -372,7 +372,7 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) append_composite_type_field (type, "si_status", int_type); append_composite_type_field (type, "si_utime", clock_type); append_composite_type_field (type, "si_stime", clock_type); - append_composite_type_field (sifields_type, "_sigchld", type); + append_composite_type_field (sifields_type, "", type); /* Begin _sigfault's anonymous union. */ sigfault_union_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); @@ -386,20 +386,20 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) append_composite_type_field (type, "_dummy_bnd", addr_bnd_pkey_padding_type); append_composite_type_field (type, "si_lower", void_ptr_type); append_composite_type_field (type, "si_upper", void_ptr_type); - append_composite_type_field (sigfault_union_type, "_addr_bnd", type); + append_composite_type_field (sigfault_union_type, "", type); /* used when si_code=SEGV_PKUERR */ type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); append_composite_type_field (type, "_dummy_pkey", addr_bnd_pkey_padding_type); append_composite_type_field (type, "si_pkey", uint32_type); - append_composite_type_field (sigfault_union_type, "_addr_pkey", type); + append_composite_type_field (sigfault_union_type, "", type); /* used when si_code=TRAP_PERF */ type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); append_composite_type_field (type, "si_perf_data", unsigned_long_type); append_composite_type_field (type, "si_perf_type", uint32_type); append_composite_type_field (type, "si_perf_flags", uint32_type); - append_composite_type_field (sigfault_union_type, "_perf", type); + append_composite_type_field (sigfault_union_type, "", type); /* End _sigfault's anonymous union. */ @@ -408,21 +408,21 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) append_composite_type_field (type, "si_addr", void_ptr_type); /* Since there is no possibility to declare an anonymous union, using '_anon_union' instead. */ - append_composite_type_field (type, "_anon_union", sigfault_union_type); - append_composite_type_field (sifields_type, "_sigfault", type); + append_composite_type_field (type, "", sigfault_union_type); + append_composite_type_field (sifields_type, "", type); /* _sigpoll */ type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); append_composite_type_field (type, "si_band", long_type); append_composite_type_field (type, "si_fd", int_type); - append_composite_type_field (sifields_type, "_sigpoll", type); + append_composite_type_field (sifields_type, "", type); /* _sigsys */ type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); append_composite_type_field (type, "_call_addr", void_ptr_type); append_composite_type_field (type, "_syscall", int_type); append_composite_type_field (type, "_arch", uint_type); - append_composite_type_field (sifields_type, "_sigsys", type); + append_composite_type_field (sifields_type, "", type); /* struct siginfo */ siginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); @@ -431,7 +431,7 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) append_composite_type_field (siginfo_type, "si_errno", int_type); append_composite_type_field (siginfo_type, "si_code", int_type); append_composite_type_field_aligned (siginfo_type, - "_sifields", sifields_type, + "", sifields_type, long_type->length ()); linux_gdbarch_data->siginfo_type = siginfo_type; diff --git i/gdb/testsuite/gdb.base/siginfo-obj.exp w/gdb/testsuite/gdb.base/siginfo-obj.exp index 5e36b3340680..272d74ac2805 100644 --- i/gdb/testsuite/gdb.base/siginfo-obj.exp +++ w/gdb/testsuite/gdb.base/siginfo-obj.exp @@ -111,11 +111,11 @@ gdb_test "continue" ".*Program received signal SIGSEGV.*" \ "continue to signal, 2nd" set test "set si_addr" -gdb_test "p \$_siginfo._sifields._sigfault.si_addr = 0x666" " = \\(void \\*\\) 0x666" +gdb_test "p \$_siginfo.si_addr = 0x666" " = \\(void \\*\\) 0x666" gdb_test "p \$_siginfo.si_errno = 666" " = 666" gdb_test "p \$_siginfo.si_code = 999" " = 999" gdb_test "p \$_siginfo.si_signo = 11" " = 11" -gdb_test "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey = 123" " = 123" +gdb_test "p \$_siginfo.si_pkey = 123" " = 123" with_test_prefix "validate modified siginfo fields" { gdb_test "break $bp_location" @@ -140,10 +140,10 @@ if {$gcore_created} { "p \$_siginfo.si_errno from core file" gdb_test "p \$_siginfo.si_code" " = $ssi_code" \ "p \$_siginfo.si_code from core file" - gdb_test "p \$_siginfo._sifields._sigfault.si_addr" \ + gdb_test "p \$_siginfo.si_addr" \ " = \\(void \\*\\) $ssi_addr" \ - "p \$_siginfo._sifields._sigfault.si_addr from core file" - gdb_test "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey" \ + "p \$_siginfo.si_addr from core file" + gdb_test "p \$_siginfo.si_pkey" \ " = $ssi_pkey" \ - "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey from core file" + "p \$_siginfo.si_pkey from core file" } Simon ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v5] gdb: align siginfo_t with the Linux kernel definition 2026-08-12 19:08 ` Simon Marchi @ 2026-08-13 14:48 ` Matthieu Longo 2026-08-13 15:49 ` Simon Marchi 2026-08-17 9:33 ` Matthieu Longo 0 siblings, 2 replies; 11+ messages in thread From: Matthieu Longo @ 2026-08-13 14:48 UTC (permalink / raw) To: Simon Marchi, gdb-patches Cc: Luis Machado, Luis Machado, Thiago Jung Bauermann, Srinath Parvathaneni, Maciej W . Rozycki, Andreas Schwab On 12/08/2026 20:08, Simon Marchi wrote: > On 7/28/26 8:32 AM, Matthieu Longo wrote: >> GDB's current definition of siginfo_t is missing many fields present in >> the Linux kernel definition [1]. >> >> These fields are useful for providing detailed, user-friendly diagnostics >> when a fault occurs. Some new AArch64 extensions, such as Permission >> Overlay Enhancement used to implement Protection Keys [2], require the >> debugger to inspect 'si_pkey' alongside 'si_addr' to help the user identify >> the problematic key. >> >> This patch aligns GDB's definition of the __sifields._sigfault member of >> siginfo_t with the definition from the Linux kernel master branch. >> >> To avoid hardcoding the field access paths throughout the codebase, this >> patch also introduces compile-time accessors for the siginfo_t attributes, >> centralizing their definitions in a single location and making future >> updates easier. >> >> Finally, extend the testsuite to verify access to the new si_pkey field >> and its preservation when modifying $_siginfo and when reading core files. >> The tests in siginfo-obj.exp rely on the siginfo_t definition provided by >> glibc's <signal.h>, which does not yet expose all of the fields present in >> the kernel definition. As a result, the tests cannot exercise every newly >> added field and therefore focus on si_pkey, the field motivating this change. >> The test validates that GDB can read and modify the field correctly; it does >> not attempt to generate a real protection-key fault. >> >> [1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/ >> tree/include/uapi/asm-generic/siginfo.h#n69 >> [2]: https://lore.kernel.org/all/20160212210213.ABC488FA@viggo.jf.intel.com/ >> >> Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org> >> --- >> gdb/aarch64-linux-tdep.c | 8 ++-- >> gdb/linux-tdep.c | 52 +++++++++++++++++++--- >> gdb/linux-tdep.h | 60 ++++++++++++++++++++++++++ >> gdb/sparc64-linux-tdep.c | 6 ++- >> gdb/testsuite/gdb.base/siginfo-obj.c | 1 + >> gdb/testsuite/gdb.base/siginfo-obj.exp | 14 ++++++ >> 6 files changed, 131 insertions(+), 10 deletions(-) >> >> diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c >> index f11eccc1bc1..235b35bcfb4 100644 >> --- a/gdb/aarch64-linux-tdep.c >> +++ b/gdb/aarch64-linux-tdep.c >> @@ -2683,13 +2683,15 @@ aarch64_linux_report_signal_info (struct gdbarch *gdbarch, >> >> try >> { >> + using gdb_si = gdb::siginfo_type; >> + using si_key = gdb::siginfo_type::key; >> /* Sigcode tells us if the segfault is actually a memory tag >> violation. */ >> - si_code = parse_and_eval_long ("$_siginfo.si_code"); >> - si_errno = parse_and_eval_long ("$_siginfo.si_errno"); >> + si_code = parse_and_eval_long (gdb_si::get (si_key::siginfo_code)); >> + si_errno = parse_and_eval_long (gdb_si::get (si_key::siginfo_errno)); >> >> fault_addr >> - = parse_and_eval_long ("$_siginfo._sifields._sigfault.si_addr"); >> + = parse_and_eval_long (gdb_si::get (si_key::siginfo_addr)); >> } >> catch (const gdb_exception_error &exception) >> { >> diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c >> index 25d625db595..740043a9292 100644 >> --- a/gdb/linux-tdep.c >> +++ b/gdb/linux-tdep.c >> @@ -272,10 +272,9 @@ static struct type * >> linux_get_siginfo_type (struct gdbarch *gdbarch) >> { >> struct linux_gdbarch_data *linux_gdbarch_data; >> - struct type *void_ptr_type; >> struct type *uid_type, *pid_type; >> struct type *sigval_type, *clock_type; >> - struct type *siginfo_type, *sifields_type; >> + struct type *siginfo_type, *sifields_type, *sigfault_union_type; >> struct type *type; >> >> linux_gdbarch_data = get_linux_gdbarch_data (gdbarch); >> @@ -285,11 +284,22 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) >> type_allocator alloc (gdbarch); >> >> const struct builtin_type *builtin_types = builtin_type (gdbarch); >> + struct type *short_type = builtin_types->builtin_short; >> struct type *int_type = builtin_types->builtin_int; >> struct type *uint_type = builtin_types->builtin_unsigned_int; >> struct type *long_type = builtin_types->builtin_long; >> - >> - void_ptr_type = lookup_pointer_type (builtin_type (gdbarch)->builtin_void); >> + struct type *unsigned_long_type = builtin_types->builtin_unsigned_long; >> + struct type *uint32_type = builtin_types->builtin_uint32; >> + struct type *void_ptr_type >> + = lookup_pointer_type (builtin_type (gdbarch)->builtin_void); >> + >> + /* Compute padding length, i.e. __ADDR_BND_PKEY_PAD. */ >> + unsigned alignof_void_ptr = type_align (void_ptr_type); >> + unsigned padding_size = (alignof_void_ptr < short_type->length () >> + ? short_type->length () >> + : alignof_void_ptr); >> + struct type *addr_bnd_pkey_padding_type >> + = init_vector_type (builtin_types->builtin_uint8, padding_size); >> >> /* sival_t */ >> sigval_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); >> @@ -364,9 +374,41 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) >> append_composite_type_field (type, "si_stime", clock_type); >> append_composite_type_field (sifields_type, "_sigchld", type); >> >> - /* _sigfault */ >> + /* Begin _sigfault's anonymous union. */ >> + sigfault_union_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); >> + /* used on alpha and sparc */ >> + append_composite_type_field (sigfault_union_type, "si_trapno", int_type); >> + /* used when si_code is BUS_MCEERR_AR or BUS_MCEERR_AO. */ >> + append_composite_type_field (sigfault_union_type, "si_addr_lsb", short_type); >> + >> + /* used when si_code=SEGV_BNDERR */ >> + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); >> + append_composite_type_field (type, "_dummy_bnd", addr_bnd_pkey_padding_type); >> + append_composite_type_field (type, "si_lower", void_ptr_type); >> + append_composite_type_field (type, "si_upper", void_ptr_type); >> + append_composite_type_field (sigfault_union_type, "_addr_bnd", type); >> + >> + /* used when si_code=SEGV_PKUERR */ >> + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); >> + append_composite_type_field (type, "_dummy_pkey", addr_bnd_pkey_padding_type); >> + append_composite_type_field (type, "si_pkey", uint32_type); >> + append_composite_type_field (sigfault_union_type, "_addr_pkey", type); >> + >> + /* used when si_code=TRAP_PERF */ >> + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); >> + append_composite_type_field (type, "si_perf_data", unsigned_long_type); >> + append_composite_type_field (type, "si_perf_type", uint32_type); >> + append_composite_type_field (type, "si_perf_flags", uint32_type); >> + append_composite_type_field (sigfault_union_type, "_perf", type); >> + >> + /* End _sigfault's anonymous union. */ >> + >> + /* _sigfault is set by SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */ >> type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); >> append_composite_type_field (type, "si_addr", void_ptr_type); >> + /* Since there is no possibility to declare an anonymous union, >> + using '_anon_union' instead. */ >> + append_composite_type_field (type, "_anon_union", sigfault_union_type); I set the name to "", and it works as you mentioned below. I also fixed the usages in gdb/testsuite/gdb.base/siginfo-obj.exp diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index 4660772752d..bbc4009d43c 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -406,9 +406,8 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) /* _sigfault is set by SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */ type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); append_composite_type_field (type, "si_addr", void_ptr_type); - /* Since there is no possibility to declare an anonymous union, - using '_anon_union' instead. */ - append_composite_type_field (type, "_anon_union", sigfault_union_type); + /* Note: this is an anonymous union. */ + append_composite_type_field (type, "", sigfault_union_type); append_composite_type_field (sifields_type, "_sigfault", type); /* _sigpoll */ diff --git a/gdb/linux-tdep.h b/gdb/linux-tdep.h index 43ed38c6633..1f40756eb2f 100644 --- a/gdb/linux-tdep.h +++ b/gdb/linux-tdep.h @@ -143,14 +143,14 @@ struct siginfo_type /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */ "$_siginfo._sifields._sigfault.si_addr", - "$_siginfo._sifields._sigfault._anon_union.si_trapno", - "$_siginfo._sifields._sigfault._anon_union.si_addr_lsb", - "$_siginfo._sifields._sigfault._anon_union._addr_bnd.si_lower", - "$_siginfo._sifields._sigfault._anon_union._addr_bnd.si_upper", - "$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey", - "$_siginfo._sifields._sigfault._anon_union._perf.si_perf_data", - "$_siginfo._sifields._sigfault._anon_union._perf.si_perf_type", - "$_siginfo._sifields._sigfault._anon_union._perf.si_perf_flags", + "$_siginfo._sifields._sigfault.si_trapno", + "$_siginfo._sifields._sigfault.si_addr_lsb", + "$_siginfo._sifields._sigfault._addr_bnd.si_lower", + "$_siginfo._sifields._sigfault._addr_bnd.si_upper", + "$_siginfo._sifields._sigfault._addr_pkey.si_pkey", + "$_siginfo._sifields._sigfault._perf.si_perf_data", + "$_siginfo._sifields._sigfault._perf.si_perf_type", + "$_siginfo._sifields._sigfault._perf.si_perf_flags", }; return paths[static_cast<size_t> (attr_)]; } diff --git a/gdb/testsuite/gdb.base/siginfo-obj.exp b/gdb/testsuite/gdb.base/siginfo-obj.exp index 5e36b334068..a724a634dc0 100644 --- a/gdb/testsuite/gdb.base/siginfo-obj.exp +++ b/gdb/testsuite/gdb.base/siginfo-obj.exp @@ -115,7 +115,7 @@ gdb_test "p \$_siginfo._sifields._sigfault.si_addr = 0x666" " = \\(void \\*\\) 0 gdb_test "p \$_siginfo.si_errno = 666" " = 666" gdb_test "p \$_siginfo.si_code = 999" " = 999" gdb_test "p \$_siginfo.si_signo = 11" " = 11" -gdb_test "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey = 123" " = 123" +gdb_test "p \$_siginfo._sifields._sigfault._addr_pkey.si_pkey = 123" " = 123" with_test_prefix "validate modified siginfo fields" { gdb_test "break $bp_location" @@ -143,7 +143,7 @@ if {$gcore_created} { gdb_test "p \$_siginfo._sifields._sigfault.si_addr" \ " = \\(void \\*\\) $ssi_addr" \ "p \$_siginfo._sifields._sigfault.si_addr from core file" - gdb_test "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey" \ + gdb_test "p \$_siginfo._sifields._sigfault._addr_pkey.si_pkey" \ " = $ssi_pkey" \ - "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey from core file" + "p \$_siginfo._sifields._sigfault._addr_pkey.si_pkey from core file" } > > Can you expand on why it's not possible to have an anonymous union? It > is certainly possible to have anonymous unions described in DWARF, which > are then translated to struct types. > I simply could not find how to implement it. It might be useful to add to the documentation of append_composite_type_field_aligned() or maybe better, to the comment in gdb/gdbtypes.h above the declaration of append_composite_type_field(), a sentence explaining what is the effect of providing an empty name. diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index dd2d24fa8e2..e4fedd886c4 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -2431,11 +2431,12 @@ extern struct type *init_pointer_type (type_allocator &alloc, int bit, extern struct type *init_fixed_point_type (type_allocator &, int, int, const char *); -/* Helper functions to construct a struct or record type. An - initially empty type is created using arch_composite_type(). - Fields are then added using append_composite_type_field*(). A union - type has its size set to the largest field. A struct type has each - field packed against the previous. */ +/* Helper functions to construct a struct or record type. An initially empty + type is created using arch_composite_type(). Fields are then added using + append_composite_type_field*(). + A union type has its size set to the largest field. A struct type has each + field packed against the previous. + If no name is specified, the type is anonymous. */ extern struct type *arch_composite_type (struct gdbarch *gdbarch, const char *name, enum type_code code); > I think that the ideal user experience would be for users to be able to > access fields the same way that they do in the code, that is > `si.si_pkey`. All the _sigfault/_addr_pkey/etc parts are implementation > details that could change. > > On top of your patch, if I just delete all the internal field names, it > seems to work just fine, see patch below. In the end it models > something like this in C: > I am not against it. However, could this suggestion be addressed in a different patch ? Simplifying the existing pathes to si_* values with anonymous structs would increase the impact of the original patch, with potentially additional testing and carefulness required for others architectures (for example, see gdb/nat/amd64-linux-siginfo.c L269). Matthieu > struct siginto_t > { > union > { > // kill > struct > { > int si_pid; > int si_uid; > }; > > // timer > struct > { > int si_tid; > int si_overrun; > int si_sys_private; > }; > > ... > }; > }; > > > diff --git i/gdb/linux-tdep.c w/gdb/linux-tdep.c > index 4660772752d6..f21fa1e18578 100644 > --- i/gdb/linux-tdep.c > +++ w/gdb/linux-tdep.c > @@ -349,21 +349,21 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) > type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); > append_composite_type_field (type, "si_pid", pid_type); > append_composite_type_field (type, "si_uid", uid_type); > - append_composite_type_field (sifields_type, "_kill", type); > + append_composite_type_field (sifields_type, "", type); > > /* _timer */ > type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); > append_composite_type_field (type, "si_tid", int_type); > append_composite_type_field (type, "si_overrun", int_type); > append_composite_type_field (type, "si_sigval", sigval_type); > - append_composite_type_field (sifields_type, "_timer", type); > + append_composite_type_field (sifields_type, "", type); > > /* _rt */ > type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); > append_composite_type_field (type, "si_pid", pid_type); > append_composite_type_field (type, "si_uid", uid_type); > append_composite_type_field (type, "si_sigval", sigval_type); > - append_composite_type_field (sifields_type, "_rt", type); > + append_composite_type_field (sifields_type, "", type); > > /* _sigchld */ > type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); > @@ -372,7 +372,7 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) > append_composite_type_field (type, "si_status", int_type); > append_composite_type_field (type, "si_utime", clock_type); > append_composite_type_field (type, "si_stime", clock_type); > - append_composite_type_field (sifields_type, "_sigchld", type); > + append_composite_type_field (sifields_type, "", type); > > /* Begin _sigfault's anonymous union. */ > sigfault_union_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); > @@ -386,20 +386,20 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) > append_composite_type_field (type, "_dummy_bnd", addr_bnd_pkey_padding_type); > append_composite_type_field (type, "si_lower", void_ptr_type); > append_composite_type_field (type, "si_upper", void_ptr_type); > - append_composite_type_field (sigfault_union_type, "_addr_bnd", type); > + append_composite_type_field (sigfault_union_type, "", type); > > /* used when si_code=SEGV_PKUERR */ > type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); > append_composite_type_field (type, "_dummy_pkey", addr_bnd_pkey_padding_type); > append_composite_type_field (type, "si_pkey", uint32_type); > - append_composite_type_field (sigfault_union_type, "_addr_pkey", type); > + append_composite_type_field (sigfault_union_type, "", type); > > /* used when si_code=TRAP_PERF */ > type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); > append_composite_type_field (type, "si_perf_data", unsigned_long_type); > append_composite_type_field (type, "si_perf_type", uint32_type); > append_composite_type_field (type, "si_perf_flags", uint32_type); > - append_composite_type_field (sigfault_union_type, "_perf", type); > + append_composite_type_field (sigfault_union_type, "", type); > > /* End _sigfault's anonymous union. */ > > @@ -408,21 +408,21 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) > append_composite_type_field (type, "si_addr", void_ptr_type); > /* Since there is no possibility to declare an anonymous union, > using '_anon_union' instead. */ > - append_composite_type_field (type, "_anon_union", sigfault_union_type); > - append_composite_type_field (sifields_type, "_sigfault", type); > + append_composite_type_field (type, "", sigfault_union_type); > + append_composite_type_field (sifields_type, "", type); > > /* _sigpoll */ > type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); > append_composite_type_field (type, "si_band", long_type); > append_composite_type_field (type, "si_fd", int_type); > - append_composite_type_field (sifields_type, "_sigpoll", type); > + append_composite_type_field (sifields_type, "", type); > > /* _sigsys */ > type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); > append_composite_type_field (type, "_call_addr", void_ptr_type); > append_composite_type_field (type, "_syscall", int_type); > append_composite_type_field (type, "_arch", uint_type); > - append_composite_type_field (sifields_type, "_sigsys", type); > + append_composite_type_field (sifields_type, "", type); > > /* struct siginfo */ > siginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); > @@ -431,7 +431,7 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) > append_composite_type_field (siginfo_type, "si_errno", int_type); > append_composite_type_field (siginfo_type, "si_code", int_type); > append_composite_type_field_aligned (siginfo_type, > - "_sifields", sifields_type, > + "", sifields_type, > long_type->length ()); > > linux_gdbarch_data->siginfo_type = siginfo_type; > diff --git i/gdb/testsuite/gdb.base/siginfo-obj.exp w/gdb/testsuite/gdb.base/siginfo-obj.exp > index 5e36b3340680..272d74ac2805 100644 > --- i/gdb/testsuite/gdb.base/siginfo-obj.exp > +++ w/gdb/testsuite/gdb.base/siginfo-obj.exp > @@ -111,11 +111,11 @@ gdb_test "continue" ".*Program received signal SIGSEGV.*" \ > "continue to signal, 2nd" > > set test "set si_addr" > -gdb_test "p \$_siginfo._sifields._sigfault.si_addr = 0x666" " = \\(void \\*\\) 0x666" > +gdb_test "p \$_siginfo.si_addr = 0x666" " = \\(void \\*\\) 0x666" > gdb_test "p \$_siginfo.si_errno = 666" " = 666" > gdb_test "p \$_siginfo.si_code = 999" " = 999" > gdb_test "p \$_siginfo.si_signo = 11" " = 11" > -gdb_test "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey = 123" " = 123" > +gdb_test "p \$_siginfo.si_pkey = 123" " = 123" > > with_test_prefix "validate modified siginfo fields" { > gdb_test "break $bp_location" > @@ -140,10 +140,10 @@ if {$gcore_created} { > "p \$_siginfo.si_errno from core file" > gdb_test "p \$_siginfo.si_code" " = $ssi_code" \ > "p \$_siginfo.si_code from core file" > - gdb_test "p \$_siginfo._sifields._sigfault.si_addr" \ > + gdb_test "p \$_siginfo.si_addr" \ > " = \\(void \\*\\) $ssi_addr" \ > - "p \$_siginfo._sifields._sigfault.si_addr from core file" > - gdb_test "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey" \ > + "p \$_siginfo.si_addr from core file" > + gdb_test "p \$_siginfo.si_pkey" \ > " = $ssi_pkey" \ > - "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey from core file" > + "p \$_siginfo.si_pkey from core file" > } > > Simon ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v5] gdb: align siginfo_t with the Linux kernel definition 2026-08-13 14:48 ` Matthieu Longo @ 2026-08-13 15:49 ` Simon Marchi 2026-08-14 10:05 ` Matthieu Longo 2026-08-17 9:33 ` Matthieu Longo 1 sibling, 1 reply; 11+ messages in thread From: Simon Marchi @ 2026-08-13 15:49 UTC (permalink / raw) To: Matthieu Longo, gdb-patches Cc: Luis Machado, Luis Machado, Thiago Jung Bauermann, Srinath Parvathaneni, Maciej W . Rozycki, Andreas Schwab On 8/13/26 10:48 AM, Matthieu Longo wrote: > diff --git a/gdb/linux-tdep.h b/gdb/linux-tdep.h > index 43ed38c6633..1f40756eb2f 100644 > --- a/gdb/linux-tdep.h > +++ b/gdb/linux-tdep.h > @@ -143,14 +143,14 @@ struct siginfo_type > > /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */ > "$_siginfo._sifields._sigfault.si_addr", > - "$_siginfo._sifields._sigfault._anon_union.si_trapno", > - "$_siginfo._sifields._sigfault._anon_union.si_addr_lsb", > - "$_siginfo._sifields._sigfault._anon_union._addr_bnd.si_lower", > - "$_siginfo._sifields._sigfault._anon_union._addr_bnd.si_upper", > - "$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey", > - "$_siginfo._sifields._sigfault._anon_union._perf.si_perf_data", > - "$_siginfo._sifields._sigfault._anon_union._perf.si_perf_type", > - "$_siginfo._sifields._sigfault._anon_union._perf.si_perf_flags", > + "$_siginfo._sifields._sigfault.si_trapno", > + "$_siginfo._sifields._sigfault.si_addr_lsb", > + "$_siginfo._sifields._sigfault._addr_bnd.si_lower", > + "$_siginfo._sifields._sigfault._addr_bnd.si_upper", > + "$_siginfo._sifields._sigfault._addr_pkey.si_pkey", > + "$_siginfo._sifields._sigfault._perf.si_perf_data", > + "$_siginfo._sifields._sigfault._perf.si_perf_type", > + "$_siginfo._sifields._sigfault._perf.si_perf_flags", Ok, my thinking was to also get rid of `_sifields`, `_sigfault`, `_addr_bnd`, `_addr_pkey` and `_perf` (and maybe others), so that a user would access the fields like: $_siginfo.si_perf_flags just like you access it in the source code (through the macro "magic"): siginfo_obj->si_perf_flags But I had not realized that _sifields and _siginfo is pre-existing, so we can't simply change it, that would be a backwards incompatible change. So for now, for consistency, it makes sense to continue in the existing direction, with the named fields. Removing `_anon_union` is good though. > }; > return paths[static_cast<size_t> (attr_)]; > } > diff --git a/gdb/testsuite/gdb.base/siginfo-obj.exp b/gdb/testsuite/gdb.base/siginfo-obj.exp > index 5e36b334068..a724a634dc0 100644 > --- a/gdb/testsuite/gdb.base/siginfo-obj.exp > +++ b/gdb/testsuite/gdb.base/siginfo-obj.exp > @@ -115,7 +115,7 @@ gdb_test "p \$_siginfo._sifields._sigfault.si_addr = 0x666" " = \\(void \\*\\) 0 > gdb_test "p \$_siginfo.si_errno = 666" " = 666" > gdb_test "p \$_siginfo.si_code = 999" " = 999" > gdb_test "p \$_siginfo.si_signo = 11" " = 11" > -gdb_test "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey = 123" " = 123" > +gdb_test "p \$_siginfo._sifields._sigfault._addr_pkey.si_pkey = 123" " = 123" > > with_test_prefix "validate modified siginfo fields" { > gdb_test "break $bp_location" > @@ -143,7 +143,7 @@ if {$gcore_created} { > gdb_test "p \$_siginfo._sifields._sigfault.si_addr" \ > " = \\(void \\*\\) $ssi_addr" \ > "p \$_siginfo._sifields._sigfault.si_addr from core file" > - gdb_test "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey" \ > + gdb_test "p \$_siginfo._sifields._sigfault._addr_pkey.si_pkey" \ That looks consistent with what currently exists, so that's good. >>> Can you expand on why it's not possible to have an anonymous union? It >> is certainly possible to have anonymous unions described in DWARF, which >> are then translated to struct types. >> > I simply could not find how to implement it. > It might be useful to add to the documentation of append_composite_type_field_aligned() or maybe > better, to the comment in gdb/gdbtypes.h above the declaration of append_composite_type_field(), a > sentence explaining what is the effect of providing an empty name. Agreed, that documentation change would be welcome. > diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h > index dd2d24fa8e2..e4fedd886c4 100644 > --- a/gdb/gdbtypes.h > +++ b/gdb/gdbtypes.h > @@ -2431,11 +2431,12 @@ extern struct type *init_pointer_type (type_allocator &alloc, int bit, > extern struct type *init_fixed_point_type (type_allocator &, int, int, > const char *); > > -/* Helper functions to construct a struct or record type. An > - initially empty type is created using arch_composite_type(). > - Fields are then added using append_composite_type_field*(). A union > - type has its size set to the largest field. A struct type has each > - field packed against the previous. */ > +/* Helper functions to construct a struct or record type. An initially empty > + type is created using arch_composite_type(). Fields are then added using > + append_composite_type_field*(). > + A union type has its size set to the largest field. A struct type has each > + field packed against the previous. > + If no name is specified, the type is anonymous. */ > > extern struct type *arch_composite_type (struct gdbarch *gdbarch, > const char *name, enum type_code code); It's not the name of the type that matters, it's the name of the field, when added with append_composite_type_field, that does. When a struct or union field has no name, it is anonymous, and its fields are visible directly in the parent scope. I mean, it's true that passing no name creates an anonymous type, but that's not what matters in the problem at hand. Also, it should be clearer: "no name" means empty string or nullptr? >> I think that the ideal user experience would be for users to be able to >> access fields the same way that they do in the code, that is >> `si.si_pkey`. All the _sigfault/_addr_pkey/etc parts are implementation >> details that could change. >> >> On top of your patch, if I just delete all the internal field names, it >> seems to work just fine, see patch below. In the end it models >> something like this in C: >> > I am not against it. > However, could this suggestion be addressed in a different patch ? As I said above, we can't just rename the existing fields, there is probably code out there relying on those names. We could add new fields, so the structure would just contain both the named hierarchy and the anonymous hierarchy, the fields would just be duplicated. That's fine if the structure is read-only, but if for some reason some user code needs to change a field (I don't really know why it would do that), then that would be awkward, since it would only update one copy. Anyway, that's for later (if ever). > Simplifying the existing pathes to si_* values with anonymous structs would increase the impact of > the original patch, with potentially additional testing and carefulness required for others > architectures (for example, see gdb/nat/amd64-linux-siginfo.c L269). Hmm, I don't think we need to touch this nat code. I am only talking about the type of the $_siginfo convenience variable, which we build manually with those arch_composite_type & co calls. Simon ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v5] gdb: align siginfo_t with the Linux kernel definition 2026-08-13 15:49 ` Simon Marchi @ 2026-08-14 10:05 ` Matthieu Longo 2026-08-17 16:59 ` Simon Marchi 0 siblings, 1 reply; 11+ messages in thread From: Matthieu Longo @ 2026-08-14 10:05 UTC (permalink / raw) To: Simon Marchi, gdb-patches Cc: Luis Machado, Luis Machado, Thiago Jung Bauermann, Srinath Parvathaneni, Maciej W . Rozycki, Andreas Schwab On 13/08/2026 16:49, Simon Marchi wrote: > On 8/13/26 10:48 AM, Matthieu Longo wrote: >> diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h >> index dd2d24fa8e2..e4fedd886c4 100644 >> --- a/gdb/gdbtypes.h >> +++ b/gdb/gdbtypes.h >> @@ -2431,11 +2431,12 @@ extern struct type *init_pointer_type (type_allocator &alloc, int bit, >> extern struct type *init_fixed_point_type (type_allocator &, int, int, >> const char *); >> >> -/* Helper functions to construct a struct or record type. An >> - initially empty type is created using arch_composite_type(). >> - Fields are then added using append_composite_type_field*(). A union >> - type has its size set to the largest field. A struct type has each >> - field packed against the previous. */ >> +/* Helper functions to construct a struct or record type. An initially empty >> + type is created using arch_composite_type(). Fields are then added using >> + append_composite_type_field*(). >> + A union type has its size set to the largest field. A struct type has each >> + field packed against the previous. >> + If no name is specified, the type is anonymous. */ >> >> extern struct type *arch_composite_type (struct gdbarch *gdbarch, >> const char *name, enum type_code code); > > It's not the name of the type that matters, it's the name of the field, > when added with append_composite_type_field, that does. When a struct > or union field has no name, it is anonymous, and its fields are visible > directly in the parent scope. > > I mean, it's true that passing no name creates an anonymous type, but > that's not what matters in the problem at hand. Also, it should be > clearer: "no name" means empty string or nullptr? > I moved this to another patch since it is not directly related to this patch. https://inbox.sourceware.org/gdb-patches/20260813172736.500755-1-matthieu.longo@arm.com/ >>> I think that the ideal user experience would be for users to be able to >>> access fields the same way that they do in the code, that is >>> `si.si_pkey`. All the _sigfault/_addr_pkey/etc parts are implementation >>> details that could change. >>> >>> On top of your patch, if I just delete all the internal field names, it >>> seems to work just fine, see patch below. In the end it models >>> something like this in C: >>> >> I am not against it. >> However, could this suggestion be addressed in a different patch ? > > As I said above, we can't just rename the existing fields, there is > probably code out there relying on those names. > > We could add new fields, so the structure would just contain both the > named hierarchy and the anonymous hierarchy, the fields would just be > duplicated. That's fine if the structure is read-only, but if for some > reason some user code needs to change a field (I don't really know why > it would do that), then that would be awkward, since it would only > update one copy. > > Anyway, that's for later (if ever). > >> Simplifying the existing pathes to si_* values with anonymous structs would increase the impact of >> the original patch, with potentially additional testing and carefulness required for others >> architectures (for example, see gdb/nat/amd64-linux-siginfo.c L269). > > Hmm, I don't think we need to touch this nat code. I am only talking > about the type of the $_siginfo convenience variable, which we build > manually with those arch_composite_type & co calls. > > Simon So, if I understood you well, you don't want to touch the current definition in linux_get_siginfo_type(). Instead, you propose to define a new siginfo type as the data structure below. Then, siginfo data should be cast to the new user-facing type before being returned. Is this correct ? #define __ARCH_SI_CLOCK_T unsigned long #define __ADDR_BND_PKEY_PAD (__alignof__(void *) < sizeof(short) ? \ sizeof(short) : __alignof__(void *)) struct siginfo { int si_signo; int si_errno; int si_code; /* Beginning of __sifields. */ union { /* _kill, signals, _sigchld and _timer are tangled, so should be flattened together. */ struct { union { int si_pid; // _kill, _rt, _sigchld int si_tid; // _timer }; union { uint32_t si_uid; // _kill, _rt, _sigchld int si_overrun; // _timer }; union { struct { int si_status; __ARCH_SI_CLOCK_T si_utime; __ARCH_SI_CLOCK_T si_stime; }; // _sigchld struct { union { int si_int; void *si_ptr; } si_value; // _rt, _timer int si_sys_private; // _timer }; }; }; /* _sigfault, _sigpoll and _sigsys are not sharing anything, so are flattened on their own. */ struct { void *si_addr; union { int si_trapno; short si_addr_lsb; struct { char _dummy_padding_1[__ADDR_BND_PKEY_PAD]; void *si_lower; void *si_upper; }; /* _addr_bnd */ struct { char _dummy_padding_2[__ADDR_BND_PKEY_PAD]; uint32_t si_pkey; }; /* _addr_pkey */ struct { unsigned long si_perf_data; uint32_t si_perf_type; uint32_t si_perf_flags; }; /* _perf */ }; }; /* _sigfault */ struct { long si_band; int si_fd; }; /* _sigpoll */ struct { void *si_call_addr; int si_syscall; unsigned int si_arch; }; /* _sigsys */ }; /* End of __sifields. */ }; Matthieu ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v5] gdb: align siginfo_t with the Linux kernel definition 2026-08-14 10:05 ` Matthieu Longo @ 2026-08-17 16:59 ` Simon Marchi 0 siblings, 0 replies; 11+ messages in thread From: Simon Marchi @ 2026-08-17 16:59 UTC (permalink / raw) To: Matthieu Longo, gdb-patches Cc: Luis Machado, Luis Machado, Thiago Jung Bauermann, Srinath Parvathaneni, Maciej W . Rozycki, Andreas Schwab On 8/14/26 6:05 AM, Matthieu Longo wrote: > So, if I understood you well, you don't want to touch the current definition in > linux_get_siginfo_type(). Instead, you propose to define a new siginfo type as the data structure > below. Then, siginfo data should be cast to the new user-facing type before being returned. > Is this correct ? I think I was a bit confused about how the siginfo convenience variable is constructed. I thought we had code to set the value of individual fields, but that does not make sense. How it actually works is that we read the bytes from the target, and the type constructed by linux_get_siginfo_type (not only Linux, but all platforms) must overlay perfectly the actual byte layout from the target. But in any case, I don't think that anything from nat/ is used during that process normally. The type of $_siginfo comes from a struct type constructed with arch_composite_type & co calls, not from a literal struct in the GDB source code. > #define __ARCH_SI_CLOCK_T unsigned long > #define __ADDR_BND_PKEY_PAD (__alignof__(void *) < sizeof(short) ? \ > sizeof(short) : __alignof__(void *)) > > struct siginfo { > int si_signo; > int si_errno; > int si_code; > > /* Beginning of __sifields. */ > union { > > /* _kill, signals, _sigchld and _timer are tangled, so should be flattened > together. */ > struct { > union { > int si_pid; // _kill, _rt, _sigchld > int si_tid; // _timer > }; > union { > uint32_t si_uid; // _kill, _rt, _sigchld > int si_overrun; // _timer > }; > union { > struct { > int si_status; > __ARCH_SI_CLOCK_T si_utime; > __ARCH_SI_CLOCK_T si_stime; > }; // _sigchld > > struct { > union { > int si_int; > void *si_ptr; > } si_value; // _rt, _timer > int si_sys_private; // _timer > }; > }; > }; > > /* _sigfault, _sigpoll and _sigsys are not sharing anything, so are > flattened on their own. */ > > struct { > void *si_addr; > union { > int si_trapno; > short si_addr_lsb; > struct { > char _dummy_padding_1[__ADDR_BND_PKEY_PAD]; > void *si_lower; > void *si_upper; > }; /* _addr_bnd */ > struct { > char _dummy_padding_2[__ADDR_BND_PKEY_PAD]; > uint32_t si_pkey; > }; /* _addr_pkey */ > struct { > unsigned long si_perf_data; > uint32_t si_perf_type; > uint32_t si_perf_flags; > }; /* _perf */ > }; > }; /* _sigfault */ > > struct { > long si_band; > int si_fd; > }; /* _sigpoll */ > > struct { > void *si_call_addr; > int si_syscall; > unsigned int si_arch; > }; /* _sigsys */ > > }; /* End of __sifields. */ > }; This is a bit hard to read, but yeah I guess that having all the struct and union fields anonymouns would make the si_* fields accessible from the top-level, and that would be ideal from a UX point of view. So, we would like to model a structure like the above, but constructed with arch_composite_type & co calls. But we'd need the old names to keep working. You don't have to worry about this though (unless you want to), it's out of scope of your original patch. Simon ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v5] gdb: align siginfo_t with the Linux kernel definition 2026-08-13 14:48 ` Matthieu Longo 2026-08-13 15:49 ` Simon Marchi @ 2026-08-17 9:33 ` Matthieu Longo 2026-08-17 16:42 ` Simon Marchi 1 sibling, 1 reply; 11+ messages in thread From: Matthieu Longo @ 2026-08-17 9:33 UTC (permalink / raw) To: Simon Marchi, gdb-patches Cc: Luis Machado, Luis Machado, Thiago Jung Bauermann, Srinath Parvathaneni, Maciej W . Rozycki, Andreas Schwab On 13/08/2026 15:48, Matthieu Longo wrote: > On 12/08/2026 20:08, Simon Marchi wrote: >> On 7/28/26 8:32 AM, Matthieu Longo wrote: >>> GDB's current definition of siginfo_t is missing many fields present in >>> the Linux kernel definition [1]. >>> >>> These fields are useful for providing detailed, user-friendly diagnostics >>> when a fault occurs. Some new AArch64 extensions, such as Permission >>> Overlay Enhancement used to implement Protection Keys [2], require the >>> debugger to inspect 'si_pkey' alongside 'si_addr' to help the user identify >>> the problematic key. >>> >>> This patch aligns GDB's definition of the __sifields._sigfault member of >>> siginfo_t with the definition from the Linux kernel master branch. >>> >>> To avoid hardcoding the field access paths throughout the codebase, this >>> patch also introduces compile-time accessors for the siginfo_t attributes, >>> centralizing their definitions in a single location and making future >>> updates easier. >>> >>> Finally, extend the testsuite to verify access to the new si_pkey field >>> and its preservation when modifying $_siginfo and when reading core files. >>> The tests in siginfo-obj.exp rely on the siginfo_t definition provided by >>> glibc's <signal.h>, which does not yet expose all of the fields present in >>> the kernel definition. As a result, the tests cannot exercise every newly >>> added field and therefore focus on si_pkey, the field motivating this change. >>> The test validates that GDB can read and modify the field correctly; it does >>> not attempt to generate a real protection-key fault. >>> >>> [1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/ >>> tree/include/uapi/asm-generic/siginfo.h#n69 >>> [2]: https://lore.kernel.org/all/20160212210213.ABC488FA@viggo.jf.intel.com/ >>> >>> Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org> >>> --- >>> gdb/aarch64-linux-tdep.c | 8 ++-- >>> gdb/linux-tdep.c | 52 +++++++++++++++++++--- >>> gdb/linux-tdep.h | 60 ++++++++++++++++++++++++++ >>> gdb/sparc64-linux-tdep.c | 6 ++- >>> gdb/testsuite/gdb.base/siginfo-obj.c | 1 + >>> gdb/testsuite/gdb.base/siginfo-obj.exp | 14 ++++++ >>> 6 files changed, 131 insertions(+), 10 deletions(-) >>> >>> diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c >>> index f11eccc1bc1..235b35bcfb4 100644 >>> --- a/gdb/aarch64-linux-tdep.c >>> +++ b/gdb/aarch64-linux-tdep.c >>> @@ -2683,13 +2683,15 @@ aarch64_linux_report_signal_info (struct gdbarch *gdbarch, >>> >>> try >>> { >>> + using gdb_si = gdb::siginfo_type; >>> + using si_key = gdb::siginfo_type::key; >>> /* Sigcode tells us if the segfault is actually a memory tag >>> violation. */ >>> - si_code = parse_and_eval_long ("$_siginfo.si_code"); >>> - si_errno = parse_and_eval_long ("$_siginfo.si_errno"); >>> + si_code = parse_and_eval_long (gdb_si::get (si_key::siginfo_code)); >>> + si_errno = parse_and_eval_long (gdb_si::get (si_key::siginfo_errno)); >>> >>> fault_addr >>> - = parse_and_eval_long ("$_siginfo._sifields._sigfault.si_addr"); >>> + = parse_and_eval_long (gdb_si::get (si_key::siginfo_addr)); >>> } >>> catch (const gdb_exception_error &exception) >>> { >>> diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c >>> index 25d625db595..740043a9292 100644 >>> --- a/gdb/linux-tdep.c >>> +++ b/gdb/linux-tdep.c >>> @@ -272,10 +272,9 @@ static struct type * >>> linux_get_siginfo_type (struct gdbarch *gdbarch) >>> { >>> struct linux_gdbarch_data *linux_gdbarch_data; >>> - struct type *void_ptr_type; >>> struct type *uid_type, *pid_type; >>> struct type *sigval_type, *clock_type; >>> - struct type *siginfo_type, *sifields_type; >>> + struct type *siginfo_type, *sifields_type, *sigfault_union_type; >>> struct type *type; >>> >>> linux_gdbarch_data = get_linux_gdbarch_data (gdbarch); >>> @@ -285,11 +284,22 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) >>> type_allocator alloc (gdbarch); >>> >>> const struct builtin_type *builtin_types = builtin_type (gdbarch); >>> + struct type *short_type = builtin_types->builtin_short; >>> struct type *int_type = builtin_types->builtin_int; >>> struct type *uint_type = builtin_types->builtin_unsigned_int; >>> struct type *long_type = builtin_types->builtin_long; >>> - >>> - void_ptr_type = lookup_pointer_type (builtin_type (gdbarch)->builtin_void); >>> + struct type *unsigned_long_type = builtin_types->builtin_unsigned_long; >>> + struct type *uint32_type = builtin_types->builtin_uint32; >>> + struct type *void_ptr_type >>> + = lookup_pointer_type (builtin_type (gdbarch)->builtin_void); >>> + >>> + /* Compute padding length, i.e. __ADDR_BND_PKEY_PAD. */ >>> + unsigned alignof_void_ptr = type_align (void_ptr_type); >>> + unsigned padding_size = (alignof_void_ptr < short_type->length () >>> + ? short_type->length () >>> + : alignof_void_ptr); >>> + struct type *addr_bnd_pkey_padding_type >>> + = init_vector_type (builtin_types->builtin_uint8, padding_size); >>> >>> /* sival_t */ >>> sigval_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); >>> @@ -364,9 +374,41 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) >>> append_composite_type_field (type, "si_stime", clock_type); >>> append_composite_type_field (sifields_type, "_sigchld", type); >>> >>> - /* _sigfault */ >>> + /* Begin _sigfault's anonymous union. */ >>> + sigfault_union_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); >>> + /* used on alpha and sparc */ >>> + append_composite_type_field (sigfault_union_type, "si_trapno", int_type); >>> + /* used when si_code is BUS_MCEERR_AR or BUS_MCEERR_AO. */ >>> + append_composite_type_field (sigfault_union_type, "si_addr_lsb", short_type); >>> + >>> + /* used when si_code=SEGV_BNDERR */ >>> + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); >>> + append_composite_type_field (type, "_dummy_bnd", addr_bnd_pkey_padding_type); >>> + append_composite_type_field (type, "si_lower", void_ptr_type); >>> + append_composite_type_field (type, "si_upper", void_ptr_type); >>> + append_composite_type_field (sigfault_union_type, "_addr_bnd", type); >>> + >>> + /* used when si_code=SEGV_PKUERR */ >>> + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); >>> + append_composite_type_field (type, "_dummy_pkey", addr_bnd_pkey_padding_type); >>> + append_composite_type_field (type, "si_pkey", uint32_type); >>> + append_composite_type_field (sigfault_union_type, "_addr_pkey", type); >>> + >>> + /* used when si_code=TRAP_PERF */ >>> + type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); >>> + append_composite_type_field (type, "si_perf_data", unsigned_long_type); >>> + append_composite_type_field (type, "si_perf_type", uint32_type); >>> + append_composite_type_field (type, "si_perf_flags", uint32_type); >>> + append_composite_type_field (sigfault_union_type, "_perf", type); >>> + >>> + /* End _sigfault's anonymous union. */ >>> + >>> + /* _sigfault is set by SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */ >>> type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); >>> append_composite_type_field (type, "si_addr", void_ptr_type); >>> + /* Since there is no possibility to declare an anonymous union, >>> + using '_anon_union' instead. */ >>> + append_composite_type_field (type, "_anon_union", sigfault_union_type); > > I set the name to "", and it works as you mentioned below. > I also fixed the usages in gdb/testsuite/gdb.base/siginfo-obj.exp > > diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c > index 4660772752d..bbc4009d43c 100644 > --- a/gdb/linux-tdep.c > +++ b/gdb/linux-tdep.c > @@ -406,9 +406,8 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) > /* _sigfault is set by SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */ > type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); > append_composite_type_field (type, "si_addr", void_ptr_type); > - /* Since there is no possibility to declare an anonymous union, > - using '_anon_union' instead. */ > - append_composite_type_field (type, "_anon_union", sigfault_union_type); > + /* Note: this is an anonymous union. */ > + append_composite_type_field (type, "", sigfault_union_type); > append_composite_type_field (sifields_type, "_sigfault", type); > > /* _sigpoll */ > diff --git a/gdb/linux-tdep.h b/gdb/linux-tdep.h > index 43ed38c6633..1f40756eb2f 100644 > --- a/gdb/linux-tdep.h > +++ b/gdb/linux-tdep.h > @@ -143,14 +143,14 @@ struct siginfo_type > > /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */ > "$_siginfo._sifields._sigfault.si_addr", > - "$_siginfo._sifields._sigfault._anon_union.si_trapno", > - "$_siginfo._sifields._sigfault._anon_union.si_addr_lsb", > - "$_siginfo._sifields._sigfault._anon_union._addr_bnd.si_lower", > - "$_siginfo._sifields._sigfault._anon_union._addr_bnd.si_upper", > - "$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey", > - "$_siginfo._sifields._sigfault._anon_union._perf.si_perf_data", > - "$_siginfo._sifields._sigfault._anon_union._perf.si_perf_type", > - "$_siginfo._sifields._sigfault._anon_union._perf.si_perf_flags", > + "$_siginfo._sifields._sigfault.si_trapno", > + "$_siginfo._sifields._sigfault.si_addr_lsb", > + "$_siginfo._sifields._sigfault._addr_bnd.si_lower", > + "$_siginfo._sifields._sigfault._addr_bnd.si_upper", > + "$_siginfo._sifields._sigfault._addr_pkey.si_pkey", > + "$_siginfo._sifields._sigfault._perf.si_perf_data", > + "$_siginfo._sifields._sigfault._perf.si_perf_type", > + "$_siginfo._sifields._sigfault._perf.si_perf_flags", > }; > return paths[static_cast<size_t> (attr_)]; > } > diff --git a/gdb/testsuite/gdb.base/siginfo-obj.exp b/gdb/testsuite/gdb.base/siginfo-obj.exp > index 5e36b334068..a724a634dc0 100644 > --- a/gdb/testsuite/gdb.base/siginfo-obj.exp > +++ b/gdb/testsuite/gdb.base/siginfo-obj.exp > @@ -115,7 +115,7 @@ gdb_test "p \$_siginfo._sifields._sigfault.si_addr = 0x666" " = \\(void \\*\\) 0 > gdb_test "p \$_siginfo.si_errno = 666" " = 666" > gdb_test "p \$_siginfo.si_code = 999" " = 999" > gdb_test "p \$_siginfo.si_signo = 11" " = 11" > -gdb_test "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey = 123" " = 123" > +gdb_test "p \$_siginfo._sifields._sigfault._addr_pkey.si_pkey = 123" " = 123" > > with_test_prefix "validate modified siginfo fields" { > gdb_test "break $bp_location" > @@ -143,7 +143,7 @@ if {$gcore_created} { > gdb_test "p \$_siginfo._sifields._sigfault.si_addr" \ > " = \\(void \\*\\) $ssi_addr" \ > "p \$_siginfo._sifields._sigfault.si_addr from core file" > - gdb_test "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey" \ > + gdb_test "p \$_siginfo._sifields._sigfault._addr_pkey.si_pkey" \ > " = $ssi_pkey" \ > - "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey from core file" > + "p \$_siginfo._sifields._sigfault._addr_pkey.si_pkey from core file" > } > > >>> Can you expand on why it's not possible to have an anonymous union? It >> is certainly possible to have anonymous unions described in DWARF, which >> are then translated to struct types. >> > > I simply could not find how to implement it. > It might be useful to add to the documentation of append_composite_type_field_aligned() or maybe > better, to the comment in gdb/gdbtypes.h above the declaration of append_composite_type_field(), a > sentence explaining what is the effect of providing an empty name. > > diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h > index dd2d24fa8e2..e4fedd886c4 100644 > --- a/gdb/gdbtypes.h > +++ b/gdb/gdbtypes.h > @@ -2431,11 +2431,12 @@ extern struct type *init_pointer_type (type_allocator &alloc, int bit, > extern struct type *init_fixed_point_type (type_allocator &, int, int, > const char *); > > -/* Helper functions to construct a struct or record type. An > - initially empty type is created using arch_composite_type(). > - Fields are then added using append_composite_type_field*(). A union > - type has its size set to the largest field. A struct type has each > - field packed against the previous. */ > +/* Helper functions to construct a struct or record type. An initially empty > + type is created using arch_composite_type(). Fields are then added using > + append_composite_type_field*(). > + A union type has its size set to the largest field. A struct type has each > + field packed against the previous. > + If no name is specified, the type is anonymous. */ > > extern struct type *arch_composite_type (struct gdbarch *gdbarch, > const char *name, enum type_code code); > >> I think that the ideal user experience would be for users to be able to >> access fields the same way that they do in the code, that is >> `si.si_pkey`. All the _sigfault/_addr_pkey/etc parts are implementation >> details that could change. >> >> On top of your patch, if I just delete all the internal field names, it >> seems to work just fine, see patch below. In the end it models >> something like this in C: >> > > I am not against it. > However, could this suggestion be addressed in a different patch ? > > Simplifying the existing pathes to si_* values with anonymous structs would increase the impact of > the original patch, with potentially additional testing and carefulness required for others > architectures (for example, see gdb/nat/amd64-linux-siginfo.c L269). > > Matthieu > >> struct siginto_t >> { >> union >> { >> // kill >> struct >> { >> int si_pid; >> int si_uid; >> }; >> >> // timer >> struct >> { >> int si_tid; >> int si_overrun; >> int si_sys_private; >> }; >> >> ... >> }; >> }; >> >> >> diff --git i/gdb/linux-tdep.c w/gdb/linux-tdep.c >> index 4660772752d6..f21fa1e18578 100644 >> --- i/gdb/linux-tdep.c >> +++ w/gdb/linux-tdep.c >> @@ -349,21 +349,21 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) >> type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); >> append_composite_type_field (type, "si_pid", pid_type); >> append_composite_type_field (type, "si_uid", uid_type); >> - append_composite_type_field (sifields_type, "_kill", type); >> + append_composite_type_field (sifields_type, "", type); >> >> /* _timer */ >> type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); >> append_composite_type_field (type, "si_tid", int_type); >> append_composite_type_field (type, "si_overrun", int_type); >> append_composite_type_field (type, "si_sigval", sigval_type); >> - append_composite_type_field (sifields_type, "_timer", type); >> + append_composite_type_field (sifields_type, "", type); >> >> /* _rt */ >> type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); >> append_composite_type_field (type, "si_pid", pid_type); >> append_composite_type_field (type, "si_uid", uid_type); >> append_composite_type_field (type, "si_sigval", sigval_type); >> - append_composite_type_field (sifields_type, "_rt", type); >> + append_composite_type_field (sifields_type, "", type); >> >> /* _sigchld */ >> type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); >> @@ -372,7 +372,7 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) >> append_composite_type_field (type, "si_status", int_type); >> append_composite_type_field (type, "si_utime", clock_type); >> append_composite_type_field (type, "si_stime", clock_type); >> - append_composite_type_field (sifields_type, "_sigchld", type); >> + append_composite_type_field (sifields_type, "", type); >> >> /* Begin _sigfault's anonymous union. */ >> sigfault_union_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); >> @@ -386,20 +386,20 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) >> append_composite_type_field (type, "_dummy_bnd", addr_bnd_pkey_padding_type); >> append_composite_type_field (type, "si_lower", void_ptr_type); >> append_composite_type_field (type, "si_upper", void_ptr_type); >> - append_composite_type_field (sigfault_union_type, "_addr_bnd", type); >> + append_composite_type_field (sigfault_union_type, "", type); >> >> /* used when si_code=SEGV_PKUERR */ >> type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); >> append_composite_type_field (type, "_dummy_pkey", addr_bnd_pkey_padding_type); >> append_composite_type_field (type, "si_pkey", uint32_type); >> - append_composite_type_field (sigfault_union_type, "_addr_pkey", type); >> + append_composite_type_field (sigfault_union_type, "", type); >> >> /* used when si_code=TRAP_PERF */ >> type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); >> append_composite_type_field (type, "si_perf_data", unsigned_long_type); >> append_composite_type_field (type, "si_perf_type", uint32_type); >> append_composite_type_field (type, "si_perf_flags", uint32_type); >> - append_composite_type_field (sigfault_union_type, "_perf", type); >> + append_composite_type_field (sigfault_union_type, "", type); >> >> /* End _sigfault's anonymous union. */ >> >> @@ -408,21 +408,21 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) >> append_composite_type_field (type, "si_addr", void_ptr_type); >> /* Since there is no possibility to declare an anonymous union, >> using '_anon_union' instead. */ >> - append_composite_type_field (type, "_anon_union", sigfault_union_type); >> - append_composite_type_field (sifields_type, "_sigfault", type); >> + append_composite_type_field (type, "", sigfault_union_type); >> + append_composite_type_field (sifields_type, "", type); >> >> /* _sigpoll */ >> type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); >> append_composite_type_field (type, "si_band", long_type); >> append_composite_type_field (type, "si_fd", int_type); >> - append_composite_type_field (sifields_type, "_sigpoll", type); >> + append_composite_type_field (sifields_type, "", type); >> >> /* _sigsys */ >> type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); >> append_composite_type_field (type, "_call_addr", void_ptr_type); >> append_composite_type_field (type, "_syscall", int_type); >> append_composite_type_field (type, "_arch", uint_type); >> - append_composite_type_field (sifields_type, "_sigsys", type); >> + append_composite_type_field (sifields_type, "", type); >> >> /* struct siginfo */ >> siginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); >> @@ -431,7 +431,7 @@ linux_get_siginfo_type (struct gdbarch *gdbarch) >> append_composite_type_field (siginfo_type, "si_errno", int_type); >> append_composite_type_field (siginfo_type, "si_code", int_type); >> append_composite_type_field_aligned (siginfo_type, >> - "_sifields", sifields_type, >> + "", sifields_type, >> long_type->length ()); >> >> linux_gdbarch_data->siginfo_type = siginfo_type; >> diff --git i/gdb/testsuite/gdb.base/siginfo-obj.exp w/gdb/testsuite/gdb.base/siginfo-obj.exp >> index 5e36b3340680..272d74ac2805 100644 >> --- i/gdb/testsuite/gdb.base/siginfo-obj.exp >> +++ w/gdb/testsuite/gdb.base/siginfo-obj.exp >> @@ -111,11 +111,11 @@ gdb_test "continue" ".*Program received signal SIGSEGV.*" \ >> "continue to signal, 2nd" >> >> set test "set si_addr" >> -gdb_test "p \$_siginfo._sifields._sigfault.si_addr = 0x666" " = \\(void \\*\\) 0x666" >> +gdb_test "p \$_siginfo.si_addr = 0x666" " = \\(void \\*\\) 0x666" >> gdb_test "p \$_siginfo.si_errno = 666" " = 666" >> gdb_test "p \$_siginfo.si_code = 999" " = 999" >> gdb_test "p \$_siginfo.si_signo = 11" " = 11" >> -gdb_test "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey = 123" " = 123" >> +gdb_test "p \$_siginfo.si_pkey = 123" " = 123" >> >> with_test_prefix "validate modified siginfo fields" { >> gdb_test "break $bp_location" >> @@ -140,10 +140,10 @@ if {$gcore_created} { >> "p \$_siginfo.si_errno from core file" >> gdb_test "p \$_siginfo.si_code" " = $ssi_code" \ >> "p \$_siginfo.si_code from core file" >> - gdb_test "p \$_siginfo._sifields._sigfault.si_addr" \ >> + gdb_test "p \$_siginfo.si_addr" \ >> " = \\(void \\*\\) $ssi_addr" \ >> - "p \$_siginfo._sifields._sigfault.si_addr from core file" >> - gdb_test "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey" \ >> + "p \$_siginfo.si_addr from core file" >> + gdb_test "p \$_siginfo.si_pkey" \ >> " = $ssi_pkey" \ >> - "p \$_siginfo._sifields._sigfault._anon_union._addr_pkey.si_pkey from core file" >> + "p \$_siginfo.si_pkey from core file" >> } >> >> Simon > Hi Simon, Do you want me to publish a new revision of the patch ? The things you raised looked minor to me, so I would assume that I don't need to publish a new revision. Please let me know if you think otherwise. Regards, Matthieu ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v5] gdb: align siginfo_t with the Linux kernel definition 2026-08-17 9:33 ` Matthieu Longo @ 2026-08-17 16:42 ` Simon Marchi 2026-08-17 21:37 ` Matthieu Longo 0 siblings, 1 reply; 11+ messages in thread From: Simon Marchi @ 2026-08-17 16:42 UTC (permalink / raw) To: Matthieu Longo, gdb-patches Cc: Luis Machado, Luis Machado, Thiago Jung Bauermann, Srinath Parvathaneni, Maciej W . Rozycki, Andreas Schwab On 8/17/26 5:33 AM, Matthieu Longo wrote: > Hi Simon, > > Do you want me to publish a new revision of the patch ? > The things you raised looked minor to me, so I would assume that I don't need to publish a new revision. > Please let me know if you think otherwise. If I'm not mistaken, you're talking about your original v5 patch plus the changes to drop the "_anon_union", as proposed in message 10ce3491-6802-480d-b2c7-fc3bf0efb60c@arm.com. If so, it LGTM. Approved-By: Simon Marchi <simon.marchi@efficios.com> Simon ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v5] gdb: align siginfo_t with the Linux kernel definition 2026-08-17 16:42 ` Simon Marchi @ 2026-08-17 21:37 ` Matthieu Longo 0 siblings, 0 replies; 11+ messages in thread From: Matthieu Longo @ 2026-08-17 21:37 UTC (permalink / raw) To: Simon Marchi, gdb-patches Cc: Luis Machado, Luis Machado, Thiago Jung Bauermann, Srinath Parvathaneni, Maciej W . Rozycki, Andreas Schwab On 17/08/2026 17:42, Simon Marchi wrote: > On 8/17/26 5:33 AM, Matthieu Longo wrote: >> Hi Simon, >> >> Do you want me to publish a new revision of the patch ? >> The things you raised looked minor to me, so I would assume that I don't need to publish a new revision. >> Please let me know if you think otherwise. > > If I'm not mistaken, you're talking about your original v5 patch plus > the changes to drop the "_anon_union", as proposed in message > 10ce3491-6802-480d-b2c7-fc3bf0efb60c@arm.com. > > If so, it LGTM. > > Approved-By: Simon Marchi <simon.marchi@efficios.com> > > Simon Thanks! Merged: https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=9c99987237dcaca0c6c493d6a5fb0ab4dc7488e7 Matthieu ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-08-17 21:38 UTC | newest] Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-07-28 12:32 [PATCH v5] gdb: align siginfo_t with the Linux kernel definition Matthieu Longo 2026-08-03 8:23 ` Matthieu Longo 2026-08-12 21:55 ` Luis 2026-08-12 19:08 ` Simon Marchi 2026-08-13 14:48 ` Matthieu Longo 2026-08-13 15:49 ` Simon Marchi 2026-08-14 10:05 ` Matthieu Longo 2026-08-17 16:59 ` Simon Marchi 2026-08-17 9:33 ` Matthieu Longo 2026-08-17 16:42 ` Simon Marchi 2026-08-17 21:37 ` Matthieu Longo
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox