Unification of regset and non-regset sides of ELF coredump
handling. Collecting per-thread register values is the only thing that needs to be ifdefed there... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQQqUNBr3gm4hGXdBJlZ7Krx/gZQ6wUCY5ZyNgAKCRBZ7Krx/gZQ 63MZAQDZDE9Pk9EQ/3qOPNb2cuz8KSB3THUyotvustUUGPTUVAD/Ut1xD03jpWCY oQ6tM8dNyh3+Vsx6/XKNd1+pj6IgNQE= =XYkZ -----END PGP SIGNATURE----- Merge tag 'pull-elfcore' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs Pull elf coredumping updates from Al Viro: "Unification of regset and non-regset sides of ELF coredump handling. Collecting per-thread register values is the only thing that needs to be ifdefed there..." * tag 'pull-elfcore' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: [elf] get rid of get_note_info_size() [elf] unify regset and non-regset cases [elf][non-regset] use elf_core_copy_task_regs() for dumper as well [elf][non-regset] uninline elf_core_copy_task_fpregs() (and lose pt_regs argument) elf_core_copy_task_regs(): task_pt_regs is defined everywhere [elf][regset] simplify thread list handling in fill_note_info() [elf][regset] clean fill_note_info() a bit kill extern of vsyscall32_sysctl kill coredump_params->regs kill signal_pt_regs()
This commit is contained in:
Коммит
405b2fc663
|
@ -120,12 +120,6 @@ extern int dump_elf_task(elf_greg_t *dest, struct task_struct *task);
|
|||
#define ELF_CORE_COPY_TASK_REGS(TASK, DEST) \
|
||||
dump_elf_task(*(DEST), TASK)
|
||||
|
||||
/* Similar, but for the FP registers. */
|
||||
|
||||
extern int dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task);
|
||||
#define ELF_CORE_COPY_FPREGS(TASK, DEST) \
|
||||
dump_elf_task_fp(*(DEST), TASK)
|
||||
|
||||
/* This yields a mask that user programs can use to figure out what
|
||||
instruction set this CPU supports. This is trivial on Alpha,
|
||||
but not so on other machines. */
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
#define current_pt_regs() \
|
||||
((struct pt_regs *) ((char *)current_thread_info() + 2*PAGE_SIZE) - 1)
|
||||
#define signal_pt_regs current_pt_regs
|
||||
|
||||
#define force_successful_syscall_return() (current_pt_regs()->r0 = 0)
|
||||
|
||||
|
|
|
@ -333,14 +333,12 @@ dump_elf_task(elf_greg_t *dest, struct task_struct *task)
|
|||
}
|
||||
EXPORT_SYMBOL(dump_elf_task);
|
||||
|
||||
int
|
||||
dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task)
|
||||
int elf_core_copy_task_fpregs(struct task_struct *t, elf_fpregset_t *fpu)
|
||||
{
|
||||
struct switch_stack *sw = (struct switch_stack *)task_pt_regs(task) - 1;
|
||||
memcpy(dest, sw->fp, 32 * 8);
|
||||
struct switch_stack *sw = (struct switch_stack *)task_pt_regs(t) - 1;
|
||||
memcpy(fpu, sw->fp, 32 * 8);
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL(dump_elf_task_fp);
|
||||
|
||||
/*
|
||||
* Return saved PC of a blocked thread. This assumes the frame
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <linux/kallsyms.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/elfcore.h>
|
||||
|
||||
#include <asm/elf.h>
|
||||
#include <abi/reg_ops.h>
|
||||
|
@ -69,12 +70,11 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
|
|||
}
|
||||
|
||||
/* Fill in the fpu structure for a core dump. */
|
||||
int dump_fpu(struct pt_regs *regs, struct user_fp *fpu)
|
||||
int elf_core_copy_task_fpregs(struct task_struct *t, elf_fpregset_t *fpu)
|
||||
{
|
||||
memcpy(fpu, ¤t->thread.user_fp, sizeof(*fpu));
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL(dump_fpu);
|
||||
|
||||
int dump_task_regs(struct task_struct *tsk, elf_gregset_t *pr_regs)
|
||||
{
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <linux/rcupdate.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/elfcore.h>
|
||||
|
||||
#include <asm/traps.h>
|
||||
#include <asm/machdep.h>
|
||||
|
@ -213,7 +214,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
|
|||
}
|
||||
|
||||
/* Fill in the fpu structure for a core dump. */
|
||||
int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
|
||||
int elf_core_copy_task_fpregs(struct task_struct *t, elf_fpregset_t *fpu)
|
||||
{
|
||||
if (FPU_IS_EMU) {
|
||||
int i;
|
||||
|
@ -262,7 +263,6 @@ int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
|
|||
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL(dump_fpu);
|
||||
|
||||
unsigned long __get_wchan(struct task_struct *p)
|
||||
{
|
||||
|
|
|
@ -133,7 +133,7 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp)
|
|||
/*
|
||||
* Set up a thread for executing a new program
|
||||
*/
|
||||
int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs)
|
||||
int elf_core_copy_task_fpregs(struct task_struct *t, elf_fpregset_t *fpu)
|
||||
{
|
||||
return 0; /* MicroBlaze has no separate FPU registers */
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <skas.h>
|
||||
#include <registers.h>
|
||||
#include <linux/time-internal.h>
|
||||
#include <linux/elfcore.h>
|
||||
|
||||
/*
|
||||
* This is a per-cpu array. A processor only modifies its entry and it only
|
||||
|
@ -393,7 +394,7 @@ unsigned long __get_wchan(struct task_struct *p)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu)
|
||||
int elf_core_copy_task_fpregs(struct task_struct *t, elf_fpregset_t *fpu)
|
||||
{
|
||||
int cpu = current_thread_info()->cpu;
|
||||
|
||||
|
|
|
@ -222,7 +222,6 @@ do { \
|
|||
/* I'm not sure if we can use '-' here */
|
||||
#define ELF_PLATFORM ("x86_64")
|
||||
extern void set_personality_64bit(void);
|
||||
extern unsigned int sysctl_vsyscall32;
|
||||
extern int force_personality32;
|
||||
|
||||
#endif /* !CONFIG_X86_32 */
|
||||
|
|
|
@ -201,10 +201,6 @@ typedef struct user_i387_struct elf_fpregset_t;
|
|||
|
||||
struct task_struct;
|
||||
|
||||
extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu);
|
||||
|
||||
#define ELF_CORE_COPY_FPREGS(t, fpu) elf_core_copy_fpregs(t, fpu)
|
||||
|
||||
#define ELF_EXEC_PAGESIZE 4096
|
||||
|
||||
#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
|
||||
|
|
271
fs/binfmt_elf.c
271
fs/binfmt_elf.c
|
@ -1718,7 +1718,6 @@ static int fill_files_note(struct memelfnote *note, struct coredump_params *cprm
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CORE_DUMP_USE_REGSET
|
||||
#include <linux/regset.h>
|
||||
|
||||
struct elf_thread_core_info {
|
||||
|
@ -1739,6 +1738,7 @@ struct elf_note_info {
|
|||
int thread_notes;
|
||||
};
|
||||
|
||||
#ifdef CORE_DUMP_USE_REGSET
|
||||
/*
|
||||
* When a regset has a writeback hook, we call it on each thread before
|
||||
* dumping user memory. On register window machines, this makes sure the
|
||||
|
@ -1818,34 +1818,58 @@ static int fill_thread_core_info(struct elf_thread_core_info *t,
|
|||
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
static int fill_thread_core_info(struct elf_thread_core_info *t,
|
||||
const struct user_regset_view *view,
|
||||
long signr, struct elf_note_info *info)
|
||||
{
|
||||
struct task_struct *p = t->task;
|
||||
elf_fpregset_t *fpu;
|
||||
|
||||
fill_prstatus(&t->prstatus.common, p, signr);
|
||||
elf_core_copy_task_regs(p, &t->prstatus.pr_reg);
|
||||
|
||||
fill_note(&t->notes[0], "CORE", NT_PRSTATUS, sizeof(t->prstatus),
|
||||
&(t->prstatus));
|
||||
info->size += notesize(&t->notes[0]);
|
||||
|
||||
fpu = kzalloc(sizeof(elf_fpregset_t), GFP_KERNEL);
|
||||
if (!fpu || !elf_core_copy_task_fpregs(p, fpu)) {
|
||||
kfree(fpu);
|
||||
return 1;
|
||||
}
|
||||
|
||||
t->prstatus.pr_fpvalid = 1;
|
||||
fill_note(&t->notes[1], "CORE", NT_PRFPREG, sizeof(*fpu), fpu);
|
||||
info->size += notesize(&t->notes[1]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int fill_note_info(struct elfhdr *elf, int phdrs,
|
||||
struct elf_note_info *info,
|
||||
struct coredump_params *cprm)
|
||||
{
|
||||
struct task_struct *dump_task = current;
|
||||
const struct user_regset_view *view = task_user_regset_view(dump_task);
|
||||
const struct user_regset_view *view;
|
||||
struct elf_thread_core_info *t;
|
||||
struct elf_prpsinfo *psinfo;
|
||||
struct core_thread *ct;
|
||||
unsigned int i;
|
||||
|
||||
info->size = 0;
|
||||
info->thread = NULL;
|
||||
|
||||
psinfo = kmalloc(sizeof(*psinfo), GFP_KERNEL);
|
||||
if (psinfo == NULL) {
|
||||
info->psinfo.data = NULL; /* So we don't free this wrongly */
|
||||
if (!psinfo)
|
||||
return 0;
|
||||
}
|
||||
|
||||
fill_note(&info->psinfo, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo);
|
||||
|
||||
#ifdef CORE_DUMP_USE_REGSET
|
||||
view = task_user_regset_view(dump_task);
|
||||
|
||||
/*
|
||||
* Figure out how many notes we're going to need for each thread.
|
||||
*/
|
||||
info->thread_notes = 0;
|
||||
for (i = 0; i < view->n; ++i)
|
||||
for (int i = 0; i < view->n; ++i)
|
||||
if (view->regsets[i].core_note_type != 0)
|
||||
++info->thread_notes;
|
||||
|
||||
|
@ -1864,11 +1888,23 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
|
|||
*/
|
||||
fill_elf_header(elf, phdrs,
|
||||
view->e_machine, view->e_flags);
|
||||
#else
|
||||
view = NULL;
|
||||
info->thread_notes = 2;
|
||||
fill_elf_header(elf, phdrs, ELF_ARCH, ELF_CORE_EFLAGS);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Allocate a structure for each thread.
|
||||
*/
|
||||
for (ct = &dump_task->signal->core_state->dumper; ct; ct = ct->next) {
|
||||
info->thread = kzalloc(offsetof(struct elf_thread_core_info,
|
||||
notes[info->thread_notes]),
|
||||
GFP_KERNEL);
|
||||
if (unlikely(!info->thread))
|
||||
return 0;
|
||||
|
||||
info->thread->task = dump_task;
|
||||
for (ct = dump_task->signal->core_state->dumper.next; ct; ct = ct->next) {
|
||||
t = kzalloc(offsetof(struct elf_thread_core_info,
|
||||
notes[info->thread_notes]),
|
||||
GFP_KERNEL);
|
||||
|
@ -1876,17 +1912,8 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
|
|||
return 0;
|
||||
|
||||
t->task = ct->task;
|
||||
if (ct->task == dump_task || !info->thread) {
|
||||
t->next = info->thread;
|
||||
info->thread = t;
|
||||
} else {
|
||||
/*
|
||||
* Make sure to keep the original task at
|
||||
* the head of the list.
|
||||
*/
|
||||
t->next = info->thread->next;
|
||||
info->thread->next = t;
|
||||
}
|
||||
t->next = info->thread->next;
|
||||
info->thread->next = t;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1914,11 +1941,6 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static size_t get_note_info_size(struct elf_note_info *info)
|
||||
{
|
||||
return info->size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write all the notes for each thread. When writing the first thread, the
|
||||
* process-wide notes are interleaved after the first thread-specific note.
|
||||
|
@ -1973,197 +1995,6 @@ static void free_note_info(struct elf_note_info *info)
|
|||
kvfree(info->files.data);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Here is the structure in which status of each thread is captured. */
|
||||
struct elf_thread_status
|
||||
{
|
||||
struct list_head list;
|
||||
struct elf_prstatus prstatus; /* NT_PRSTATUS */
|
||||
elf_fpregset_t fpu; /* NT_PRFPREG */
|
||||
struct task_struct *thread;
|
||||
struct memelfnote notes[3];
|
||||
int num_notes;
|
||||
};
|
||||
|
||||
/*
|
||||
* In order to add the specific thread information for the elf file format,
|
||||
* we need to keep a linked list of every threads pr_status and then create
|
||||
* a single section for them in the final core file.
|
||||
*/
|
||||
static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
|
||||
{
|
||||
int sz = 0;
|
||||
struct task_struct *p = t->thread;
|
||||
t->num_notes = 0;
|
||||
|
||||
fill_prstatus(&t->prstatus.common, p, signr);
|
||||
elf_core_copy_task_regs(p, &t->prstatus.pr_reg);
|
||||
|
||||
fill_note(&t->notes[0], "CORE", NT_PRSTATUS, sizeof(t->prstatus),
|
||||
&(t->prstatus));
|
||||
t->num_notes++;
|
||||
sz += notesize(&t->notes[0]);
|
||||
|
||||
if ((t->prstatus.pr_fpvalid = elf_core_copy_task_fpregs(p, NULL,
|
||||
&t->fpu))) {
|
||||
fill_note(&t->notes[1], "CORE", NT_PRFPREG, sizeof(t->fpu),
|
||||
&(t->fpu));
|
||||
t->num_notes++;
|
||||
sz += notesize(&t->notes[1]);
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
struct elf_note_info {
|
||||
struct memelfnote *notes;
|
||||
struct memelfnote *notes_files;
|
||||
struct elf_prstatus *prstatus; /* NT_PRSTATUS */
|
||||
struct elf_prpsinfo *psinfo; /* NT_PRPSINFO */
|
||||
struct list_head thread_list;
|
||||
elf_fpregset_t *fpu;
|
||||
user_siginfo_t csigdata;
|
||||
int thread_status_size;
|
||||
int numnote;
|
||||
};
|
||||
|
||||
static int elf_note_info_init(struct elf_note_info *info)
|
||||
{
|
||||
memset(info, 0, sizeof(*info));
|
||||
INIT_LIST_HEAD(&info->thread_list);
|
||||
|
||||
/* Allocate space for ELF notes */
|
||||
info->notes = kmalloc_array(8, sizeof(struct memelfnote), GFP_KERNEL);
|
||||
if (!info->notes)
|
||||
return 0;
|
||||
info->psinfo = kmalloc(sizeof(*info->psinfo), GFP_KERNEL);
|
||||
if (!info->psinfo)
|
||||
return 0;
|
||||
info->prstatus = kmalloc(sizeof(*info->prstatus), GFP_KERNEL);
|
||||
if (!info->prstatus)
|
||||
return 0;
|
||||
info->fpu = kmalloc(sizeof(*info->fpu), GFP_KERNEL);
|
||||
if (!info->fpu)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int fill_note_info(struct elfhdr *elf, int phdrs,
|
||||
struct elf_note_info *info,
|
||||
struct coredump_params *cprm)
|
||||
{
|
||||
struct core_thread *ct;
|
||||
struct elf_thread_status *ets;
|
||||
|
||||
if (!elf_note_info_init(info))
|
||||
return 0;
|
||||
|
||||
for (ct = current->signal->core_state->dumper.next;
|
||||
ct; ct = ct->next) {
|
||||
ets = kzalloc(sizeof(*ets), GFP_KERNEL);
|
||||
if (!ets)
|
||||
return 0;
|
||||
|
||||
ets->thread = ct->task;
|
||||
list_add(&ets->list, &info->thread_list);
|
||||
}
|
||||
|
||||
list_for_each_entry(ets, &info->thread_list, list) {
|
||||
int sz;
|
||||
|
||||
sz = elf_dump_thread_status(cprm->siginfo->si_signo, ets);
|
||||
info->thread_status_size += sz;
|
||||
}
|
||||
/* now collect the dump for the current */
|
||||
memset(info->prstatus, 0, sizeof(*info->prstatus));
|
||||
fill_prstatus(&info->prstatus->common, current, cprm->siginfo->si_signo);
|
||||
elf_core_copy_regs(&info->prstatus->pr_reg, cprm->regs);
|
||||
|
||||
/* Set up header */
|
||||
fill_elf_header(elf, phdrs, ELF_ARCH, ELF_CORE_EFLAGS);
|
||||
|
||||
/*
|
||||
* Set up the notes in similar form to SVR4 core dumps made
|
||||
* with info from their /proc.
|
||||
*/
|
||||
|
||||
fill_note(info->notes + 0, "CORE", NT_PRSTATUS,
|
||||
sizeof(*info->prstatus), info->prstatus);
|
||||
fill_psinfo(info->psinfo, current->group_leader, current->mm);
|
||||
fill_note(info->notes + 1, "CORE", NT_PRPSINFO,
|
||||
sizeof(*info->psinfo), info->psinfo);
|
||||
|
||||
fill_siginfo_note(info->notes + 2, &info->csigdata, cprm->siginfo);
|
||||
fill_auxv_note(info->notes + 3, current->mm);
|
||||
info->numnote = 4;
|
||||
|
||||
if (fill_files_note(info->notes + info->numnote, cprm) == 0) {
|
||||
info->notes_files = info->notes + info->numnote;
|
||||
info->numnote++;
|
||||
}
|
||||
|
||||
/* Try to dump the FPU. */
|
||||
info->prstatus->pr_fpvalid =
|
||||
elf_core_copy_task_fpregs(current, cprm->regs, info->fpu);
|
||||
if (info->prstatus->pr_fpvalid)
|
||||
fill_note(info->notes + info->numnote++,
|
||||
"CORE", NT_PRFPREG, sizeof(*info->fpu), info->fpu);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static size_t get_note_info_size(struct elf_note_info *info)
|
||||
{
|
||||
int sz = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < info->numnote; i++)
|
||||
sz += notesize(info->notes + i);
|
||||
|
||||
sz += info->thread_status_size;
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
static int write_note_info(struct elf_note_info *info,
|
||||
struct coredump_params *cprm)
|
||||
{
|
||||
struct elf_thread_status *ets;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < info->numnote; i++)
|
||||
if (!writenote(info->notes + i, cprm))
|
||||
return 0;
|
||||
|
||||
/* write out the thread status notes section */
|
||||
list_for_each_entry(ets, &info->thread_list, list) {
|
||||
for (i = 0; i < ets->num_notes; i++)
|
||||
if (!writenote(&ets->notes[i], cprm))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void free_note_info(struct elf_note_info *info)
|
||||
{
|
||||
while (!list_empty(&info->thread_list)) {
|
||||
struct list_head *tmp = info->thread_list.next;
|
||||
list_del(tmp);
|
||||
kfree(list_entry(tmp, struct elf_thread_status, list));
|
||||
}
|
||||
|
||||
/* Free data possibly allocated by fill_files_note(): */
|
||||
if (info->notes_files)
|
||||
kvfree(info->notes_files->data);
|
||||
|
||||
kfree(info->prstatus);
|
||||
kfree(info->psinfo);
|
||||
kfree(info->notes);
|
||||
kfree(info->fpu);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
|
||||
elf_addr_t e_shoff, int segs)
|
||||
{
|
||||
|
@ -2227,7 +2058,7 @@ static int elf_core_dump(struct coredump_params *cprm)
|
|||
|
||||
/* Write notes phdr entry */
|
||||
{
|
||||
size_t sz = get_note_info_size(&info);
|
||||
size_t sz = info.size;
|
||||
|
||||
/* For cell spufs */
|
||||
sz += elf_coredump_extra_notes_size();
|
||||
|
|
|
@ -529,7 +529,6 @@ void do_coredump(const kernel_siginfo_t *siginfo)
|
|||
static atomic_t core_dump_count = ATOMIC_INIT(0);
|
||||
struct coredump_params cprm = {
|
||||
.siginfo = siginfo,
|
||||
.regs = signal_pt_regs(),
|
||||
.limit = rlimit(RLIMIT_CORE),
|
||||
/*
|
||||
* We must use the same mm->flags while dumping core to avoid
|
||||
|
|
|
@ -18,7 +18,6 @@ struct core_vma_metadata {
|
|||
|
||||
struct coredump_params {
|
||||
const kernel_siginfo_t *siginfo;
|
||||
struct pt_regs *regs;
|
||||
struct file *file;
|
||||
unsigned long limit;
|
||||
unsigned long mm_flags;
|
||||
|
|
|
@ -88,22 +88,13 @@ static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t*
|
|||
{
|
||||
#if defined (ELF_CORE_COPY_TASK_REGS)
|
||||
return ELF_CORE_COPY_TASK_REGS(t, elfregs);
|
||||
#elif defined (task_pt_regs)
|
||||
#else
|
||||
elf_core_copy_regs(elfregs, task_pt_regs(t));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int dump_fpu (struct pt_regs *, elf_fpregset_t *);
|
||||
|
||||
static inline int elf_core_copy_task_fpregs(struct task_struct *t, struct pt_regs *regs, elf_fpregset_t *fpu)
|
||||
{
|
||||
#ifdef ELF_CORE_COPY_FPREGS
|
||||
return ELF_CORE_COPY_FPREGS(t, fpu);
|
||||
#else
|
||||
return dump_fpu(regs, fpu);
|
||||
#endif
|
||||
}
|
||||
int elf_core_copy_task_fpregs(struct task_struct *t, elf_fpregset_t *fpu);
|
||||
|
||||
#ifdef CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS
|
||||
/*
|
||||
|
|
|
@ -389,15 +389,6 @@ static inline void user_single_step_report(struct pt_regs *regs)
|
|||
#define current_pt_regs() task_pt_regs(current)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* unlike current_pt_regs(), this one is equal to task_pt_regs(current)
|
||||
* on *all* architectures; the only reason to have a per-arch definition
|
||||
* is optimisation.
|
||||
*/
|
||||
#ifndef signal_pt_regs
|
||||
#define signal_pt_regs() task_pt_regs(current)
|
||||
#endif
|
||||
|
||||
#ifndef current_user_stack_pointer
|
||||
#define current_user_stack_pointer() user_stack_pointer(current_pt_regs())
|
||||
#endif
|
||||
|
|
|
@ -1255,7 +1255,7 @@ int send_signal_locked(int sig, struct kernel_siginfo *info,
|
|||
|
||||
static void print_fatal_signal(int signr)
|
||||
{
|
||||
struct pt_regs *regs = signal_pt_regs();
|
||||
struct pt_regs *regs = task_pt_regs(current);
|
||||
pr_info("potentially unexpected fatal signal %d.\n", signr);
|
||||
|
||||
#if defined(__i386__) && !defined(__arch_um__)
|
||||
|
|
Загрузка…
Ссылка в новой задаче