elf/coredump: add support of dump task stack without memory segments
Signed-off-by: chao an <anchao@xiaomi.com>
This commit is contained in:
parent
0133831a70
commit
24f4216066
@ -44,7 +44,8 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int core_dump(FAR struct memory_region_s *regions,
|
int core_dump(FAR struct memory_region_s *regions,
|
||||||
FAR struct lib_outstream_s *stream)
|
FAR struct lib_outstream_s *stream,
|
||||||
|
pid_t pid)
|
||||||
{
|
{
|
||||||
FAR struct binfmt_s *binfmt;
|
FAR struct binfmt_s *binfmt;
|
||||||
int ret = -ENOENT;
|
int ret = -ENOENT;
|
||||||
@ -55,7 +56,7 @@ int core_dump(FAR struct memory_region_s *regions,
|
|||||||
|
|
||||||
if (binfmt->coredump)
|
if (binfmt->coredump)
|
||||||
{
|
{
|
||||||
ret = binfmt->coredump(regions, stream);
|
ret = binfmt->coredump(regions, stream, pid);
|
||||||
if (ret == OK)
|
if (ret == OK)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
@ -71,7 +71,8 @@ static int elf_loadbinary(FAR struct binary_s *binp,
|
|||||||
int nexports);
|
int nexports);
|
||||||
#ifdef CONFIG_ELF_COREDUMP
|
#ifdef CONFIG_ELF_COREDUMP
|
||||||
static int elf_dumpbinary(FAR struct memory_region_s *regions,
|
static int elf_dumpbinary(FAR struct memory_region_s *regions,
|
||||||
FAR struct lib_outstream_s *stream);
|
FAR struct lib_outstream_s *stream,
|
||||||
|
pid_t pid);
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_DEBUG_FEATURES) && defined(CONFIG_DEBUG_BINFMT)
|
#if defined(CONFIG_DEBUG_FEATURES) && defined(CONFIG_DEBUG_BINFMT)
|
||||||
static void elf_dumploadinfo(FAR struct elf_loadinfo_s *loadinfo);
|
static void elf_dumploadinfo(FAR struct elf_loadinfo_s *loadinfo);
|
||||||
@ -316,12 +317,14 @@ errout_with_init:
|
|||||||
|
|
||||||
#ifdef CONFIG_ELF_COREDUMP
|
#ifdef CONFIG_ELF_COREDUMP
|
||||||
static int elf_dumpbinary(FAR struct memory_region_s *regions,
|
static int elf_dumpbinary(FAR struct memory_region_s *regions,
|
||||||
FAR struct lib_outstream_s *stream)
|
FAR struct lib_outstream_s *stream,
|
||||||
|
pid_t pid)
|
||||||
{
|
{
|
||||||
struct elf_dumpinfo_s dumpinfo;
|
struct elf_dumpinfo_s dumpinfo;
|
||||||
|
|
||||||
dumpinfo.regions = regions;
|
dumpinfo.regions = regions;
|
||||||
dumpinfo.stream = stream;
|
dumpinfo.stream = stream;
|
||||||
|
dumpinfo.pid = pid;
|
||||||
|
|
||||||
return elf_coredump(&dumpinfo);
|
return elf_coredump(&dumpinfo);
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
#include <nuttx/arch.h>
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -43,10 +44,20 @@
|
|||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#define ELF_PAGESIZE 4096
|
#ifdef PAGESIZE
|
||||||
|
# define ELF_PAGESIZE PAGESIZE
|
||||||
|
#else
|
||||||
|
# define ELF_PAGESIZE 1024
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ROUNDUP(x, y) ((x + (y - 1)) / (y)) * (y)
|
#define ROUNDUP(x, y) ((x + (y - 1)) / (y)) * (y)
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static uint8_t g_running_regs[XCPTCONTEXT_SIZE] aligned_data(16);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -128,14 +139,14 @@ static int elf_emit_align(FAR struct elf_dumpinfo_s *cinfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: elf_emit_header
|
* Name: elf_emit_hdr
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Fill the elf header
|
* Fill the elf header
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int elf_emit_header(FAR struct elf_dumpinfo_s *cinfo,
|
static int elf_emit_hdr(FAR struct elf_dumpinfo_s *cinfo,
|
||||||
int segs)
|
int segs)
|
||||||
{
|
{
|
||||||
Elf_Ehdr ehdr;
|
Elf_Ehdr ehdr;
|
||||||
@ -160,6 +171,30 @@ static int elf_emit_header(FAR struct elf_dumpinfo_s *cinfo,
|
|||||||
return elf_emit(cinfo, &ehdr, sizeof(ehdr));
|
return elf_emit(cinfo, &ehdr, sizeof(ehdr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: elf_get_ntcb
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Calculate the note segment size
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int elf_get_ntcb(void)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < g_npidhash; i++)
|
||||||
|
{
|
||||||
|
if (g_pidhash[i] != NULL)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: elf_get_note_size
|
* Name: elf_get_note_size
|
||||||
*
|
*
|
||||||
@ -168,57 +203,38 @@ static int elf_emit_header(FAR struct elf_dumpinfo_s *cinfo,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int elf_get_note_size(void)
|
static int elf_get_note_size(int stksegs)
|
||||||
{
|
{
|
||||||
int count = 0;
|
|
||||||
int total;
|
int total;
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < g_npidhash; i++)
|
total = stksegs * (sizeof(Elf_Nhdr) + ROUNDUP(CONFIG_TASK_NAME_SIZE, 8) +
|
||||||
{
|
|
||||||
if (g_pidhash[i])
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
total = count * (sizeof(Elf_Nhdr) + ROUNDUP(CONFIG_TASK_NAME_SIZE, 8) +
|
|
||||||
sizeof(elf_prstatus_t));
|
sizeof(elf_prstatus_t));
|
||||||
total += count * (sizeof(Elf_Nhdr) + ROUNDUP(CONFIG_TASK_NAME_SIZE, 8) +
|
total += stksegs * (sizeof(Elf_Nhdr) + ROUNDUP(CONFIG_TASK_NAME_SIZE, 8) +
|
||||||
sizeof(elf_prpsinfo_t));
|
sizeof(elf_prpsinfo_t));
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: elf_emit_note_info
|
* Name: elf_emit_tcb_note
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Fill the note segment information
|
* Fill the note segment information from tcb
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void elf_emit_note_info(FAR struct elf_dumpinfo_s *cinfo)
|
static void elf_emit_tcb_note(FAR struct elf_dumpinfo_s *cinfo,
|
||||||
|
FAR struct tcb_s *tcb)
|
||||||
{
|
{
|
||||||
char name[ROUNDUP(CONFIG_TASK_NAME_SIZE, 8)];
|
char name[ROUNDUP(CONFIG_TASK_NAME_SIZE, 8)];
|
||||||
FAR struct tcb_s *tcb;
|
|
||||||
elf_prstatus_t status;
|
elf_prstatus_t status;
|
||||||
elf_prpsinfo_t info;
|
elf_prpsinfo_t info;
|
||||||
|
FAR uint32_t *regs;
|
||||||
Elf_Nhdr nhdr;
|
Elf_Nhdr nhdr;
|
||||||
int i;
|
int i;
|
||||||
int j;
|
|
||||||
|
|
||||||
memset(&info, 0x0, sizeof(info));
|
memset(&info, 0x0, sizeof(info));
|
||||||
memset(&status, 0x0, sizeof(status));
|
memset(&status, 0x0, sizeof(status));
|
||||||
|
|
||||||
for (i = 0; i < g_npidhash; i++)
|
|
||||||
{
|
|
||||||
if (g_pidhash[i] == NULL)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
tcb = g_pidhash[i];
|
|
||||||
|
|
||||||
/* Fill Process info */
|
/* Fill Process info */
|
||||||
|
|
||||||
nhdr.n_namesz = sizeof(name);
|
nhdr.n_namesz = sizeof(name);
|
||||||
@ -244,40 +260,205 @@ static void elf_emit_note_info(FAR struct elf_dumpinfo_s *cinfo)
|
|||||||
|
|
||||||
status.pr_pid = tcb->pid;
|
status.pr_pid = tcb->pid;
|
||||||
|
|
||||||
for (j = 0; j < nitems(status.pr_regs); j++)
|
if (running_task() == tcb)
|
||||||
{
|
{
|
||||||
if (tcb->xcp.regs == NULL)
|
if (up_interrupt_context())
|
||||||
{
|
{
|
||||||
continue;
|
regs = (FAR uint32_t *)CURRENT_REGS;
|
||||||
}
|
|
||||||
|
|
||||||
if (g_tcbinfo.reg_off.p[j] == UINT16_MAX)
|
|
||||||
{
|
|
||||||
status.pr_regs[j] = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
status.pr_regs[j] = *(uintptr_t *)((uint8_t *)tcb->xcp.regs +
|
up_saveusercontext(g_running_regs);
|
||||||
g_tcbinfo.reg_off.p[j]);
|
regs = (FAR uint32_t *)g_running_regs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
regs = tcb->xcp.regs;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regs != NULL)
|
||||||
|
{
|
||||||
|
for (i = 0; i < nitems(status.pr_regs); i++)
|
||||||
|
{
|
||||||
|
if (g_tcbinfo.reg_off.p[i] == UINT16_MAX)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status.pr_regs[i] =
|
||||||
|
*(uintptr_t *)((uint8_t *)regs + g_tcbinfo.reg_off.p[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
elf_emit(cinfo, &status, sizeof(status));
|
elf_emit(cinfo, &status, sizeof(status));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: elf_emit_note
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Fill the note segment information
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void elf_emit_note(FAR struct elf_dumpinfo_s *cinfo)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (cinfo->pid == INVALID_PROCESS_ID)
|
||||||
|
{
|
||||||
|
for (i = 0; i < g_npidhash; i++)
|
||||||
|
{
|
||||||
|
if (g_pidhash[i] != NULL)
|
||||||
|
{
|
||||||
|
elf_emit_tcb_note(cinfo, g_pidhash[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
elf_emit_tcb_note(cinfo, nxsched_get_tcb(cinfo->pid));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: elf_emit_program_header
|
* Name: elf_emit_tcb_stack
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Fill the task stack information from tcb
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void elf_emit_tcb_stack(FAR struct elf_dumpinfo_s *cinfo,
|
||||||
|
FAR struct tcb_s *tcb)
|
||||||
|
{
|
||||||
|
FAR void *buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (running_task() != tcb)
|
||||||
|
{
|
||||||
|
len = ((uintptr_t)tcb->stack_base_ptr + tcb->adj_stack_size) -
|
||||||
|
up_getusrsp(tcb->xcp.regs);
|
||||||
|
buf = (FAR void *)up_getusrsp(tcb->xcp.regs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf = (FAR void *)tcb->stack_alloc_ptr;
|
||||||
|
len = tcb->adj_stack_size +
|
||||||
|
(tcb->stack_base_ptr - tcb->stack_alloc_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
elf_emit(cinfo, buf, len);
|
||||||
|
|
||||||
|
/* Align to page */
|
||||||
|
|
||||||
|
elf_emit_align(cinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: elf_emit_stack
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Fill the task stack information
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void elf_emit_stack(FAR struct elf_dumpinfo_s *cinfo)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (cinfo->pid == INVALID_PROCESS_ID)
|
||||||
|
{
|
||||||
|
for (i = 0; i < g_npidhash; i++)
|
||||||
|
{
|
||||||
|
if (g_pidhash[i] != NULL)
|
||||||
|
{
|
||||||
|
elf_emit_tcb_stack(cinfo, g_pidhash[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
elf_emit_tcb_stack(cinfo, nxsched_get_tcb(cinfo->pid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: elf_emit_memory
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Fill the note segment information
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void elf_emit_memory(FAR struct elf_dumpinfo_s *cinfo, int memsegs)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < memsegs; i++)
|
||||||
|
{
|
||||||
|
elf_emit(cinfo, (FAR void *)cinfo->regions[i].start,
|
||||||
|
cinfo->regions[i].end -
|
||||||
|
cinfo->regions[i].start);
|
||||||
|
|
||||||
|
/* Align to page */
|
||||||
|
|
||||||
|
elf_emit_align(cinfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: elf_emit_tcb_phdr
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Fill the program segment header from tcb
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void elf_emit_tcb_phdr(FAR struct elf_dumpinfo_s *cinfo,
|
||||||
|
FAR struct tcb_s *tcb,
|
||||||
|
FAR Elf_Phdr *phdr, off_t *offset)
|
||||||
|
{
|
||||||
|
if (running_task() != tcb)
|
||||||
|
{
|
||||||
|
phdr->p_filesz = (uintptr_t)(tcb->stack_base_ptr +
|
||||||
|
tcb->adj_stack_size) - up_getusrsp(tcb->xcp.regs);
|
||||||
|
phdr->p_vaddr = up_getusrsp(tcb->xcp.regs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
phdr->p_vaddr = (uintptr_t)tcb->stack_alloc_ptr;
|
||||||
|
phdr->p_filesz = tcb->adj_stack_size +
|
||||||
|
(tcb->stack_base_ptr - tcb->stack_alloc_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
phdr->p_type = PT_LOAD;
|
||||||
|
phdr->p_offset = ROUNDUP(*offset, ELF_PAGESIZE);
|
||||||
|
phdr->p_paddr = phdr->p_vaddr;
|
||||||
|
phdr->p_memsz = phdr->p_filesz;
|
||||||
|
phdr->p_flags = PF_X | PF_W | PF_R;
|
||||||
|
phdr->p_align = ELF_PAGESIZE;
|
||||||
|
*offset += ROUNDUP(phdr->p_memsz, ELF_PAGESIZE);
|
||||||
|
|
||||||
|
elf_emit(cinfo, phdr, sizeof(*phdr));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: elf_emit_phdr
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Fill the program segment header
|
* Fill the program segment header
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void elf_emit_program_header(FAR struct elf_dumpinfo_s *cinfo,
|
static void elf_emit_phdr(FAR struct elf_dumpinfo_s *cinfo,
|
||||||
int segs)
|
int stksegs, int memsegs)
|
||||||
{
|
{
|
||||||
off_t offset = cinfo->stream->nput + (segs + 1) * sizeof(Elf_Phdr);
|
off_t offset = cinfo->stream->nput +
|
||||||
|
(stksegs + memsegs + 1) * sizeof(Elf_Phdr);
|
||||||
Elf_Phdr phdr;
|
Elf_Phdr phdr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -285,19 +466,35 @@ static void elf_emit_program_header(FAR struct elf_dumpinfo_s *cinfo,
|
|||||||
|
|
||||||
phdr.p_type = PT_NOTE;
|
phdr.p_type = PT_NOTE;
|
||||||
phdr.p_offset = offset;
|
phdr.p_offset = offset;
|
||||||
phdr.p_filesz = elf_get_note_size();
|
phdr.p_filesz = elf_get_note_size(stksegs);
|
||||||
offset += phdr.p_filesz;
|
offset += phdr.p_filesz;
|
||||||
|
|
||||||
elf_emit(cinfo, &phdr, sizeof(phdr));
|
elf_emit(cinfo, &phdr, sizeof(phdr));
|
||||||
|
|
||||||
|
if (cinfo->pid == INVALID_PROCESS_ID)
|
||||||
|
{
|
||||||
|
for (i = 0; i < g_npidhash; i++)
|
||||||
|
{
|
||||||
|
if (g_pidhash[i] != NULL)
|
||||||
|
{
|
||||||
|
elf_emit_tcb_phdr(cinfo, g_pidhash[i], &phdr, &offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
elf_emit_tcb_phdr(cinfo, nxsched_get_tcb(cinfo->pid),
|
||||||
|
&phdr, &offset);
|
||||||
|
}
|
||||||
|
|
||||||
/* Write program headers for segments dump */
|
/* Write program headers for segments dump */
|
||||||
|
|
||||||
for (i = 0; i < segs; i++)
|
for (i = 0; i < memsegs; i++)
|
||||||
{
|
{
|
||||||
phdr.p_type = PT_LOAD;
|
phdr.p_type = PT_LOAD;
|
||||||
phdr.p_offset = ROUNDUP(offset, ELF_PAGESIZE);
|
phdr.p_offset = ROUNDUP(offset, ELF_PAGESIZE);
|
||||||
phdr.p_vaddr = cinfo->regions[i].start;
|
phdr.p_vaddr = cinfo->regions[i].start;
|
||||||
phdr.p_paddr = cinfo->regions[i].start;
|
phdr.p_paddr = phdr.p_vaddr;
|
||||||
phdr.p_filesz = cinfo->regions[i].end - cinfo->regions[i].start;
|
phdr.p_filesz = cinfo->regions[i].end - cinfo->regions[i].start;
|
||||||
phdr.p_memsz = phdr.p_filesz;
|
phdr.p_memsz = phdr.p_filesz;
|
||||||
phdr.p_flags = cinfo->regions[i].flags;
|
phdr.p_flags = cinfo->regions[i].flags;
|
||||||
@ -327,54 +524,69 @@ static void elf_emit_program_header(FAR struct elf_dumpinfo_s *cinfo,
|
|||||||
|
|
||||||
int elf_coredump(FAR struct elf_dumpinfo_s *cinfo)
|
int elf_coredump(FAR struct elf_dumpinfo_s *cinfo)
|
||||||
{
|
{
|
||||||
int segs = 0;
|
irqstate_t flags;
|
||||||
int i;
|
int memsegs = 0;
|
||||||
|
int stksegs;
|
||||||
|
|
||||||
|
flags = enter_critical_section();
|
||||||
|
|
||||||
|
if (cinfo->pid != INVALID_PROCESS_ID)
|
||||||
|
{
|
||||||
|
if (nxsched_get_tcb(cinfo->pid) == NULL)
|
||||||
|
{
|
||||||
|
leave_critical_section(flags);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
stksegs = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stksegs = elf_get_ntcb();
|
||||||
|
}
|
||||||
|
|
||||||
/* Check the memory region */
|
/* Check the memory region */
|
||||||
|
|
||||||
if (cinfo->regions)
|
if (cinfo->regions != NULL)
|
||||||
{
|
{
|
||||||
for (; cinfo->regions[segs].start <
|
for (; cinfo->regions[memsegs].start <
|
||||||
cinfo->regions[segs].end; segs++);
|
cinfo->regions[memsegs].end; memsegs++);
|
||||||
}
|
|
||||||
|
|
||||||
if (segs == 0)
|
|
||||||
{
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill notes section */
|
/* Fill notes section */
|
||||||
|
|
||||||
elf_emit_header(cinfo, segs + 1);
|
elf_emit_hdr(cinfo, stksegs + memsegs + 1);
|
||||||
|
|
||||||
/* Fill all the program information about the process for the
|
/* Fill all the program information about the process for the
|
||||||
* notes. This also sets up the file header.
|
* notes. This also sets up the file header.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
elf_emit_program_header(cinfo, segs);
|
elf_emit_phdr(cinfo, stksegs, memsegs);
|
||||||
|
|
||||||
/* Fill note information */
|
/* Fill note information */
|
||||||
|
|
||||||
elf_emit_note_info(cinfo);
|
elf_emit_note(cinfo);
|
||||||
|
|
||||||
/* Align to page */
|
/* Align to page */
|
||||||
|
|
||||||
elf_emit_align(cinfo);
|
elf_emit_align(cinfo);
|
||||||
|
|
||||||
/* Start dump the memory */
|
/* Dump stack */
|
||||||
|
|
||||||
for (i = 0; i < segs; i++)
|
elf_emit_stack(cinfo);
|
||||||
|
|
||||||
|
/* Dump memory segments */
|
||||||
|
|
||||||
|
if (memsegs > 0)
|
||||||
{
|
{
|
||||||
elf_emit(cinfo, (FAR void *)cinfo->regions[i].start,
|
elf_emit_memory(cinfo, memsegs);
|
||||||
cinfo->regions[i].end -
|
|
||||||
cinfo->regions[i].start);
|
|
||||||
|
|
||||||
/* Align to page */
|
|
||||||
|
|
||||||
elf_emit_align(cinfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flush the dump */
|
/* Flush the dump */
|
||||||
|
|
||||||
return elf_flush(cinfo);
|
elf_flush(cinfo);
|
||||||
|
|
||||||
|
leave_critical_section(flags);
|
||||||
|
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,8 @@ struct binfmt_s
|
|||||||
/* Unload module callback */
|
/* Unload module callback */
|
||||||
|
|
||||||
CODE int (*coredump)(FAR struct memory_region_s *regions,
|
CODE int (*coredump)(FAR struct memory_region_s *regions,
|
||||||
FAR struct lib_outstream_s *stream);
|
FAR struct lib_outstream_s *stream,
|
||||||
|
pid_t pid);
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -209,7 +210,8 @@ int unregister_binfmt(FAR struct binfmt_s *binfmt);
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int core_dump(FAR struct memory_region_s *regions,
|
int core_dump(FAR struct memory_region_s *regions,
|
||||||
FAR struct lib_outstream_s *stream);
|
FAR struct lib_outstream_s *stream,
|
||||||
|
pid_t pid);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: load_module
|
* Name: load_module
|
||||||
|
@ -141,6 +141,7 @@ struct elf_dumpinfo_s
|
|||||||
{
|
{
|
||||||
FAR struct memory_region_s *regions;
|
FAR struct memory_region_s *regions;
|
||||||
FAR struct lib_outstream_s *stream;
|
FAR struct lib_outstream_s *stream;
|
||||||
|
pid_t pid;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user