elf_prstatus: collect the common part (everything before pr_reg) into a struct
Preparations to doing i386 compat elf_prstatus sanely - rather than duplicating the beginning of compat_elf_prstatus, take these fields into a separate structure (compat_elf_prstatus_common), so that it could be reused. Due to the incestous relationship between binfmt_elf.c and compat_binfmt_elf.c we need the same shape change done to native struct elf_prstatus, gathering the fields prior to pr_reg into a new structure (struct elf_prstatus_common). Fortunately, offset of pr_reg is always a multiple of 16 with no padding right before it, so it's possible to turn all the stuff prior to it into a single member without disturbing the layout. [build fix from Geert Uytterhoeven folded in] Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
8a00dd0012
commit
f2485a2dc9
|
@ -43,7 +43,7 @@ crash_save_this_cpu(void)
|
||||||
|
|
||||||
elf_greg_t *dst = (elf_greg_t *)&(prstatus->pr_reg);
|
elf_greg_t *dst = (elf_greg_t *)&(prstatus->pr_reg);
|
||||||
memset(prstatus, 0, sizeof(*prstatus));
|
memset(prstatus, 0, sizeof(*prstatus));
|
||||||
prstatus->pr_pid = current->pid;
|
prstatus->common.pr_pid = current->pid;
|
||||||
|
|
||||||
ia64_dump_cpu_regs(dst);
|
ia64_dump_cpu_regs(dst);
|
||||||
cfm = dst[43];
|
cfm = dst[43];
|
||||||
|
|
|
@ -44,7 +44,8 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
|
||||||
#include <linux/math64.h>
|
#include <linux/math64.h>
|
||||||
|
|
||||||
#define elf_prstatus elf_prstatus32
|
#define elf_prstatus elf_prstatus32
|
||||||
struct elf_prstatus32
|
#define elf_prstatus_common elf_prstatus32_common
|
||||||
|
struct elf_prstatus32_common
|
||||||
{
|
{
|
||||||
struct elf_siginfo pr_info; /* Info associated with signal */
|
struct elf_siginfo pr_info; /* Info associated with signal */
|
||||||
short pr_cursig; /* Current signal */
|
short pr_cursig; /* Current signal */
|
||||||
|
@ -58,6 +59,10 @@ struct elf_prstatus32
|
||||||
struct old_timeval32 pr_stime; /* System time */
|
struct old_timeval32 pr_stime; /* System time */
|
||||||
struct old_timeval32 pr_cutime;/* Cumulative user time */
|
struct old_timeval32 pr_cutime;/* Cumulative user time */
|
||||||
struct old_timeval32 pr_cstime;/* Cumulative system time */
|
struct old_timeval32 pr_cstime;/* Cumulative system time */
|
||||||
|
};
|
||||||
|
struct elf_prstatus32
|
||||||
|
{
|
||||||
|
struct elf_prstatus32_common common:
|
||||||
elf_gregset_t pr_reg; /* GP registers */
|
elf_gregset_t pr_reg; /* GP registers */
|
||||||
int pr_fpvalid; /* True if math co-processor being used. */
|
int pr_fpvalid; /* True if math co-processor being used. */
|
||||||
};
|
};
|
||||||
|
|
|
@ -49,7 +49,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
|
||||||
#include <linux/math64.h>
|
#include <linux/math64.h>
|
||||||
|
|
||||||
#define elf_prstatus elf_prstatus32
|
#define elf_prstatus elf_prstatus32
|
||||||
struct elf_prstatus32
|
struct elf_prstatus32_common
|
||||||
{
|
{
|
||||||
struct elf_siginfo pr_info; /* Info associated with signal */
|
struct elf_siginfo pr_info; /* Info associated with signal */
|
||||||
short pr_cursig; /* Current signal */
|
short pr_cursig; /* Current signal */
|
||||||
|
@ -63,6 +63,10 @@ struct elf_prstatus32
|
||||||
struct old_timeval32 pr_stime; /* System time */
|
struct old_timeval32 pr_stime; /* System time */
|
||||||
struct old_timeval32 pr_cutime;/* Cumulative user time */
|
struct old_timeval32 pr_cutime;/* Cumulative user time */
|
||||||
struct old_timeval32 pr_cstime;/* Cumulative system time */
|
struct old_timeval32 pr_cstime;/* Cumulative system time */
|
||||||
|
};
|
||||||
|
struct elf_prstatus32
|
||||||
|
{
|
||||||
|
struct elf_prstatus32_common common:
|
||||||
elf_gregset_t pr_reg; /* GP registers */
|
elf_gregset_t pr_reg; /* GP registers */
|
||||||
int pr_fpvalid; /* True if math co-processor being used. */
|
int pr_fpvalid; /* True if math co-processor being used. */
|
||||||
};
|
};
|
||||||
|
|
|
@ -119,8 +119,8 @@ static void fill_prstatus(struct elf_prstatus *prstatus, int pir,
|
||||||
* As a PIR value could also be '0', add an offset of '100'
|
* As a PIR value could also be '0', add an offset of '100'
|
||||||
* to every PIR to avoid misinterpretations in GDB.
|
* to every PIR to avoid misinterpretations in GDB.
|
||||||
*/
|
*/
|
||||||
prstatus->pr_pid = cpu_to_be32(100 + pir);
|
prstatus->common.pr_pid = cpu_to_be32(100 + pir);
|
||||||
prstatus->pr_ppid = cpu_to_be32(1);
|
prstatus->common.pr_ppid = cpu_to_be32(1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Indicate SIGUSR1 for crash initiated from kernel.
|
* Indicate SIGUSR1 for crash initiated from kernel.
|
||||||
|
@ -130,7 +130,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus, int pir,
|
||||||
short sig;
|
short sig;
|
||||||
|
|
||||||
sig = kernel_initiated ? SIGUSR1 : SIGTERM;
|
sig = kernel_initiated ? SIGUSR1 : SIGTERM;
|
||||||
prstatus->pr_cursig = cpu_to_be16(sig);
|
prstatus->common.pr_cursig = cpu_to_be16(sig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -365,7 +365,7 @@ static void *fill_cpu_elf_notes(void *ptr, int cpu, struct save_area *sa)
|
||||||
memcpy(&nt_prstatus.pr_reg.gprs, sa->gprs, sizeof(sa->gprs));
|
memcpy(&nt_prstatus.pr_reg.gprs, sa->gprs, sizeof(sa->gprs));
|
||||||
memcpy(&nt_prstatus.pr_reg.psw, sa->psw, sizeof(sa->psw));
|
memcpy(&nt_prstatus.pr_reg.psw, sa->psw, sizeof(sa->psw));
|
||||||
memcpy(&nt_prstatus.pr_reg.acrs, sa->acrs, sizeof(sa->acrs));
|
memcpy(&nt_prstatus.pr_reg.acrs, sa->acrs, sizeof(sa->acrs));
|
||||||
nt_prstatus.pr_pid = cpu;
|
nt_prstatus.common.pr_pid = cpu;
|
||||||
/* Prepare fpregset (floating point) note */
|
/* Prepare fpregset (floating point) note */
|
||||||
memset(&nt_fpregset, 0, sizeof(nt_fpregset));
|
memset(&nt_fpregset, 0, sizeof(nt_fpregset));
|
||||||
memcpy(&nt_fpregset.fpc, &sa->fpc, sizeof(sa->fpc));
|
memcpy(&nt_fpregset.fpc, &sa->fpc, sizeof(sa->fpc));
|
||||||
|
|
|
@ -1495,7 +1495,7 @@ static void fill_note(struct memelfnote *note, const char *name, int type,
|
||||||
* fill up all the fields in prstatus from the given task struct, except
|
* fill up all the fields in prstatus from the given task struct, except
|
||||||
* registers which need to be filled up separately.
|
* registers which need to be filled up separately.
|
||||||
*/
|
*/
|
||||||
static void fill_prstatus(struct elf_prstatus *prstatus,
|
static void fill_prstatus(struct elf_prstatus_common *prstatus,
|
||||||
struct task_struct *p, long signr)
|
struct task_struct *p, long signr)
|
||||||
{
|
{
|
||||||
prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
|
prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
|
||||||
|
@ -1736,7 +1736,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t,
|
||||||
* than being the whole note contents. We fill the reset in here.
|
* than being the whole note contents. We fill the reset in here.
|
||||||
* We assume that regset 0 is NT_PRSTATUS.
|
* We assume that regset 0 is NT_PRSTATUS.
|
||||||
*/
|
*/
|
||||||
fill_prstatus(&t->prstatus, t->task, signr);
|
fill_prstatus(&t->prstatus.common, t->task, signr);
|
||||||
regset_get(t->task, &view->regsets[0],
|
regset_get(t->task, &view->regsets[0],
|
||||||
sizeof(t->prstatus.pr_reg), &t->prstatus.pr_reg);
|
sizeof(t->prstatus.pr_reg), &t->prstatus.pr_reg);
|
||||||
|
|
||||||
|
@ -1958,7 +1958,7 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
|
||||||
struct task_struct *p = t->thread;
|
struct task_struct *p = t->thread;
|
||||||
t->num_notes = 0;
|
t->num_notes = 0;
|
||||||
|
|
||||||
fill_prstatus(&t->prstatus, p, signr);
|
fill_prstatus(&t->prstatus.common, p, signr);
|
||||||
elf_core_copy_task_regs(p, &t->prstatus.pr_reg);
|
elf_core_copy_task_regs(p, &t->prstatus.pr_reg);
|
||||||
|
|
||||||
fill_note(&t->notes[0], "CORE", NT_PRSTATUS, sizeof(t->prstatus),
|
fill_note(&t->notes[0], "CORE", NT_PRSTATUS, sizeof(t->prstatus),
|
||||||
|
@ -2037,7 +2037,7 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
|
||||||
}
|
}
|
||||||
/* now collect the dump for the current */
|
/* now collect the dump for the current */
|
||||||
memset(info->prstatus, 0, sizeof(*info->prstatus));
|
memset(info->prstatus, 0, sizeof(*info->prstatus));
|
||||||
fill_prstatus(info->prstatus, current, siginfo->si_signo);
|
fill_prstatus(&info->prstatus->common, current, siginfo->si_signo);
|
||||||
elf_core_copy_regs(&info->prstatus->pr_reg, regs);
|
elf_core_copy_regs(&info->prstatus->pr_reg, regs);
|
||||||
|
|
||||||
/* Set up header */
|
/* Set up header */
|
||||||
|
|
|
@ -1191,18 +1191,7 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
|
||||||
|
|
||||||
struct elf_prstatus_fdpic
|
struct elf_prstatus_fdpic
|
||||||
{
|
{
|
||||||
struct elf_siginfo pr_info; /* Info associated with signal */
|
struct elf_prstatus_common common;
|
||||||
short pr_cursig; /* Current signal */
|
|
||||||
unsigned long pr_sigpend; /* Set of pending signals */
|
|
||||||
unsigned long pr_sighold; /* Set of held signals */
|
|
||||||
pid_t pr_pid;
|
|
||||||
pid_t pr_ppid;
|
|
||||||
pid_t pr_pgrp;
|
|
||||||
pid_t pr_sid;
|
|
||||||
struct __kernel_old_timeval pr_utime; /* User time */
|
|
||||||
struct __kernel_old_timeval pr_stime; /* System time */
|
|
||||||
struct __kernel_old_timeval pr_cutime; /* Cumulative user time */
|
|
||||||
struct __kernel_old_timeval pr_cstime; /* Cumulative system time */
|
|
||||||
elf_gregset_t pr_reg; /* GP registers */
|
elf_gregset_t pr_reg; /* GP registers */
|
||||||
/* When using FDPIC, the loadmap addresses need to be communicated
|
/* When using FDPIC, the loadmap addresses need to be communicated
|
||||||
* to GDB in order for GDB to do the necessary relocations. The
|
* to GDB in order for GDB to do the necessary relocations. The
|
||||||
|
@ -1301,7 +1290,7 @@ static inline void fill_note(struct memelfnote *note, const char *name, int type
|
||||||
* fill up all the fields in prstatus from the given task struct, except
|
* fill up all the fields in prstatus from the given task struct, except
|
||||||
* registers which need to be filled up separately.
|
* registers which need to be filled up separately.
|
||||||
*/
|
*/
|
||||||
static void fill_prstatus(struct elf_prstatus_fdpic *prstatus,
|
static void fill_prstatus(struct elf_prstatus_common *prstatus,
|
||||||
struct task_struct *p, long signr)
|
struct task_struct *p, long signr)
|
||||||
{
|
{
|
||||||
prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
|
prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
|
||||||
|
@ -1332,9 +1321,6 @@ static void fill_prstatus(struct elf_prstatus_fdpic *prstatus,
|
||||||
}
|
}
|
||||||
prstatus->pr_cutime = ns_to_kernel_old_timeval(p->signal->cutime);
|
prstatus->pr_cutime = ns_to_kernel_old_timeval(p->signal->cutime);
|
||||||
prstatus->pr_cstime = ns_to_kernel_old_timeval(p->signal->cstime);
|
prstatus->pr_cstime = ns_to_kernel_old_timeval(p->signal->cstime);
|
||||||
|
|
||||||
prstatus->pr_exec_fdpic_loadmap = p->mm->context.exec_fdpic_loadmap;
|
|
||||||
prstatus->pr_interp_fdpic_loadmap = p->mm->context.interp_fdpic_loadmap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
|
static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
|
||||||
|
@ -1405,7 +1391,9 @@ static struct elf_thread_status *elf_dump_thread_status(long signr, struct task_
|
||||||
if (!t)
|
if (!t)
|
||||||
return t;
|
return t;
|
||||||
|
|
||||||
fill_prstatus(&t->prstatus, p, signr);
|
fill_prstatus(&t->prstatus.common, p, signr);
|
||||||
|
t->prstatus.pr_exec_fdpic_loadmap = p->mm->context.exec_fdpic_loadmap;
|
||||||
|
t->prstatus.pr_interp_fdpic_loadmap = p->mm->context.interp_fdpic_loadmap;
|
||||||
regset_get(p, &view->regsets[0],
|
regset_get(p, &view->regsets[0],
|
||||||
sizeof(t->prstatus.pr_reg), &t->prstatus.pr_reg);
|
sizeof(t->prstatus.pr_reg), &t->prstatus.pr_reg);
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
* which requires asm/elf.h to define compat_elf_gregset_t et al.
|
* which requires asm/elf.h to define compat_elf_gregset_t et al.
|
||||||
*/
|
*/
|
||||||
#define elf_prstatus compat_elf_prstatus
|
#define elf_prstatus compat_elf_prstatus
|
||||||
|
#define elf_prstatus_common compat_elf_prstatus_common
|
||||||
#define elf_prpsinfo compat_elf_prpsinfo
|
#define elf_prpsinfo compat_elf_prpsinfo
|
||||||
|
|
||||||
#undef ns_to_kernel_old_timeval
|
#undef ns_to_kernel_old_timeval
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct compat_elf_siginfo
|
||||||
compat_int_t si_errno;
|
compat_int_t si_errno;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct compat_elf_prstatus
|
struct compat_elf_prstatus_common
|
||||||
{
|
{
|
||||||
struct compat_elf_siginfo pr_info;
|
struct compat_elf_siginfo pr_info;
|
||||||
short pr_cursig;
|
short pr_cursig;
|
||||||
|
@ -31,6 +31,11 @@ struct compat_elf_prstatus
|
||||||
struct old_timeval32 pr_stime;
|
struct old_timeval32 pr_stime;
|
||||||
struct old_timeval32 pr_cutime;
|
struct old_timeval32 pr_cutime;
|
||||||
struct old_timeval32 pr_cstime;
|
struct old_timeval32 pr_cstime;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct compat_elf_prstatus
|
||||||
|
{
|
||||||
|
struct compat_elf_prstatus_common common;
|
||||||
compat_elf_gregset_t pr_reg;
|
compat_elf_gregset_t pr_reg;
|
||||||
compat_int_t pr_fpvalid;
|
compat_int_t pr_fpvalid;
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,7 +29,7 @@ struct elf_siginfo
|
||||||
* the SVR4 structure, but more Linuxy, with things that Linux does
|
* the SVR4 structure, but more Linuxy, with things that Linux does
|
||||||
* not support and which gdb doesn't really use excluded.
|
* not support and which gdb doesn't really use excluded.
|
||||||
*/
|
*/
|
||||||
struct elf_prstatus
|
struct elf_prstatus_common
|
||||||
{
|
{
|
||||||
struct elf_siginfo pr_info; /* Info associated with signal */
|
struct elf_siginfo pr_info; /* Info associated with signal */
|
||||||
short pr_cursig; /* Current signal */
|
short pr_cursig; /* Current signal */
|
||||||
|
@ -43,6 +43,11 @@ struct elf_prstatus
|
||||||
struct __kernel_old_timeval pr_stime; /* System time */
|
struct __kernel_old_timeval pr_stime; /* System time */
|
||||||
struct __kernel_old_timeval pr_cutime; /* Cumulative user time */
|
struct __kernel_old_timeval pr_cutime; /* Cumulative user time */
|
||||||
struct __kernel_old_timeval pr_cstime; /* Cumulative system time */
|
struct __kernel_old_timeval pr_cstime; /* Cumulative system time */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct elf_prstatus
|
||||||
|
{
|
||||||
|
struct elf_prstatus_common common;
|
||||||
elf_gregset_t pr_reg; /* GP registers */
|
elf_gregset_t pr_reg; /* GP registers */
|
||||||
int pr_fpvalid; /* True if math co-processor being used. */
|
int pr_fpvalid; /* True if math co-processor being used. */
|
||||||
};
|
};
|
||||||
|
|
|
@ -1076,7 +1076,7 @@ void crash_save_cpu(struct pt_regs *regs, int cpu)
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return;
|
return;
|
||||||
memset(&prstatus, 0, sizeof(prstatus));
|
memset(&prstatus, 0, sizeof(prstatus));
|
||||||
prstatus.pr_pid = current->pid;
|
prstatus.common.pr_pid = current->pid;
|
||||||
elf_core_copy_kernel_regs(&prstatus.pr_reg, regs);
|
elf_core_copy_kernel_regs(&prstatus.pr_reg, regs);
|
||||||
buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS,
|
buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS,
|
||||||
&prstatus, sizeof(prstatus));
|
&prstatus, sizeof(prstatus));
|
||||||
|
|
Loading…
Reference in New Issue