From 53dc39f8271c2a0489a4a7de689b7c4f59f2dfdf Mon Sep 17 00:00:00 2001 From: Zhou Wenjian Date: Tue, 16 Dec 2014 09:37:29 +0800 Subject: [PATCH] Make note info human readable when help -D --- defs.h | 7 ++ diskdump.c | 7 ++ netdump.c | 312 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 326 insertions(+), 0 deletions(-) diff --git a/defs.h b/defs.h index 2e52bc4..76b113a 100755 --- a/defs.h +++ b/defs.h @@ -5547,6 +5547,13 @@ int write_proc_kcore(int, void *, int, ulong, physaddr_t); int kcore_memory_dump(FILE *); void dump_registers_for_qemu_mem_dump(void); void kdump_backup_region_init(void); +void display_ELF_note(int, int, void *, char *); + +/* + * for display_ELF_note() type + */ +#define PRSTATUS 0x1 +#define QEMU 0X2 /* * ramdump.c diff --git a/diskdump.c b/diskdump.c index 3d33fdc..b6fbfd9 100644 --- a/diskdump.c +++ b/diskdump.c @@ -1736,9 +1736,16 @@ __diskdump_memory_dump(FILE *fp) dd->num_prstatus_notes); fprintf(fp, " notes_buf: %lx\n", (ulong)dd->notes_buf); + + char l_buf[BUFSIZE * 2]; + BZERO(l_buf, BUFSIZE *2); for (i = 0; i < dd->num_prstatus_notes; i++) { fprintf(fp, " notes[%d]: %lx\n", i, (ulong)dd->nt_prstatus_percpu[i]); + + display_ELF_note(dd->machine_type, PRSTATUS, + dd->nt_prstatus_percpu[i],l_buf); + fprintf(fp, "%s", l_buf); } dump_nt_prstatus_offset(fp); } diff --git a/netdump.c b/netdump.c index 903faa0..02f1bba 100644 --- a/netdump.c +++ b/netdump.c @@ -1976,6 +1976,12 @@ dump_Elf32_Nhdr(Elf32_Off offset, int store) } lf = 0; } else { + if (nd->ofp) { + char l_buf[BUFSIZE * 2]; + BZERO(l_buf, BUFSIZE *2); + display_ELF_note(EM_386, qemuinfo ? QEMU : PRSTATUS, note,l_buf); + fprintf(fp, "%s", l_buf); + } for (i = lf = 0; i < note->n_descsz/sizeof(ulong); i++) { if (((i%4)==0)) { netdump_print("%s ", @@ -2255,6 +2261,13 @@ dump_Elf64_Nhdr(Elf64_Off offset, int store) } if (BITS32() && (xen_core || (note->n_type == NT_PRSTATUS))) { + if (!xen_core && nd->ofp) { + char l_buf[BUFSIZE * 2]; + BZERO(l_buf, BUFSIZE *2); + display_ELF_note(EM_386, PRSTATUS, note, l_buf); + fprintf(fp, "%s", l_buf); + } + iptr = (int *)uptr; for (i = lf = 0; i < note->n_descsz/sizeof(ulong); i++) { if (((i%4)==0)) { @@ -2279,6 +2292,12 @@ dump_Elf64_Nhdr(Elf64_Off offset, int store) iptr = (int *)uptr; netdump_print(" %08lx\n", *iptr); } else { + if (nd->ofp) { + char l_buf[BUFSIZE * 2]; + BZERO(l_buf, BUFSIZE *2); + display_ELF_note(EM_X86_64, qemuinfo ? QEMU : PRSTATUS, note, l_buf); + fprintf(fp, "%s", l_buf); + } for (i = lf = 0; i < note->n_descsz/sizeof(ulonglong); i++) { if (((i%2)==0)) { netdump_print("%s ", @@ -2543,6 +2562,299 @@ struct x86_64_user_regs_struct { unsigned long ds,es,fs,gs; }; +struct x86_64_prstatus { + int si_signo; + int si_code; + int si_errno; + short cursig; + unsigned long sigpend; + unsigned long sighold; + int pid; + int ppid; + int pgrp; + int sid; + struct timeval utime; + struct timeval stime; + struct timeval cutime; + struct timeval cstime; + struct x86_64_user_regs_struct regs; + int fpvalid; +}; + +static void +display_prstatus_x86_64(void *note_ptr, char *buf) +{ + struct x86_64_prstatus *pr; + Elf64_Nhdr *note; + + note = (Elf64_Nhdr *)note_ptr; + pr = (struct x86_64_prstatus *)( + (char *)note + sizeof(Elf64_Nhdr) + note->n_namesz); + pr = (struct x86_64_prstatus *)roundup((ulong)pr, 4); + sprintf(buf, + " si.signo: %d, si.code: %d, si.errno: %d, cursig:%d\n" + " sigpend: %lu\n" + " sighold: %lu\n" + " pid: %d, ppid: %d, pgrp: %d, sid:%d\n" + " utime: %01lld.%06d, stime: %01lld.%06d, cutime: %01lld.%06d, " + "cstime: %01lld.%06d\n" + " ORIG_RAX: %ld, fpvalid: %d\n" + " R15 : 0x%016lx R14 : 0x%016lx\n" + " R13 : 0x%016lx R12 : 0x%016lx\n" + " RBP : 0x%016lx RBX : 0x%016lx\n" + " R11 : 0x%016lx R10 : 0x%016lx\n" + " R9 : 0x%016lx R8 : 0x%016lx\n" + " RAX : 0x%016lx RCX : 0x%016lx\n" + " RDX : 0x%016lx RSI : 0x%016lx\n" + " RDI : 0x%016lx RIP : 0x%016lx\n" + " RFLAGS : 0x%016lx RSP : 0x%016lx\n" + " FS_BASE: 0x%016lx GS_BASE : 0x%016lx\n" + " CS: 0x%04lx SS: 0x%04lx DS: 0x%04lx ES: 0x%04lx " + "FS: 0x%04lx GS: 0x%04lx\n", + pr->si_signo, pr->si_code, pr->si_errno, pr->cursig, + pr->sigpend, pr->sighold, + pr->pid, pr->ppid, pr->pgrp, pr->sid, + (long long)pr->utime.tv_sec, (int)pr->utime.tv_usec, + (long long)pr->stime.tv_sec, (int)pr->stime.tv_usec, + (long long)pr->cutime.tv_sec, (int)pr->cutime.tv_usec, + (long long)pr->cstime.tv_sec, (int)pr->cstime.tv_usec, + pr->regs.orig_rax, pr->fpvalid, + pr->regs.r15, pr->regs.r14, + pr->regs.r13, pr->regs.r12, + pr->regs.rbp, pr->regs.rbx, + pr->regs.r11, pr->regs.r10, + pr->regs.r9, pr->regs.r8, + pr->regs.rax, pr->regs.rcx, + pr->regs.rdx, pr->regs.rsi, + pr->regs.rdi, pr->regs.rip, + pr->regs.eflags, pr->regs.rsp, + pr->regs.fs_base, pr->regs.gs_base, + pr->regs.cs, pr->regs.ss, + pr->regs.ds, pr->regs.es, + pr->regs.fs, pr->regs.gs + ); +} + +struct x86_user_regs_struct { + unsigned long ebx,ecx,edx,esi,edi,ebp,eax; + unsigned long ds,es,fs,gs,orig_eax; + unsigned long eip,cs,eflags; + unsigned long esp,ss; +}; + +struct x86_prstatus { + int si_signo; + int si_code; + int si_errno; + short cursig; + unsigned long sigpend; + unsigned long sighold; + int pid; + int ppid; + int pgrp; + int sid; + struct timeval utime; + struct timeval stime; + struct timeval cutime; + struct timeval cstime; + struct x86_user_regs_struct regs; + int fpvalid; +}; + +static void +display_prstatus_x86(void *note_ptr, char *buf) +{ + struct x86_prstatus *pr; + Elf32_Nhdr *note; + + note = (Elf32_Nhdr *)note_ptr; + pr = (struct x86_prstatus *)( + (char *)note + sizeof(Elf32_Nhdr) + note->n_namesz); + pr = (struct x86_prstatus *)roundup((ulong)pr, 4); + + sprintf(buf, + " si.signo: %d si.code: %d si.errno: %d cursig: %d\n" + " sigpend : %lu\n" + " sighold : %lu\n" + " pid: %d ppid: %d pgrp: %d sid: %d\n" + " utime: %01lld.%06d, stime: %01lld.%06d, cutime: %01lld.%06d, " + "cstime: %01lld.%06d\n" + " orig_eax: %ld, fpvalid: %d\n" + " EBX : 0x%08lx ECX : 0x%08lx\n" + " EDX : 0x%08lx ESI : 0x%08lx\n" + " EDI : 0x%08lx EBP : 0x%08lx\n" + " EAX : 0x%08lx EIP : 0x%08lx\n" + " EFLAGS : 0x%08lx ESP : 0x%08lx\n" + " DS: 0x%04lx ES: 0x%04lx FS: 0x%04lx GS: 0x%04lx " + "CS: 0x%04lx SS: 0x%04lx\n", + pr->si_signo, pr->si_code, pr->si_errno, pr->cursig, + pr->sigpend, pr->sighold, + pr->pid, pr->ppid, pr->pgrp, pr->sid, + (long long)pr->utime.tv_sec, (int)pr->utime.tv_usec, + (long long)pr->stime.tv_sec, (int)pr->stime.tv_usec, + (long long)pr->cutime.tv_sec, (int)pr->cutime.tv_usec, + (long long)pr->cstime.tv_sec, (int)pr->cstime.tv_usec, + pr->regs.orig_eax, pr->fpvalid, + pr->regs.ebx, pr->regs.ecx, + pr->regs.edx, pr->regs.esi, + pr->regs.edi, pr->regs.ebp, + pr->regs.eax, pr->regs.eip, + pr->regs.eflags, pr->regs.esp, + pr->regs.ds, pr->regs.es, pr->regs.fs, + pr->regs.gs, pr->regs.cs, pr->regs.ss + ); +} + +static void +display_qemu_x86_64(void *note_ptr, char *buf) +{ + int i, size; + Elf64_Nhdr *note; + QEMUCPUState *ptr; + QEMUCPUSegment *seg; + char *seg_names[] = {"CS", "DS", "ES", "FS", "GS", "SS", "LDT", "TR", + "GDT", "IDT"}; + + note = (Elf64_Nhdr *)note_ptr; + ptr = (QEMUCPUState *)( + (char *)note + sizeof(Elf64_Nhdr) + note->n_namesz); + + ptr = (QEMUCPUState *)roundup((ulong)ptr, 4); + seg = &(ptr->cs); + + size = sprintf(buf, + " version: 0x%08x size: 0x%08x\n" + " RAX : 0x%016llx RBX : 0x%016llx\n" + " RCX : 0x%016llx RDX : 0x%016llx\n" + " RSI : 0x%016llx RDI : 0x%016llx\n" + " RSP : 0x%016llx RBP : 0x%016llx\n" + " RIP : 0x%016llx RFLAGS: 0x%016llx\n" + " R8 : 0x%016llx R9 : 0x%016llx\n" + " R10 : 0x%016llx R11 : 0x%016llx\n" + " R12 : 0x%016llx R13 : 0x%016llx\n" + " R14 : 0x%016llx R15 : 0x%016llx\n", + ptr->version, ptr->size, + (ulonglong)ptr->rax, (ulonglong)ptr->rbx, + (ulonglong)ptr->rcx, (ulonglong)ptr->rdx, + (ulonglong)ptr->rsi, (ulonglong)ptr->rdi, + (ulonglong)ptr->rsp, (ulonglong)ptr->rbp, + (ulonglong)ptr->rip, (ulonglong)ptr->rflags, + (ulonglong)ptr->r8, (ulonglong)ptr->r9, + (ulonglong)ptr->r10, (ulonglong)ptr->r11, + (ulonglong)ptr->r12, (ulonglong)ptr->r13, + (ulonglong)ptr->r14, (ulonglong)ptr->r15 + ); + buf += size; + + for(i = 0; i < sizeof(seg_names)/sizeof(seg_names[0]); i++) { + size = sprintf(buf, + " %s:\n" + " selector: 0x%08x limit: 0x%08x flags: 0x%08x\n" + " pad : 0x%08x base : 0x%016llx\n", + seg_names[i], + seg->selector, seg->limit, seg->flags, + seg->pad, (ulonglong)seg->base + ); + buf += size; + seg++; + } + + sprintf(buf, + " cr[0]: %016llx cr[1]: %016llx cr[2]: %016llx\n" + " cr[3]: %016llx cr[4]: %016llx\n", + (ulonglong)ptr->cr[0], (ulonglong)ptr->cr[1], (ulonglong)ptr->cr[2], + (ulonglong)ptr->cr[3], (ulonglong)ptr->cr[4] + ); +} + +static void +display_qemu_x86(void *note_ptr, char *buf) +{ + int i, size, t=0; + Elf32_Nhdr *note; + QEMUCPUState *ptr; + QEMUCPUSegment *seg; + char *seg_names[] = {"CS", "DS", "ES", "FS", "GS", "SS", "LDT", "TR", + "GDT", "IDT"}; + + + note = (Elf32_Nhdr *)note_ptr; + ptr = (QEMUCPUState *)( + (char *)note + sizeof(Elf32_Nhdr) + note->n_namesz); + ptr = (QEMUCPUState *)roundup((ulong)ptr, 4); + seg = &(ptr->cs); + + size = sprintf(buf, + " version: 0x%08x\tsize: 0x%08x\n" + " EAX : 0x%016llx\tEBX : 0x%016llx\n" + " ECX : 0x%016llx\tEDX : 0x%016llx\n" + " ESI : 0x%016llx\tEDI : 0x%016llx\n" + " ESP : 0x%016llx\tEBP : 0x%016llx\n" + " EIP : 0x%016llx\tEFLAGS: 0x%016llx\n", + ptr->version, ptr->size, + (ulonglong)ptr->rax, (ulonglong)ptr->rbx, (ulonglong)ptr->rcx, + (ulonglong)ptr->rdx, (ulonglong)ptr->rsi, (ulonglong)ptr->rdi, + (ulonglong)ptr->rsp, (ulonglong)ptr->rbp, + (ulonglong)ptr->rip, (ulonglong)ptr->rflags + ); + buf += size; + t+=size; + + for(i = 0; i < sizeof(seg_names)/sizeof(seg_names[0]); i++) { + size = sprintf(buf, + " %s:\n" + " selector: 0x%08x limit: 0x%08x flags: 0x%08x\n" + " pad : 0x%08x base : 0x%016llx\n", + seg_names[i], + seg->selector, seg->limit, seg->flags, + seg->pad, (ulonglong)seg->base + ); + buf += size; + seg++; + } + + sprintf(buf, + " cr[0]: %016llx cr[1]: %016llx cr[2]: %016llx\n" + " cr[3]: %016llx cr[4]: %016llx\n", + (ulonglong)ptr->cr[0], (ulonglong)ptr->cr[1], (ulonglong)ptr->cr[2], + (ulonglong)ptr->cr[3], (ulonglong)ptr->cr[4] + ); +} + +void +display_ELF_note(int machine, int type, void *note, char *buf) +{ + switch (machine) + { + case EM_386: + switch (type) + { + case PRSTATUS: + display_prstatus_x86(note, buf); + break; + case QEMU: + display_qemu_x86(note, buf); + break; + } + break; + + case EM_X86_64: + switch (type) + { + case PRSTATUS: + display_prstatus_x86_64(note, buf); + break; + case QEMU: + display_qemu_x86_64(note, buf); + break; + } + break; + + default: + return; + } +} + void get_netdump_regs_x86_64(struct bt_info *bt, ulong *ripp, ulong *rspp) { -- 1.7.1