Prepare inside of core. Not tested.
modified: arch/x86/kernel/gencore.c modified: arch/x86/kernel/include/elfcore.h modified: kernel/mem.c
This commit is contained in:
@@ -24,38 +24,47 @@
|
|||||||
int gencore(struct process *proc, void *regs,
|
int gencore(struct process *proc, void *regs,
|
||||||
struct coretable **coretable, int *chunks)
|
struct coretable **coretable, int *chunks)
|
||||||
{
|
{
|
||||||
|
struct coretable *ct;
|
||||||
Elf64_Ehdr eh;
|
Elf64_Ehdr eh;
|
||||||
|
Elf64_Phdr *ph;
|
||||||
|
void *note;
|
||||||
|
struct vm_range *range;
|
||||||
|
struct process_vm *vm = proc->vm;
|
||||||
|
int segs = 1; /* the first one is for NOTES */
|
||||||
|
int notesize, phsize;
|
||||||
|
unsigned int offset = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (vm == NULL) {
|
||||||
|
dkprintf("no vm found.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_for_each_entry(range, &vm->vm_range_list, list) {
|
||||||
|
dkprintf("start:%x end:%x flag:%x objoff:%x\n",
|
||||||
|
range->start, range->end, range->flag, range->objoff);
|
||||||
|
if ((range->flag && VR_RESERVED) == 0)
|
||||||
|
segs++;
|
||||||
|
}
|
||||||
|
dkprintf("we have %d segs including one for NOTES.\n\n", segs);
|
||||||
|
|
||||||
{
|
{
|
||||||
struct vm_regions region = proc->vm->region;
|
struct vm_regions region = proc->vm->region;
|
||||||
|
|
||||||
dkprintf("text: %x-%x\n", region.text_start, region.text_end);
|
dkprintf("text: %x-%x\n", region.text_start, region.text_end);
|
||||||
dkprintf("data: %x-%x\n", region.data_start, region.data_end);
|
dkprintf("data: %x-%x\n", region.data_start, region.data_end);
|
||||||
dkprintf("brk: %x-%x\n", region.brk_start, region.brk_end);
|
dkprintf("brk: %x-%x\n", region.brk_start, region.brk_end);
|
||||||
dkprintf("map: %x-%x\n", region.map_start, region.map_end);
|
dkprintf("map: %x-%x\n", region.map_start, region.map_end);
|
||||||
dkprintf("stack: %x-%x\n", region.stack_start, region.stack_end);
|
dkprintf("stack: %x-%x\n", region.stack_start, region.stack_end);
|
||||||
dkprintf("user: %x-%x\n", region.user_start, region.user_end);
|
dkprintf("user: %x-%x\n\n", region.user_start, region.user_end);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
dkprintf("now generate a core file image\n");
|
||||||
struct vm_range *range;
|
|
||||||
struct process_vm *vm = proc->vm;
|
|
||||||
|
|
||||||
if (vm == NULL) {
|
|
||||||
dkprintf("no vm found.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
list_for_each_entry(range, &vm->vm_range_list, list) {
|
|
||||||
dkprintf("start:%x end:%x flag:%x objoff:%x\n",
|
|
||||||
range->start, range->end, range->flag, range->objoff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define DUMMY
|
||||||
|
|
||||||
|
#ifdef DUMMY
|
||||||
|
|
||||||
/* ELF header */
|
/* ELF header */
|
||||||
|
|
||||||
@@ -67,32 +76,137 @@ int gencore(struct process *proc, void *regs,
|
|||||||
eh.e_ident[EI_DATA] = ELFDATA2LSB;
|
eh.e_ident[EI_DATA] = ELFDATA2LSB;
|
||||||
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] = EI_ABIVERSION;
|
eh.e_ident[EI_ABIVERSION] = El_ABIVERSION_NONE;
|
||||||
eh.e_type = ET_CORE;
|
eh.e_type = ET_CORE;
|
||||||
eh.e_machine = EM_K10M;
|
eh.e_machine = EM_K10M;
|
||||||
eh.e_version = EV_CURRENT;
|
eh.e_version = EV_CURRENT;
|
||||||
|
eh.e_entry = 0; /* Do we really need this? */
|
||||||
|
eh.e_phoff = 64; /* fixed */
|
||||||
|
eh.e_shoff = 0; /* no section header */
|
||||||
|
eh.e_flags = 0;
|
||||||
|
eh.e_ehsize = 64; /* fixed */
|
||||||
|
eh.e_phentsize = 56; /* fixed */
|
||||||
|
eh.e_phnum = segs;
|
||||||
|
eh.e_shentsize = 0;
|
||||||
|
eh.e_shnum = 0;
|
||||||
|
eh.e_shstrndx = 0;
|
||||||
|
|
||||||
dkprintf("now generate a core file image\n");
|
offset += 64;
|
||||||
|
|
||||||
|
notesize = 1024; /* dummy */
|
||||||
|
|
||||||
/* program header table */
|
/* program header table */
|
||||||
/* segments */
|
|
||||||
|
|
||||||
|
phsize = sizeof(Elf64_Phdr) * segs;
|
||||||
|
ph = kmalloc(phsize, IHK_MC_AP_NOWAIT);
|
||||||
|
if (ph == NULL) {
|
||||||
|
dkprintf("could not alloc a program header table.\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += phsize;
|
||||||
|
|
||||||
|
/* prgram header for NOTE segment is exceptional */
|
||||||
|
|
||||||
|
ph[0].p_type = PT_NOTE;
|
||||||
|
ph[0].p_flags = 0;
|
||||||
|
ph[0].p_offset = offset;
|
||||||
|
ph[0].p_vaddr = 0;
|
||||||
|
ph[0].p_paddr = 0;
|
||||||
|
ph[0].p_filesz = 0;
|
||||||
|
ph[0].p_memsz = notesize;
|
||||||
|
ph[0].p_align = 1024;
|
||||||
|
|
||||||
|
/* program header for each memory chunk */
|
||||||
|
i = 1;
|
||||||
|
list_for_each_entry(range, &vm->vm_range_list, list) {
|
||||||
|
unsigned long flag = range->flag;
|
||||||
|
unsigned long size = range->end - range->start;
|
||||||
|
|
||||||
|
ph[i].p_type = PT_LOAD;
|
||||||
|
/* xxx */
|
||||||
|
ph[i].p_flags = ((flag & VR_PROT_READ) ? PF_R : 0)
|
||||||
|
| ((flag & VR_PROT_WRITE) ? PF_W : 0)
|
||||||
|
| ((flag & VR_PROT_EXEC) ? PF_X : 0);
|
||||||
|
ph[i].p_offset = offset;
|
||||||
|
ph[i].p_vaddr = range->start;
|
||||||
|
ph[i].p_paddr = 0;
|
||||||
|
ph[i].p_filesz = 0; /* How can we know this? */
|
||||||
|
ph[i].p_memsz = size;
|
||||||
|
ph[i].p_align = 1024; /* ??? */
|
||||||
|
i++;
|
||||||
|
offset += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* note */
|
||||||
|
|
||||||
|
note = kmalloc(notesize, IHK_MC_AP_NOWAIT);
|
||||||
|
if (note == NULL) {
|
||||||
|
dkprintf("could not alloc note.\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* coretable to send to host */
|
||||||
|
ct = kmalloc(sizeof(struct coretable) * (segs + 2), IHK_MC_AP_NOWAIT);
|
||||||
|
if (!ct) {
|
||||||
|
dkprintf("could not alloc a coretable.\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ct[0].addr = virt_to_phys(&eh); /* ELF header */
|
||||||
|
ct[0].len = 64;
|
||||||
|
|
||||||
|
ct[1].addr = virt_to_phys(ph); /* program header table */
|
||||||
|
ct[1].len = phsize;
|
||||||
|
|
||||||
|
ct[2].addr = virt_to_phys(note); /* NOTE segment */
|
||||||
|
ct[2].len = notesize;
|
||||||
|
|
||||||
|
i = 3; /* memory segments */
|
||||||
|
list_for_each_entry(range, &vm->vm_range_list, list) {
|
||||||
|
ct[i].addr = virt_to_phys(range->start);
|
||||||
|
ct[i].len = range->end - range->start;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
*chunks = segs + 2;
|
||||||
|
|
||||||
|
#else /* dummy */
|
||||||
*coretable = kmalloc(sizeof(struct coretable) * 3, IHK_MC_AP_NOWAIT);
|
*coretable = kmalloc(sizeof(struct coretable) * 3, IHK_MC_AP_NOWAIT);
|
||||||
if (!*coretable) {
|
if (!*coretable) {
|
||||||
dkprintf("could not alloc a coretable.\n");
|
dkprintf("could not alloc a coretable.\n");
|
||||||
return -1;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*coretable)[0].len = 8;
|
ct[0].len = 8;
|
||||||
(*coretable)[0].addr = virt_to_phys("this is ");
|
ct[0].addr = virt_to_phys("this is ");
|
||||||
(*coretable)[1].len = 7;
|
ct[1].len = 7;
|
||||||
(*coretable)[1].addr = virt_to_phys("a test ");
|
ct[1].addr = virt_to_phys("a test ");
|
||||||
(*coretable)[2].len = 15;
|
ct[2].len = 15;
|
||||||
(*coretable)[2].addr = virt_to_phys("for coredump.\n");
|
ct[2].addr = virt_to_phys("for coredump.\n");
|
||||||
|
|
||||||
dkprintf("generated a core table.\n");
|
dkprintf("generated a core table.\n");
|
||||||
|
|
||||||
*chunks = 3;
|
*chunks = 3;
|
||||||
|
#endif
|
||||||
|
*coretable = ct;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (ct)
|
||||||
|
kfree(ct);
|
||||||
|
if (ph)
|
||||||
|
kfree(ph);
|
||||||
|
if (note)
|
||||||
|
kfree(note);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free all the allocated spaces. */
|
||||||
|
|
||||||
|
void freecore(struct coretable **coretable)
|
||||||
|
{
|
||||||
|
struct coretable *ct = *coretable;
|
||||||
|
kfree(phys_to_virt(ct[2].addr)); /* NOTE segment */
|
||||||
|
kfree(phys_to_virt(ct[1].addr)); /* ph */
|
||||||
|
kfree(*coretable);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ typedef struct {
|
|||||||
#define ELFDATA2LSB 1 /* LSB */
|
#define ELFDATA2LSB 1 /* LSB */
|
||||||
#define El_VERSION 1 /* defined to be the same as EV CURRENT */
|
#define El_VERSION 1 /* defined to be the same as EV CURRENT */
|
||||||
#define ELFOSABI_NONE 0 /* unspecied */
|
#define ELFOSABI_NONE 0 /* unspecied */
|
||||||
#define EI_ABIVERSION 0 /* unspecied */ /* xxx */
|
#define El_ABIVERSION_NONE 0 /* unspecied */
|
||||||
#define ET_CORE 4 /* Core file */
|
#define ET_CORE 4 /* Core file */
|
||||||
#define EM_K10M 181 /* Intel K10M */
|
#define EM_K10M 181 /* Intel K10M */
|
||||||
#define EV_CURRENT 1 /* Current version */
|
#define EV_CURRENT 1 /* Current version */
|
||||||
@@ -79,7 +79,7 @@ typedef struct note {
|
|||||||
Elf64_Xword descsz;
|
Elf64_Xword descsz;
|
||||||
Elf64_Xword type;
|
Elf64_Xword type;
|
||||||
char *contents; /* name char[namesz] and desc[descsz] */
|
char *contents; /* name char[namesz] and desc[descsz] */
|
||||||
};
|
} Elf64_Nhdr;
|
||||||
|
|
||||||
#include "elfcoregpl.h"
|
#include "elfcoregpl.h"
|
||||||
|
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ static struct ihk_mc_interrupt_handler query_free_mem_handler = {
|
|||||||
void set_signal(int sig, void *regs);
|
void set_signal(int sig, void *regs);
|
||||||
void check_signal(unsigned long rc, void *regs);
|
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 **);
|
||||||
|
|
||||||
static void coredump(struct process *proc, void *regs)
|
static void coredump(struct process *proc, void *regs)
|
||||||
{
|
{
|
||||||
@@ -192,7 +193,7 @@ static void coredump(struct process *proc, void *regs)
|
|||||||
} else {
|
} else {
|
||||||
kprintf("core dump failed.\n");
|
kprintf("core dump failed.\n");
|
||||||
}
|
}
|
||||||
kfree(coretable);
|
freecore(&coretable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unhandled_page_fault(struct process *proc, void *fault_addr, void *regs)
|
static void unhandled_page_fault(struct process *proc, void *fault_addr, void *regs)
|
||||||
|
|||||||
Reference in New Issue
Block a user