diff --git a/arch/x86/kernel/gencore.c b/arch/x86/kernel/gencore.c index b474fb11..f7975c65 100644 --- a/arch/x86/kernel/gencore.c +++ b/arch/x86/kernel/gencore.c @@ -24,7 +24,12 @@ * 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) { @@ -37,6 +42,8 @@ void fill_elf_header(Elf64_Ehdr *eh, int segs) eh->e_ident[EI_VERSION] = El_VERSION; eh->e_ident[EI_OSABI] = ELFOSABI_NONE; eh->e_ident[EI_ABIVERSION] = El_ABIVERSION_NONE; + memset((void *)eh + EI_PAD, 0, sizeof(*eh) - EI_PAD); + eh->e_type = ET_CORE; #ifdef CONFIG_MIC eh->e_machine = EM_K10M; @@ -56,7 +63,10 @@ void fill_elf_header(Elf64_Ehdr *eh, int segs) eh->e_shstrndx = 0; } -/* prstatus NOTE */ +/** + * \brief Return the size of the prstatus entry of the NOTE segment. + * + */ int get_prstatus_size(void) { @@ -64,6 +74,14 @@ int get_prstatus_size(void) + 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 *name; @@ -80,6 +98,7 @@ void fill_prstatus(struct note *head, struct process *proc, void *regs0) name = (void *) (head + 1); memcpy(name, "CORE", sizeof("CORE")); prstatus = (struct elf_prstatus64 *)(name + align32(sizeof("CORE"))); + memset(prstatus, 0, sizeof(struct elf_prstatus64)); /* 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 */ } -/* prpsinfo NOTE */ +/** + * \brief Return the size of the prpsinfo entry of the NOTE segment. + * + */ int get_prpsinfo_size(void) { @@ -134,6 +156,14 @@ int get_prpsinfo_size(void) + 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 *name; @@ -145,6 +175,7 @@ void fill_prpsinfo(struct note *head, struct process *proc, void *regs) name = (void *) (head + 1); memcpy(name, "CORE", sizeof("CORE")); prpsinfo = (struct elf_prpsinfo64 *)(name + align32(sizeof("CORE"))); + memset(prpsinfo, 0, sizeof(struct elf_prpsinfo64)); prpsinfo->pr_state = proc->status; 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) { @@ -173,6 +207,14 @@ int get_auxv_size(void) + 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 *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); } -/* whole NOTE segment */ +/** + * \brief Return the size of the whole NOTE segment. + * + */ int get_note_size(void) { @@ -195,6 +240,14 @@ int get_note_size(void) + 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) { fill_prstatus(note, proc, regs); @@ -204,7 +257,20 @@ void fill_note(void *note, struct process *proc, void *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, struct coretable **coretable, int *chunks) @@ -430,7 +496,11 @@ int gencore(struct process *proc, void *regs, 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) { diff --git a/executer/kernel/syscall.c b/executer/kernel/syscall.c index 6b33326d..3e77e6c8 100644 --- a/executer/kernel/syscall.c +++ b/executer/kernel/syscall.c @@ -1215,6 +1215,11 @@ static int writecore(ihk_os_t os, unsigned long rcoretable, int chunks) { /* unmap the chunk */ ihk_device_unmap_virtual(dev, pt, 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 { /* We skip if the physical address is NULL and make the core file sparse. */ @@ -1229,11 +1234,6 @@ static int writecore(ihk_os_t os, unsigned long rcoretable, int chunks) { break; } } - if (ret != size) { - dprintk("core file write failed(%d).\n", ret); - error = PTR_ERR(file); - break; - } } /* unmap the chunk table */ ihk_device_unmap_virtual(dev, coretable, tablesize); diff --git a/kernel/mem.c b/kernel/mem.c index bd85b9e2..8fe6b0d8 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -169,9 +169,15 @@ void check_signal(unsigned long rc, void *regs); int gencore(struct process *, void *, struct coretable **, int *); 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) { - /* xxx */ struct syscall_request request IHK_DMA_ALIGN; int ret; struct coretable *coretable;