Sharyathi Nagesh wrote: > Dave > > Excuse me for overlooking this part of the code, I am attaching a fix to this, hope this fixes the issue. I cleaned up your latest version a bit, and have attached the proposed patch to defs.h and netdump.c. The only functional differences I made was to ensure that there are multiple NT_PRSTATUS sections when the requested task is just an active task (i.e. not the panic task). You had correctly made that check for ppc64, but not for the other two arches. Dave
Index: defs.h =================================================================== RCS file: /nfs/projects/cvs/crash/defs.h,v retrieving revision 1.373 diff -u -r1.373 defs.h --- defs.h 30 Apr 2009 18:24:28 -0000 1.373 +++ defs.h 27 May 2009 20:01:10 -0000 @@ -4137,6 +4137,8 @@ ulong xen_phys_start(void); int xen_major_version(void); int xen_minor_version(void); +int get_netdump_arch(void); +void *get_regs_from_elf_notes(struct task_context *); /* * diskdump.c Index: netdump.c =================================================================== RCS file: /nfs/projects/cvs/crash/netdump.c,v retrieving revision 1.87 diff -u -r1.87 netdump.c --- netdump.c 15 Apr 2009 18:19:35 -0000 1.87 +++ netdump.c 27 May 2009 20:47:41 -0000 @@ -2488,3 +2488,151 @@ { return nd->xen_kdump_data->xen_minor_version; } + + +/* + * The following set of functions are not used by the crash + * source code, but are available to extension modules for + * gathering register sets from ELF NT_PRSTATUS note sections. + * + * Contributed by: Sharyathi Nagesh (sharyath@xxxxxxxxxx) + */ + +static void *get_ppc64_regs_from_elf_notes(struct task_context *); +static void *get_x86_regs_from_elf_notes(struct task_context *); +static void *get_x86_64_regs_from_elf_notes(struct task_context *); + +int get_netdump_arch(void) +{ + int e_machine; + + if (nd->elf32) + e_machine = nd->elf32->e_machine; + else if (nd->elf64) + e_machine = nd->elf64->e_machine; + else + e_machine = EM_NONE; + + return e_machine; +} + +void * +get_regs_from_elf_notes(struct task_context *tc) +{ + switch(get_netdump_arch()) + { + case EM_386: + return get_x86_regs_from_elf_notes(tc); + case EM_PPC64: + return get_ppc64_regs_from_elf_notes(tc); + case EM_X86_64: + return get_x86_64_regs_from_elf_notes(tc); + default: + error(FATAL, + "support for ELF machine type %d not available\n", + get_netdump_arch()); + } + + return NULL; +} + +static void * +get_x86_regs_from_elf_notes(struct task_context *tc) +{ + Elf32_Nhdr *note_32; + Elf64_Nhdr *note_64; + void *note; + size_t len; + void *pt_regs; + + if ((tc->task == tt->panic_task) || + (is_task_active(tc->task) && (nd->num_prstatus_notes > 1))) { + if (nd->num_prstatus_notes > 1) + note = (void *) + nd->nt_prstatus_percpu[tc->processor]; + else + note = (void *)nd->nt_prstatus; + if (nd->elf32) { + note_32 = (Elf32_Nhdr *)note; + len = sizeof(Elf32_Nhdr); + len = roundup(len + note_32->n_namesz, 4); + } else if (nd->elf64) { + note_64 = (Elf64_Nhdr *)note; + len = sizeof(Elf64_Nhdr); + len = roundup(len + note_64->n_namesz, 4); + } + + pt_regs = (void *)((char *)note + len + + MEMBER_OFFSET("elf_prstatus", "pr_reg")); + /* NEED TO BE FIXED: Hack to get the proper alignment */ + pt_regs +=4; + } else + error(FATAL, + "cannot determine register set for task \"%s\"\n", + tc->comm); + return pt_regs; + +} + +static void * +get_x86_64_regs_from_elf_notes(struct task_context *tc) +{ + Elf64_Nhdr *note; + size_t len; + void *pt_regs; + + if ((tc->task == tt->panic_task) || + (is_task_active(tc->task) && (nd->num_prstatus_notes > 1))) { + if (nd->num_prstatus_notes > 1) + note = (Elf64_Nhdr *) + nd->nt_prstatus_percpu[tc->processor]; + else + note = (Elf64_Nhdr *)nd->nt_prstatus; + + len = sizeof(Elf64_Nhdr); + len = roundup(len + note->n_namesz, 4); + pt_regs = (void *)((char *)note + len + + MEMBER_OFFSET("elf_prstatus", "pr_reg")); + } else + error(FATAL, + "cannot determine register set for task \"%s\"\n", + tc->comm); + return pt_regs; +} + +static void * +get_ppc64_regs_from_elf_notes(struct task_context *tc) +{ + Elf64_Nhdr *note; + size_t len; + void *pt_regs; + extern struct vmcore_data *nd; + + if ((tc->task == tt->panic_task) || + (is_task_active(tc->task) && (nd->num_prstatus_notes > 1))) { + /* + * Registers are always saved during the dump process for the + * panic task. Kdump also captures registers for all CPUs if + * they responded to an IPI. + */ + if (nd->num_prstatus_notes > 1) { + if (tc->processor >= nd->num_prstatus_notes) + error(FATAL, "cannot determine NT_PRSTATUS ELF note " + "for %s task: %lx\n", (tc->task == tt->panic_task) ? + "panic" : "active", tc->task); + note = (Elf64_Nhdr *) + nd->nt_prstatus_percpu[tc->processor]; + } else + note = (Elf64_Nhdr *)nd->nt_prstatus; + + len = sizeof(Elf64_Nhdr); + len = roundup(len + note->n_namesz, 4); + pt_regs = (void *)((char *)note + len + + MEMBER_OFFSET("elf_prstatus", "pr_reg")); + } else + error(FATAL, + "cannot determine register set for task \"%s\"\n", + tc->comm); + + return pt_regs; +}
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility