mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 01:20:52 +07:00
[elf-fdpic] use elf_dump_thread_status() for the dumper thread as well
the only reason to have it open-coded for the first (dumper) thread is that coredump has a couple of process-wide notes stuck right after the first (NT_PRSTATUS) note of the first thread. But we don't need to make the data collection side irregular for the first thread to handle that - it's only the logics ordering the calls of writenote() that needs to take care of that. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
38a62779ae
commit
d2f581684a
@ -1482,7 +1482,8 @@ static struct elf_thread_status *elf_dump_thread_status(long signr, struct task_
|
|||||||
t->num_notes++;
|
t->num_notes++;
|
||||||
*sz += notesize(&t->notes[0]);
|
*sz += notesize(&t->notes[0]);
|
||||||
|
|
||||||
t->prstatus.pr_fpvalid = elf_core_copy_task_fpregs(p, NULL, &t->fpu);
|
t->prstatus.pr_fpvalid = elf_core_copy_task_fpregs(p, task_pt_regs(p),
|
||||||
|
&t->fpu);
|
||||||
if (t->prstatus.pr_fpvalid) {
|
if (t->prstatus.pr_fpvalid) {
|
||||||
fill_note(&t->notes[1], "CORE", NT_PRFPREG, sizeof(t->fpu),
|
fill_note(&t->notes[1], "CORE", NT_PRFPREG, sizeof(t->fpu),
|
||||||
&t->fpu);
|
&t->fpu);
|
||||||
@ -1568,19 +1569,15 @@ static size_t elf_core_vma_data_size(unsigned long mm_flags)
|
|||||||
*/
|
*/
|
||||||
static int elf_fdpic_core_dump(struct coredump_params *cprm)
|
static int elf_fdpic_core_dump(struct coredump_params *cprm)
|
||||||
{
|
{
|
||||||
#define NUM_NOTES 6
|
|
||||||
int has_dumped = 0;
|
int has_dumped = 0;
|
||||||
int segs;
|
int segs;
|
||||||
int i;
|
int i;
|
||||||
struct vm_area_struct *vma;
|
struct vm_area_struct *vma;
|
||||||
struct elfhdr *elf = NULL;
|
struct elfhdr *elf = NULL;
|
||||||
loff_t offset = 0, dataoff;
|
loff_t offset = 0, dataoff;
|
||||||
int numnote;
|
struct memelfnote psinfo_note, auxv_note;
|
||||||
struct memelfnote *notes = NULL;
|
|
||||||
struct elf_prstatus_fdpic *prstatus = NULL; /* NT_PRSTATUS */
|
|
||||||
struct elf_prpsinfo *psinfo = NULL; /* NT_PRPSINFO */
|
struct elf_prpsinfo *psinfo = NULL; /* NT_PRPSINFO */
|
||||||
struct elf_thread_status *thread_list = NULL;
|
struct elf_thread_status *thread_list = NULL;
|
||||||
elf_fpregset_t *fpu = NULL;
|
|
||||||
int thread_status_size = 0;
|
int thread_status_size = 0;
|
||||||
elf_addr_t *auxv;
|
elf_addr_t *auxv;
|
||||||
struct elf_phdr *phdr4note = NULL;
|
struct elf_phdr *phdr4note = NULL;
|
||||||
@ -1606,19 +1603,9 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
|
|||||||
elf = kmalloc(sizeof(*elf), GFP_KERNEL);
|
elf = kmalloc(sizeof(*elf), GFP_KERNEL);
|
||||||
if (!elf)
|
if (!elf)
|
||||||
goto end_coredump;
|
goto end_coredump;
|
||||||
prstatus = kzalloc(sizeof(*prstatus), GFP_KERNEL);
|
|
||||||
if (!prstatus)
|
|
||||||
goto end_coredump;
|
|
||||||
psinfo = kmalloc(sizeof(*psinfo), GFP_KERNEL);
|
psinfo = kmalloc(sizeof(*psinfo), GFP_KERNEL);
|
||||||
if (!psinfo)
|
if (!psinfo)
|
||||||
goto end_coredump;
|
goto end_coredump;
|
||||||
notes = kmalloc_array(NUM_NOTES, sizeof(struct memelfnote),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!notes)
|
|
||||||
goto end_coredump;
|
|
||||||
fpu = kmalloc(sizeof(*fpu), GFP_KERNEL);
|
|
||||||
if (!fpu)
|
|
||||||
goto end_coredump;
|
|
||||||
|
|
||||||
for (ct = current->mm->core_state->dumper.next;
|
for (ct = current->mm->core_state->dumper.next;
|
||||||
ct; ct = ct->next) {
|
ct; ct = ct->next) {
|
||||||
@ -1632,8 +1619,12 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* now collect the dump for the current */
|
/* now collect the dump for the current */
|
||||||
fill_prstatus(prstatus, current, cprm->siginfo->si_signo);
|
tmp = elf_dump_thread_status(cprm->siginfo->si_signo,
|
||||||
elf_core_copy_regs(&prstatus->pr_reg, cprm->regs);
|
current, &thread_status_size);
|
||||||
|
if (!tmp)
|
||||||
|
goto end_coredump;
|
||||||
|
tmp->next = thread_list;
|
||||||
|
thread_list = tmp;
|
||||||
|
|
||||||
segs = current->mm->map_count;
|
segs = current->mm->map_count;
|
||||||
segs += elf_core_extra_phdrs();
|
segs += elf_core_extra_phdrs();
|
||||||
@ -1655,46 +1646,28 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
|
|||||||
* with info from their /proc.
|
* with info from their /proc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fill_note(notes + 0, "CORE", NT_PRSTATUS, sizeof(*prstatus), prstatus);
|
|
||||||
fill_psinfo(psinfo, current->group_leader, current->mm);
|
fill_psinfo(psinfo, current->group_leader, current->mm);
|
||||||
fill_note(notes + 1, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo);
|
fill_note(&psinfo_note, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo);
|
||||||
|
thread_status_size += notesize(&psinfo_note);
|
||||||
numnote = 2;
|
|
||||||
|
|
||||||
auxv = (elf_addr_t *) current->mm->saved_auxv;
|
auxv = (elf_addr_t *) current->mm->saved_auxv;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
do
|
do
|
||||||
i += 2;
|
i += 2;
|
||||||
while (auxv[i - 2] != AT_NULL);
|
while (auxv[i - 2] != AT_NULL);
|
||||||
fill_note(¬es[numnote++], "CORE", NT_AUXV,
|
fill_note(&auxv_note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv);
|
||||||
i * sizeof(elf_addr_t), auxv);
|
thread_status_size += notesize(&auxv_note);
|
||||||
|
|
||||||
/* Try to dump the FPU. */
|
offset = sizeof(*elf); /* Elf header */
|
||||||
if ((prstatus->pr_fpvalid =
|
|
||||||
elf_core_copy_task_fpregs(current, cprm->regs, fpu)))
|
|
||||||
fill_note(notes + numnote++,
|
|
||||||
"CORE", NT_PRFPREG, sizeof(*fpu), fpu);
|
|
||||||
|
|
||||||
offset += sizeof(*elf); /* Elf header */
|
|
||||||
offset += segs * sizeof(struct elf_phdr); /* Program headers */
|
offset += segs * sizeof(struct elf_phdr); /* Program headers */
|
||||||
|
|
||||||
/* Write notes phdr entry */
|
/* Write notes phdr entry */
|
||||||
{
|
phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL);
|
||||||
int sz = 0;
|
if (!phdr4note)
|
||||||
|
goto end_coredump;
|
||||||
|
|
||||||
for (i = 0; i < numnote; i++)
|
fill_elf_note_phdr(phdr4note, thread_status_size, offset);
|
||||||
sz += notesize(notes + i);
|
offset += thread_status_size;
|
||||||
|
|
||||||
sz += thread_status_size;
|
|
||||||
|
|
||||||
phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL);
|
|
||||||
if (!phdr4note)
|
|
||||||
goto end_coredump;
|
|
||||||
|
|
||||||
fill_elf_note_phdr(phdr4note, sz, offset);
|
|
||||||
offset += sz;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Page-align dumped data */
|
/* Page-align dumped data */
|
||||||
dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
|
dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
|
||||||
@ -1747,12 +1720,18 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
|
|||||||
goto end_coredump;
|
goto end_coredump;
|
||||||
|
|
||||||
/* write out the notes section */
|
/* write out the notes section */
|
||||||
for (i = 0; i < numnote; i++)
|
if (!writenote(thread_list->notes, cprm))
|
||||||
if (!writenote(notes + i, cprm))
|
goto end_coredump;
|
||||||
|
if (!writenote(&psinfo_note, cprm))
|
||||||
|
goto end_coredump;
|
||||||
|
if (!writenote(&auxv_note, cprm))
|
||||||
|
goto end_coredump;
|
||||||
|
for (i = 1; i < thread_list->num_notes; i++)
|
||||||
|
if (!writenote(thread_list->notes + i, cprm))
|
||||||
goto end_coredump;
|
goto end_coredump;
|
||||||
|
|
||||||
/* write out the thread status notes section */
|
/* write out the thread status notes section */
|
||||||
for (tmp = thread_list; tmp; tmp = tmp->next) {
|
for (tmp = thread_list->next; tmp; tmp = tmp->next) {
|
||||||
for (i = 0; i < tmp->num_notes; i++)
|
for (i = 0; i < tmp->num_notes; i++)
|
||||||
if (!writenote(&tmp->notes[i], cprm))
|
if (!writenote(&tmp->notes[i], cprm))
|
||||||
goto end_coredump;
|
goto end_coredump;
|
||||||
@ -1787,13 +1766,9 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
|
|||||||
}
|
}
|
||||||
kfree(phdr4note);
|
kfree(phdr4note);
|
||||||
kfree(elf);
|
kfree(elf);
|
||||||
kfree(prstatus);
|
|
||||||
kfree(psinfo);
|
kfree(psinfo);
|
||||||
kfree(notes);
|
|
||||||
kfree(fpu);
|
|
||||||
kfree(shdr4extnum);
|
kfree(shdr4extnum);
|
||||||
return has_dumped;
|
return has_dumped;
|
||||||
#undef NUM_NOTES
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_ELF_CORE */
|
#endif /* CONFIG_ELF_CORE */
|
||||||
|
Loading…
Reference in New Issue
Block a user