Proposal for a new NT_X86_CPUID core dump note

A year or so ago I purchased a new desktop with an AMD Ryzen CPU and discovered that GDB did not like the NT_X86_XSTATE register notes in core dumps on FreeBSD. These notes used a size that GDB did not understand. Current releases of GDB have assumed a fixed layout of the extended regions of the XSAVE area (basically following the layout of Intel CPUs to date). However, my Ryzen CPU used a different layout. It included PKRU, but it did not leave a gap for the MPX regions in its XSAVE layout, just a gap for AVX-512 between AVX and PKRU.

As a first level workaround, I wrote a series of patches for GDB to add a notion of an XSAVE layout with a variable starting offset for each of the extended state regions (e.g. AVX, PKRU, the various AVX-512 regions). For a live process CPUID on the host is queried to determine the layout returned by ptrace(). However, for a core dump, GDB currently uses a heuristic based on the active XCR0 mask and the register note size to infer a layout ([PATCH v6 00/15] Handle variable XSAVE layouts is the cover letter for the last version of that patch series).

The heuristic is fragile however, and as a more permanent fix, I have proposed adding a new core dump note (with patches for GDB and FreeBSD’s kernel) to dump the relevant leaves of CPUID so that GDB can use that to determine the XSAVE layout reliably. That proposal (and set of patches to GDB) can be found at [PATCH v6 00/15] Handle variable XSAVE layouts with the FreeBSD kernel patch (still in review) at ⚙ D42136 x86: Add a new NT_X86_CPUID regset for ptrace and core dumps.

Folks from AMD have helpfully offered to work on adding support to the Linux kernel upstream and are cc’d on the thread on gdb-patches@. However, I wanted to loop the LLDB folks if you have any input. Given that there is already some active discussion on the gdb-patches@ thread, I believe that might be the best place to coordinate discussion on this idea, but I’ll watch for any followups here as well.


My only thought was answered by you on the FreeBSD review:

The current note is designed such that we could extend it with more CPUID leaves in the future if they prove useful. Right now GDB just looks for the feature-specific sub-leaves of 0xd to determine the offsets of regions. The information from these sub-leaves could also permit parsing the compact format of XSAVE in the future. (We don’t yet use compact XSAVE in our kernel, but Linux uses the compact format internally and expands it back out when writing out process cores and for ptrace().)

Which was that this CPUID could be useful for for instance, detecting which register fields are present. Which I am working on right now using HWCAPs (for AArch64), but CPUID could be a potential fallback.

(sometimes there are things userspace should not concern itself with, but a debugger user would like to know are present or not)

If we can extend the note easily then we avoid needing a whole new note next time we have a use case.

Yes, the note’s contents is designed as an array of structures each of which contains the input (eax, ecx) values and the output (eax, ebx, ecx, edx) values as 6 32-bit little endian integers. In the GDB patches I read those into a std::unordered_map<> that uses the input (eax, ecx) as a key and the XSAVE layout parsing code looks for the leaves it needs from the map.