Fix for demand paging and documentation.
This commit is contained in:
@@ -24,7 +24,12 @@
|
|||||||
* of a chunk and its length.
|
* of a chunk and its length.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ELF header */
|
/**
|
||||||
|
* \brief Fill the elf header.
|
||||||
|
*
|
||||||
|
* \param eh An Elf64_Ehdr structure.
|
||||||
|
* \param segs Number of segments of the core file.
|
||||||
|
*/
|
||||||
|
|
||||||
void fill_elf_header(Elf64_Ehdr *eh, int segs)
|
void fill_elf_header(Elf64_Ehdr *eh, int segs)
|
||||||
{
|
{
|
||||||
@@ -37,6 +42,8 @@ void fill_elf_header(Elf64_Ehdr *eh, int segs)
|
|||||||
eh->e_ident[EI_VERSION] = El_VERSION;
|
eh->e_ident[EI_VERSION] = El_VERSION;
|
||||||
eh->e_ident[EI_OSABI] = ELFOSABI_NONE;
|
eh->e_ident[EI_OSABI] = ELFOSABI_NONE;
|
||||||
eh->e_ident[EI_ABIVERSION] = El_ABIVERSION_NONE;
|
eh->e_ident[EI_ABIVERSION] = El_ABIVERSION_NONE;
|
||||||
|
memset((void *)eh + EI_PAD, 0, sizeof(*eh) - EI_PAD);
|
||||||
|
|
||||||
eh->e_type = ET_CORE;
|
eh->e_type = ET_CORE;
|
||||||
#ifdef CONFIG_MIC
|
#ifdef CONFIG_MIC
|
||||||
eh->e_machine = EM_K10M;
|
eh->e_machine = EM_K10M;
|
||||||
@@ -56,7 +63,10 @@ void fill_elf_header(Elf64_Ehdr *eh, int segs)
|
|||||||
eh->e_shstrndx = 0;
|
eh->e_shstrndx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prstatus NOTE */
|
/**
|
||||||
|
* \brief Return the size of the prstatus entry of the NOTE segment.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
int get_prstatus_size(void)
|
int get_prstatus_size(void)
|
||||||
{
|
{
|
||||||
@@ -64,6 +74,14 @@ int get_prstatus_size(void)
|
|||||||
+ align32(sizeof(struct elf_prstatus64));
|
+ align32(sizeof(struct elf_prstatus64));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Fill a prstatus structure.
|
||||||
|
*
|
||||||
|
* \param head A pointer to a note structure.
|
||||||
|
* \param proc A pointer to the current process structure.
|
||||||
|
* \param regs0 A pointer to a x86_regs structure.
|
||||||
|
*/
|
||||||
|
|
||||||
void fill_prstatus(struct note *head, struct process *proc, void *regs0)
|
void fill_prstatus(struct note *head, struct process *proc, void *regs0)
|
||||||
{
|
{
|
||||||
void *name;
|
void *name;
|
||||||
@@ -80,6 +98,7 @@ void fill_prstatus(struct note *head, struct process *proc, void *regs0)
|
|||||||
name = (void *) (head + 1);
|
name = (void *) (head + 1);
|
||||||
memcpy(name, "CORE", sizeof("CORE"));
|
memcpy(name, "CORE", sizeof("CORE"));
|
||||||
prstatus = (struct elf_prstatus64 *)(name + align32(sizeof("CORE")));
|
prstatus = (struct elf_prstatus64 *)(name + align32(sizeof("CORE")));
|
||||||
|
memset(prstatus, 0, sizeof(struct elf_prstatus64));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We ignore following entries for now.
|
We ignore following entries for now.
|
||||||
@@ -126,7 +145,10 @@ void fill_prstatus(struct note *head, struct process *proc, void *regs0)
|
|||||||
prstatus->pr_fpvalid = 0; /* We assume no fp */
|
prstatus->pr_fpvalid = 0; /* We assume no fp */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prpsinfo NOTE */
|
/**
|
||||||
|
* \brief Return the size of the prpsinfo entry of the NOTE segment.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
int get_prpsinfo_size(void)
|
int get_prpsinfo_size(void)
|
||||||
{
|
{
|
||||||
@@ -134,6 +156,14 @@ int get_prpsinfo_size(void)
|
|||||||
+ align32(sizeof(struct elf_prpsinfo64));
|
+ align32(sizeof(struct elf_prpsinfo64));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Fill a prpsinfo structure.
|
||||||
|
*
|
||||||
|
* \param head A pointer to a note structure.
|
||||||
|
* \param proc A pointer to the current process structure.
|
||||||
|
* \param regs A pointer to a x86_regs structure.
|
||||||
|
*/
|
||||||
|
|
||||||
void fill_prpsinfo(struct note *head, struct process *proc, void *regs)
|
void fill_prpsinfo(struct note *head, struct process *proc, void *regs)
|
||||||
{
|
{
|
||||||
void *name;
|
void *name;
|
||||||
@@ -145,6 +175,7 @@ void fill_prpsinfo(struct note *head, struct process *proc, void *regs)
|
|||||||
name = (void *) (head + 1);
|
name = (void *) (head + 1);
|
||||||
memcpy(name, "CORE", sizeof("CORE"));
|
memcpy(name, "CORE", sizeof("CORE"));
|
||||||
prpsinfo = (struct elf_prpsinfo64 *)(name + align32(sizeof("CORE")));
|
prpsinfo = (struct elf_prpsinfo64 *)(name + align32(sizeof("CORE")));
|
||||||
|
memset(prpsinfo, 0, sizeof(struct elf_prpsinfo64));
|
||||||
|
|
||||||
prpsinfo->pr_state = proc->status;
|
prpsinfo->pr_state = proc->status;
|
||||||
prpsinfo->pr_pid = proc->pid;
|
prpsinfo->pr_pid = proc->pid;
|
||||||
@@ -165,7 +196,10 @@ void fill_prpsinfo(struct note *head, struct process *proc, void *regs)
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/* auxv NOTE */
|
/**
|
||||||
|
* \brief Return the size of the AUXV entry of the NOTE segment.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
int get_auxv_size(void)
|
int get_auxv_size(void)
|
||||||
{
|
{
|
||||||
@@ -173,6 +207,14 @@ int get_auxv_size(void)
|
|||||||
+ sizeof(unsigned long) * AUXV_LEN;
|
+ sizeof(unsigned long) * AUXV_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Fill an AUXV structure.
|
||||||
|
*
|
||||||
|
* \param head A pointer to a note structure.
|
||||||
|
* \param proc A pointer to the current process structure.
|
||||||
|
* \param regs A pointer to a x86_regs structure.
|
||||||
|
*/
|
||||||
|
|
||||||
void fill_auxv(struct note *head, struct process *proc, void *regs)
|
void fill_auxv(struct note *head, struct process *proc, void *regs)
|
||||||
{
|
{
|
||||||
void *name;
|
void *name;
|
||||||
@@ -187,7 +229,10 @@ void fill_auxv(struct note *head, struct process *proc, void *regs)
|
|||||||
memcpy(auxv, proc->saved_auxv, sizeof(unsigned long) * AUXV_LEN);
|
memcpy(auxv, proc->saved_auxv, sizeof(unsigned long) * AUXV_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* whole NOTE segment */
|
/**
|
||||||
|
* \brief Return the size of the whole NOTE segment.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
int get_note_size(void)
|
int get_note_size(void)
|
||||||
{
|
{
|
||||||
@@ -195,6 +240,14 @@ int get_note_size(void)
|
|||||||
+ get_auxv_size();
|
+ get_auxv_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Fill the NOTE segment.
|
||||||
|
*
|
||||||
|
* \param head A pointer to a note structure.
|
||||||
|
* \param proc A pointer to the current process structure.
|
||||||
|
* \param regs A pointer to a x86_regs structure.
|
||||||
|
*/
|
||||||
|
|
||||||
void fill_note(void *note, struct process *proc, void *regs)
|
void fill_note(void *note, struct process *proc, void *regs)
|
||||||
{
|
{
|
||||||
fill_prstatus(note, proc, regs);
|
fill_prstatus(note, proc, regs);
|
||||||
@@ -204,7 +257,20 @@ void fill_note(void *note, struct process *proc, void *regs)
|
|||||||
fill_auxv(note, proc, regs);
|
fill_auxv(note, proc, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* whole core image */
|
/**
|
||||||
|
* \brief Generate an image of the core file.
|
||||||
|
*
|
||||||
|
* \param proc A pointer to the current process structure.
|
||||||
|
* \param regs A pointer to a x86_regs structure.
|
||||||
|
* \param coretable(out) An array of core chunks.
|
||||||
|
* \param chunks(out) Number of the entires of coretable.
|
||||||
|
*
|
||||||
|
* A core chunk is represented by a pair of a physical
|
||||||
|
* address of memory region and its size. If there are
|
||||||
|
* no corresponding physical address for a VM area
|
||||||
|
* (an unallocated demand-paging page, e.g.), the address
|
||||||
|
* should be zero.
|
||||||
|
*/
|
||||||
|
|
||||||
int gencore(struct process *proc, void *regs,
|
int gencore(struct process *proc, void *regs,
|
||||||
struct coretable **coretable, int *chunks)
|
struct coretable **coretable, int *chunks)
|
||||||
@@ -430,7 +496,11 @@ int gencore(struct process *proc, void *regs,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free all the allocated spaces. */
|
/**
|
||||||
|
* \brief Free all the allocated spaces for an image of the core file.
|
||||||
|
*
|
||||||
|
* \param coretable An array of core chunks.
|
||||||
|
*/
|
||||||
|
|
||||||
void freecore(struct coretable **coretable)
|
void freecore(struct coretable **coretable)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1215,6 +1215,11 @@ static int writecore(ihk_os_t os, unsigned long rcoretable, int chunks) {
|
|||||||
/* unmap the chunk */
|
/* unmap the chunk */
|
||||||
ihk_device_unmap_virtual(dev, pt, size);
|
ihk_device_unmap_virtual(dev, pt, size);
|
||||||
ihk_device_unmap_memory(dev, phys, size);
|
ihk_device_unmap_memory(dev, phys, size);
|
||||||
|
if (ret != size) {
|
||||||
|
dprintk("core file write failed(%d).\n", ret);
|
||||||
|
error = PTR_ERR(file);
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* We skip if the physical address is NULL
|
/* We skip if the physical address is NULL
|
||||||
and make the core file sparse. */
|
and make the core file sparse. */
|
||||||
@@ -1229,11 +1234,6 @@ static int writecore(ihk_os_t os, unsigned long rcoretable, int chunks) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret != size) {
|
|
||||||
dprintk("core file write failed(%d).\n", ret);
|
|
||||||
error = PTR_ERR(file);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* unmap the chunk table */
|
/* unmap the chunk table */
|
||||||
ihk_device_unmap_virtual(dev, coretable, tablesize);
|
ihk_device_unmap_virtual(dev, coretable, tablesize);
|
||||||
|
|||||||
@@ -169,9 +169,15 @@ void check_signal(unsigned long rc, void *regs);
|
|||||||
int gencore(struct process *, void *, struct coretable **, int *);
|
int gencore(struct process *, void *, struct coretable **, int *);
|
||||||
void freecore(struct coretable **);
|
void freecore(struct coretable **);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Generate a core file and tell the host to write it out.
|
||||||
|
*
|
||||||
|
* \param proc A current process structure.
|
||||||
|
* \param regs A pointer to a x86_regs structure.
|
||||||
|
*/
|
||||||
|
|
||||||
static void coredump(struct process *proc, void *regs)
|
static void coredump(struct process *proc, void *regs)
|
||||||
{
|
{
|
||||||
/* xxx */
|
|
||||||
struct syscall_request request IHK_DMA_ALIGN;
|
struct syscall_request request IHK_DMA_ALIGN;
|
||||||
int ret;
|
int ret;
|
||||||
struct coretable *coretable;
|
struct coretable *coretable;
|
||||||
|
|||||||
Reference in New Issue
Block a user