diff --git a/arch/x86/kernel/gencore.c b/arch/x86/kernel/gencore.c new file mode 100644 index 00000000..a6321e72 --- /dev/null +++ b/arch/x86/kernel/gencore.c @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include +#include + +#define DEBUG_PRINT_GENCORE + +#ifdef DEBUG_PRINT_GENCORE +#define dkprintf(...) kprintf(__VA_ARGS__) +#define ekprintf(...) kprintf(__VA_ARGS__) +#else +#define dkprintf(...) +#define ekprintf(...) kprintf(__VA_ARGS__) +#endif + +/* + * Generate a core file image, which consists of many chunks. + * Returns an allocated table, an etnry of which is a pair of the address + * of a chunk and its length. + */ + +int gencore(struct process *proc, void *regs, + struct coretable **coretable, int *chunks) +{ + Elf64_Ehdr eh; + + { + struct vm_regions region = proc->vm->region; + + dkprintf("text: %x-%x\n", region.text_start, region.text_end); + dkprintf("data: %x-%x\n", region.data_start, region.data_end); + dkprintf("brk: %x-%x\n", region.brk_start, region.brk_end); + dkprintf("map: %x-%x\n", region.map_start, region.map_end); + dkprintf("stack: %x-%x\n", region.stack_start, region.stack_end); + dkprintf("user: %x-%x\n", region.user_start, region.user_end); + + } + + { + 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); + } + } + + + + + + /* ELF header */ + + eh.e_ident[EI_MAG0] = 0x7f; + eh.e_ident[EI_MAG1] = 'E'; + eh.e_ident[EI_MAG2] = 'L'; + eh.e_ident[EI_MAG3] = 'F'; + eh.e_ident[EI_CLASS] = ELFCLASS64; + eh.e_ident[EI_DATA] = ELFDATA2LSB; + eh.e_ident[EI_VERSION] = El_VERSION; + eh.e_ident[EI_OSABI] = ELFOSABI_NONE; + eh.e_ident[EI_ABIVERSION] = EI_ABIVERSION; + eh.e_type = ET_CORE; + eh.e_machine = EM_K10M; + eh.e_version = EV_CURRENT; + + dkprintf("now generate a core file image\n"); + + /* program header table */ + /* segments */ + + *coretable = kmalloc(sizeof(struct coretable) * 3, IHK_MC_AP_NOWAIT); + if (!*coretable) { + dkprintf("could not alloc a coretable.\n"); + return -1; + } + + (*coretable)[0].len = 8; + (*coretable)[0].addr = virt_to_phys("this is "); + (*coretable)[1].len = 7; + (*coretable)[1].addr = virt_to_phys("a test "); + (*coretable)[2].len = 15; + (*coretable)[2].addr = virt_to_phys("for coredump.\n"); + + dkprintf("generated a core table.\n"); + + *chunks = 3; + + return 0; +} diff --git a/arch/x86/kernel/include/elfcore.h b/arch/x86/kernel/include/elfcore.h new file mode 100644 index 00000000..d5b6fbf7 --- /dev/null +++ b/arch/x86/kernel/include/elfcore.h @@ -0,0 +1,85 @@ +/* + * Structures and definitions for ELF core file. + * Extracted from + * System V Application Binary Interface - DRAFT - 10 June 2013, + * http://www.sco.com/developers/gabi/latest/contents.html + */ + +typedef uint16_t Elf64_Half; +typedef uint32_t Elf64_Word; +typedef uint64_t Elf64_Xword; +typedef uint64_t Elf64_Addr; +typedef uint64_t Elf64_Off; + +#define EI_NIDENT 16 + +typedef struct { + unsigned char e_ident[EI_NIDENT]; + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; +} Elf64_Ehdr; + +#define EI_MAG0 0 +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define EI_OSABI 7 +#define EI_ABIVERSION 8 +#define EI_PAD 9 + + +#define ELFMAG0 0x7f +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' + +#define ELFCLASS64 2 /* 64-bit object */ +#define ELFDATA2LSB 1 /* LSB */ +#define El_VERSION 1 /* defined to be the same as EV CURRENT */ +#define ELFOSABI_NONE 0 /* unspecied */ +#define EI_ABIVERSION 0 /* unspecied */ /* xxx */ +#define ET_CORE 4 /* Core file */ +#define EM_K10M 181 /* Intel K10M */ +#define EV_CURRENT 1 /* Current version */ + +typedef struct { + Elf64_Word p_type; + Elf64_Word p_flags; + Elf64_Off p_offset; + Elf64_Addr p_vaddr; + Elf64_Addr p_paddr; + Elf64_Xword p_filesz; + Elf64_Xword p_memsz; + Elf64_Xword p_align; +} Elf64_Phdr; + +#define PT_LOAD 1 +#define PT_NOTE 4 + +#define PF_X 1 /* executable bit */ +#define PF_W 2 /* writable bit */ +#define PF_R 4 /* readable bit */ + +typedef struct note { + Elf64_Xword namesz; + Elf64_Xword descsz; + Elf64_Xword type; + char *contents; /* name char[namesz] and desc[descsz] */ +}; + +#include "elfcoregpl.h" + diff --git a/arch/x86/kernel/include/elfcoregpl.h b/arch/x86/kernel/include/elfcoregpl.h new file mode 100644 index 00000000..09207355 --- /dev/null +++ b/arch/x86/kernel/include/elfcoregpl.h @@ -0,0 +1,94 @@ +/* + * Structures and defines from GPLed file. + */ + +#define pid_t int + +/* From /usr/include/linux/elfcore.h of Linux */ + +#define ELF_PRARGSZ (80) + +/* From /usr/include/linux/elfcore.h fro Linux */ + +struct elf_siginfo +{ + int si_signo; + int si_code; + int si_errno; +}; + +/* From bfd/hosts/x86-64linux.h of gdb. */ + +typedef uint64_t __attribute__ ((__aligned__ (8))) a8_uint64_t; +typedef a8_uint64_t elf_greg64_t; + +struct user_regs64_struct +{ + a8_uint64_t r15; + a8_uint64_t r14; + a8_uint64_t r13; + a8_uint64_t r12; + a8_uint64_t rbp; + a8_uint64_t rbx; + a8_uint64_t r11; + a8_uint64_t r10; + a8_uint64_t r9; + a8_uint64_t r8; + a8_uint64_t rax; + a8_uint64_t rcx; + a8_uint64_t rdx; + a8_uint64_t rsi; + a8_uint64_t rdi; + a8_uint64_t orig_rax; + a8_uint64_t rip; + a8_uint64_t cs; + a8_uint64_t eflags; + a8_uint64_t rsp; + a8_uint64_t ss; + a8_uint64_t fs_base; + a8_uint64_t gs_base; + a8_uint64_t ds; + a8_uint64_t es; + a8_uint64_t fs; + a8_uint64_t gs; +}; + +#define ELF_NGREG64 (sizeof (struct user_regs64_struct) / sizeof(elf_greg64_t)) + +typedef elf_greg64_t elf_gregset64_t[ELF_NGREG64]; + +struct prstatus64_timeval +{ + a8_uint64_t tv_sec; + a8_uint64_t tv_usec; +}; +struct elf_prstatus64 +{ + struct elf_siginfo pr_info; + short int pr_cursig; + a8_uint64_t pr_sigpend; + a8_uint64_t pr_sighold; + pid_t pr_pid; + pid_t pr_ppid; + 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; + elf_gregset64_t pr_reg; + int pr_fpvalid; +}; +struct elf_prpsinfo64 +{ + char pr_state; + char pr_sname; + char pr_zomb; + char pr_nice; + a8_uint64_t pr_flag; + unsigned int pr_uid; + unsigned int pr_gid; + int pr_pid, pr_ppid, pr_pgrp, pr_sid; + char pr_fname[16]; + char pr_psargs[ELF_PRARGSZ]; +};