Skip to content

RM7326: support FDPIC core dump debugging#9

Open
vdskvortsov wants to merge 2 commits intoemcraft-fdpic-2022.08.xfrom
rm7326-gdb-coredump
Open

RM7326: support FDPIC core dump debugging#9
vdskvortsov wants to merge 2 commits intoemcraft-fdpic-2022.08.xfrom
rm7326-gdb-coredump

Conversation

@vdskvortsov
Copy link
Copy Markdown
Contributor

GDB could open FDPIC core dumps but could not parse them: no
general-purpose registers were loaded, shared libraries came up
empty, and backtraces produced only "<unavailable> in ?? ()".
Two independent root causes:

1. The Linux kernel writes struct elf_prstatus_fdpic
   (fs/binfmt_elf_fdpic.c), which inserts pr_exec_fdpic_loadmap and
   pr_interp_fdpic_loadmap (2 * 4 bytes) between pr_reg and
   pr_fpvalid, making the NT_PRSTATUS note 156 bytes instead of
   148.  BFD's ARM backend only recognised the stock 148-byte
   layout and rejected the note, so no .reg pseudosection was
   created and GDB reported "Couldn't find general-purpose
   registers in core file".

2. solib-fdpic's fdpic_get_initial_loadmaps() retrieves loadmaps
   via target_read_alloc(TARGET_OBJECT_FDPIC, ...), which is
   served by gdbserver for live inferiors but has no core-file
   backend, so post-mortem sessions saw "No shared libraries
   loaded at this time".

Three patches address the problem:

- 0020 (bfd/elf32-arm.c): recognise descsz == 156 and size the
  .reg pseudosection at 80 bytes so the two loadmap addresses
  sit at offsets 72 and 76, mirroring how bfd/elf32-frv.c handles
  the FRV FDPIC case.

- 0021 (gdb/solib-fdpic.c): when core_bfd != NULL, read the
  loadmap addresses from .reg via bfd_get_section_contents() and
  feed them to the existing fetch_loadmap() helper, which walks
  target memory served from the core's PT_LOAD segments.  Also
  soften the rm7087 !target_has_execution guard to let core-file
  sessions reach fdpic_relocate_main_executable().

- 0022 (gdb/arm-linux-tdep.c): advertise 80-byte .reg in
  arm_linux_iterate_over_regset_sections when tdep->is_fdpic, so
  the size advertised to GDB's core-section validator matches
  what BFD produces.  Silences the "Unexpected size of section
  \`.reg/<lwp>'" warning without affecting non-FDPIC cores.

Verified against an FDPIC core dump from imxrt1170-evkb: GP
registers load, both initial loadmaps extract from the extended
prstatus, link-map chain walks successfully, and "bt" resolves
cleanly across the libc/main-exec boundary.
Post-mortem `bt' on an FDPIC core from a Cortex-M target stopped
one frame past the innermost libc function with
"previous frame inner to this frame (corrupt stack?)" even though
symbols, the loadmap, and stack memory were all correct.  The
earlier RM-7623 patches (0020-0022) made the core readable; this
one makes the unwinder interpret it correctly.

arm_gdbarch_init selects Cortex-M (`is_m') from either a target
description (supplied by gdbserver) or the ARM build attributes on
`info.abfd'.  In a core session neither path fires: the core target
synthesises a generic org.gnu.gdb.arm.core tdesc from NT_PRSTATUS,
and the Linux FDPIC core dumper writes e_flags = 0 with no
.ARM.attributes section, so the core bfd carries no M-profile
marker.  With is_m left false, arm_psr_thumb_bit returns CPSR_T
instead of XPSR_T, arm_frame_is_thumb misreads the xPSR bit-24
flag as not-Thumb, and arm_scan_prologue runs the ARM-mode
analyser against Thumb prologues.  saved_regs stays in its
is_realreg initial state and trad_frame_get_prev_register hands
the current frame's register values back as the caller's,
corrupting every unwound register value.

0023 teaches arm_gdbarch_init to fall back to
current_program_space->exec_bfd () when info.abfd has no ARM
build attributes, drops the `!tdesc_has_registers' guard so the
attribute is authoritative even alongside the synthetic arm.core
tdesc, and accepts either "xpsr" or "cpsr" naming for ARM_PS_REGNUM
when is_m is true (the synthesised tdesc names the PS register
"cpsr").

Verified against an FDPIC core dump from imxrt1170-evkb: the
post-mortem backtrace now walks the full call chain identically
to a live gdbserver session, with saved r4/r7/lr offsets matching
between the two.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant