mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 06:01:57 +00:00
Provide FPU buffer layout in core dumps:
Debuggers have guess the FPU buffer layout in core dumps, which is error prone. This is because AMD and Intel layouts differ. To avoid buggy heuristics add a ELF section which describes the buffer layout which can be retrieved by tools. -----BEGIN PGP SIGNATURE----- iQJHBAABCgAxFiEEQp8+kY+LLUocC4bMphj1TA10mKEFAmbpOuwTHHRnbHhAbGlu dXRyb25peC5kZQAKCRCmGPVMDXSYoTRAEACGHPdAYFp5A396c9qUbHUE2gEKIad2 iuq15TZKLPY/LFqfTwnkp9/nqKtZ0gj4D6XCIucWZjwWJuPgvgGf/tC9Fk+H+C6X 9+rycP3GdqxU28qLxA428SN2Pg3lvqG4rryVWeHUXQ4x8A0DSMV+3pkNY5YgJ+2+ fTzNzVi2tkPRAXhKmj3EdcFcgDPiFQBMm1QNBpc+FqrXk4rjJb9Axln0oT8xemDv TtJ5BMhFpR73naaiS4IrK8Tk3oFCa8CmafCQfl1zAOor/+EemPQKwMuGeiXE7dLG eE+OTw5zuxYwlc9WoaPmM/ZiEc5JptpHQUtyHDBN7BaK87VKjsupAXXVOh6XMRCt R2coqq7fqDqMANwWpUKddky3vSwbst1GZpXGAENOy64yU4VoFutr616WSj3sJfUi knBauPqLAFeZLhMn/kKr5a0rBgm7VuQSlGPYEhqVdaM3Eb/zJEupFL/bTpqQbbz/ 8lo2hYcfDslhShcEZYBwm4eUg+ytZ96K3ciZ5YgNih9LFBxEOo0SY1CqbQJiRtpB 3DmgldYtzRdQq5/JtFGNv717uMESn5khG3qHUpXtrDhWfD8spMWiY1yO/cwWvLFJ ZS5ATp1dAt1Pbv2MC6r9jQBbW3V7xNNAOJdzUvIZPP04PKeV0ObFOplxhabOzUDj OLquyIrjpxeisg== =Vqqo -----END PGP SIGNATURE----- Merge tag 'x86-fpu-2024-09-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull x86 fpu updates from Thomas Gleixner: "Provide FPU buffer layout in core dumps: Debuggers have guess the FPU buffer layout in core dumps, which is error prone. This is because AMD and Intel layouts differ. To avoid buggy heuristics add a ELF section which describes the buffer layout which can be retrieved by tools" * tag 'x86-fpu-2024-09-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/elf: Add a new FPU buffer layout info to x86 core files
This commit is contained in:
commit
c3056a7d14
@ -107,6 +107,7 @@ config X86
|
||||
select ARCH_HAS_DEBUG_WX
|
||||
select ARCH_HAS_ZONE_DMA_SET if EXPERT
|
||||
select ARCH_HAVE_NMI_SAFE_CMPXCHG
|
||||
select ARCH_HAVE_EXTRA_ELF_NOTES
|
||||
select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE
|
||||
select ARCH_MIGHT_HAVE_ACPI_PDC if ACPI
|
||||
select ARCH_MIGHT_HAVE_PC_PARPORT
|
||||
|
16
arch/x86/include/uapi/asm/elf.h
Normal file
16
arch/x86/include/uapi/asm/elf.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
#ifndef _UAPI_ASM_X86_ELF_H
|
||||
#define _UAPI_ASM_X86_ELF_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct x86_xfeat_component {
|
||||
__u32 type;
|
||||
__u32 size;
|
||||
__u32 offset;
|
||||
__u32 flags;
|
||||
} __packed;
|
||||
|
||||
_Static_assert(sizeof(struct x86_xfeat_component) % 4 == 0, "x86_xfeat_component is not aligned");
|
||||
|
||||
#endif /* _UAPI_ASM_X86_ELF_H */
|
@ -13,6 +13,7 @@
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/coredump.h>
|
||||
|
||||
#include <asm/fpu/api.h>
|
||||
#include <asm/fpu/regset.h>
|
||||
@ -23,6 +24,8 @@
|
||||
#include <asm/prctl.h>
|
||||
#include <asm/elf.h>
|
||||
|
||||
#include <uapi/asm/elf.h>
|
||||
|
||||
#include "context.h"
|
||||
#include "internal.h"
|
||||
#include "legacy.h"
|
||||
@ -1841,3 +1844,89 @@ int proc_pid_arch_status(struct seq_file *m, struct pid_namespace *ns,
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PROC_PID_ARCH_STATUS */
|
||||
|
||||
#ifdef CONFIG_COREDUMP
|
||||
static const char owner_name[] = "LINUX";
|
||||
|
||||
/*
|
||||
* Dump type, size, offset and flag values for every xfeature that is present.
|
||||
*/
|
||||
static int dump_xsave_layout_desc(struct coredump_params *cprm)
|
||||
{
|
||||
int num_records = 0;
|
||||
int i;
|
||||
|
||||
for_each_extended_xfeature(i, fpu_user_cfg.max_features) {
|
||||
struct x86_xfeat_component xc = {
|
||||
.type = i,
|
||||
.size = xstate_sizes[i],
|
||||
.offset = xstate_offsets[i],
|
||||
/* reserved for future use */
|
||||
.flags = 0,
|
||||
};
|
||||
|
||||
if (!dump_emit(cprm, &xc, sizeof(xc)))
|
||||
return 0;
|
||||
|
||||
num_records++;
|
||||
}
|
||||
return num_records;
|
||||
}
|
||||
|
||||
static u32 get_xsave_desc_size(void)
|
||||
{
|
||||
u32 cnt = 0;
|
||||
u32 i;
|
||||
|
||||
for_each_extended_xfeature(i, fpu_user_cfg.max_features)
|
||||
cnt++;
|
||||
|
||||
return cnt * (sizeof(struct x86_xfeat_component));
|
||||
}
|
||||
|
||||
int elf_coredump_extra_notes_write(struct coredump_params *cprm)
|
||||
{
|
||||
int num_records = 0;
|
||||
struct elf_note en;
|
||||
|
||||
if (!fpu_user_cfg.max_features)
|
||||
return 0;
|
||||
|
||||
en.n_namesz = sizeof(owner_name);
|
||||
en.n_descsz = get_xsave_desc_size();
|
||||
en.n_type = NT_X86_XSAVE_LAYOUT;
|
||||
|
||||
if (!dump_emit(cprm, &en, sizeof(en)))
|
||||
return 1;
|
||||
if (!dump_emit(cprm, owner_name, en.n_namesz))
|
||||
return 1;
|
||||
if (!dump_align(cprm, 4))
|
||||
return 1;
|
||||
|
||||
num_records = dump_xsave_layout_desc(cprm);
|
||||
if (!num_records)
|
||||
return 1;
|
||||
|
||||
/* Total size should be equal to the number of records */
|
||||
if ((sizeof(struct x86_xfeat_component) * num_records) != en.n_descsz)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int elf_coredump_extra_notes_size(void)
|
||||
{
|
||||
int size;
|
||||
|
||||
if (!fpu_user_cfg.max_features)
|
||||
return 0;
|
||||
|
||||
/* .note header */
|
||||
size = sizeof(struct elf_note);
|
||||
/* Name plus alignment to 4 bytes */
|
||||
size += roundup(sizeof(owner_name), 4);
|
||||
size += get_xsave_desc_size();
|
||||
|
||||
return size;
|
||||
}
|
||||
#endif /* CONFIG_COREDUMP */
|
||||
|
@ -2039,7 +2039,7 @@ static int elf_core_dump(struct coredump_params *cprm)
|
||||
{
|
||||
size_t sz = info.size;
|
||||
|
||||
/* For cell spufs */
|
||||
/* For cell spufs and x86 xstate */
|
||||
sz += elf_coredump_extra_notes_size();
|
||||
|
||||
phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL);
|
||||
@ -2103,7 +2103,7 @@ static int elf_core_dump(struct coredump_params *cprm)
|
||||
if (!write_note_info(&info, cprm))
|
||||
goto end_coredump;
|
||||
|
||||
/* For cell spufs */
|
||||
/* For cell spufs and x86 xstate */
|
||||
if (elf_coredump_extra_notes_write(cprm))
|
||||
goto end_coredump;
|
||||
|
||||
|
@ -411,6 +411,7 @@ typedef struct elf64_shdr {
|
||||
#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
|
||||
/* Old binutils treats 0x203 as a CET state */
|
||||
#define NT_X86_SHSTK 0x204 /* x86 SHSTK state */
|
||||
#define NT_X86_XSAVE_LAYOUT 0x205 /* XSAVE layout description */
|
||||
#define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */
|
||||
#define NT_S390_TIMER 0x301 /* s390 timer register */
|
||||
#define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */
|
||||
|
Loading…
Reference in New Issue
Block a user