93 lines
2.3 KiB
C
93 lines
2.3 KiB
C
/* coredump.c COPYRIGHT FUJITSU LIMITED 2015-2019 */
|
|
#include <process.h>
|
|
#include <elfcore.h>
|
|
#include <string.h>
|
|
#include <ptrace.h>
|
|
#include <cls.h>
|
|
#include <hwcap.h>
|
|
|
|
#define align32(x) ((((x) + 3) / 4) * 4)
|
|
|
|
void arch_fill_prstatus(struct elf_prstatus64 *prstatus,
|
|
struct thread *thread, void *regs0, int sig)
|
|
{
|
|
struct pt_regs *regs = regs0;
|
|
struct elf_prstatus64 tmp_prstatus;
|
|
/*
|
|
We ignore following entries for now.
|
|
|
|
struct elf_siginfo pr_info;
|
|
short int pr_cursig;
|
|
a8_uint64_t pr_sigpend;
|
|
a8_uint64_t pr_sighold;
|
|
pid_t pr_pgrp;
|
|
pid_t pr_sid;
|
|
struct prstatus64_timeval pr_utime;
|
|
struct prstatus64_timeval pr_stime;
|
|
struct prstatus64_timeval pr_cutime;
|
|
struct prstatus64_timeval pr_cstime;
|
|
*/
|
|
|
|
/* copy x0-30, sp, pc, pstate */
|
|
memcpy(&tmp_prstatus.pr_reg, ®s->user_regs, sizeof(tmp_prstatus.pr_reg));
|
|
tmp_prstatus.pr_fpvalid = 0; /* We assume no fp */
|
|
|
|
/* copy unaligned prstatus addr */
|
|
memcpy(prstatus, &tmp_prstatus, sizeof(*prstatus));
|
|
|
|
prstatus->pr_pid = thread->tid;
|
|
if (thread->proc->parent) {
|
|
prstatus->pr_ppid = thread->proc->parent->pid;
|
|
}
|
|
|
|
prstatus->pr_info.si_signo = sig;
|
|
prstatus->pr_cursig = sig;
|
|
}
|
|
|
|
int arch_get_thread_core_info_size(void)
|
|
{
|
|
const struct user_regset_view *view = current_user_regset_view();
|
|
const struct user_regset *regset = find_regset(view, NT_ARM_SVE);
|
|
|
|
if (unlikely(!(elf_hwcap & HWCAP_SVE))) {
|
|
return 0;
|
|
}
|
|
return sizeof(struct note) + align32(sizeof("LINUX"))
|
|
+ regset_size(cpu_local_var(current), regset);
|
|
}
|
|
|
|
void arch_fill_thread_core_info(struct note *head,
|
|
struct thread *thread, void *regs)
|
|
{
|
|
const struct user_regset_view *view = current_user_regset_view();
|
|
const struct user_regset *regset = find_regset(view, NT_ARM_SVE);
|
|
|
|
if (unlikely(!(elf_hwcap & HWCAP_SVE))) {
|
|
return;
|
|
}
|
|
|
|
/* pre saved registers */
|
|
save_fp_regs(thread);
|
|
|
|
if (regset->core_note_type && regset->get &&
|
|
(!regset->active || regset->active(thread, regset))) {
|
|
int ret;
|
|
size_t size = regset_size(thread, regset);
|
|
void *namep;
|
|
void *descp;
|
|
|
|
namep = (void *) (head + 1);
|
|
descp = namep + align32(sizeof("LINUX"));
|
|
|
|
ret = regset->get(thread, regset, 0, size, descp, NULL);
|
|
if (ret) {
|
|
return;
|
|
}
|
|
|
|
head->namesz = sizeof("LINUX");
|
|
head->descsz = size;
|
|
head->type = NT_ARM_SVE;
|
|
memcpy(namep, "LINUX", sizeof("LINUX"));
|
|
}
|
|
}
|