bfd/ELF: Handle prstatus of 156 bytes in elf32_arm_nabi_grok_prstatus

For a corefile generated on openSUSE Leap 15.2 armv7l with linux version
5.3.18, we get:
...
$ gdb -q --core core
  ...
Core was generated by `/usr/bin/rs_scope -d'.

⚠️ warning: Couldn't find general-purpose registers in core file.
(gdb)
...

The warning is emitted because the pseudo-section .reg is missing, because
elf32_arm_nabi_grok_prstatus expects the PRSTATUS note to have size 148, but
instead we have:
...
$ eu-readelf -n core | grep -i prstatus
  CORE                 156  PRSTATUS
  CORE                 156  PRSTATUS
  CORE                 156  PRSTATUS
  CORE                 156  PRSTATUS
...

This is a bug for CONFIG_BINFMT_ELF_FDPIC=y configurations, fixed
by v5.9 linux kernel commit 16aead81018c ("take fdpic-related parts of
elf_prstatus out").

The bug causes the FDPIC-specific unsigned long fields pr_exec_fdpic_loadmap
and pr_interp_fdpic_loadmap to be added to struct elf_prstatus in case the
FDPIC ABI is not used.

Work around this bug in elf32_arm_nabi_grok_prstatus, by ignoring the extra
fields, which gets us instead:
...
Core was generated by `/usr/bin/rs_scope -d'.
Program terminated with signal SIGSEGV, Segmentation fault.
[Current thread is 1 (LWP 30047)]
(gdb)
...

Tested gdb, gas, binutils and ld on x86_64-linux and arm-linux with
--enable-targets=all.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33560
This commit is contained in:
Tom de Vries
2025-12-17 15:04:21 +01:00
parent f5de926fc6
commit 03819fa9be

View File

@@ -2149,6 +2149,16 @@ elf32_arm_nabi_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
default:
return false;
case 156: /* Linux/ARM 32-bit, some pre-v5.9 linux kernels. */
/* There's a linux kernel bug for CONFIG_BINFMT_ELF_FDPIC=y
configurations, fixed by v5.9 linux kernel commit 16aead81018c
("take fdpic-related parts of elf_prstatus out").
The bug causes the FDPIC-specific unsigned long fields
pr_exec_fdpic_loadmap and pr_interp_fdpic_loadmap to be added to
struct elf_prstatus in case the FDPIC ABI is not used.
The two fields are added after pr_reg, so just ignore them. */
/* Fall through. */
case 148: /* Linux/ARM 32-bit. */
/* pr_cursig */
elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);