[Crash-utility] [PATCH v2 2/3] [ppc][netdump] Read register set from ELF Note

Suzuki K. Poulose suzuki at in.ibm.com
Thu Dec 29 10:30:11 UTC 2011


This patch adds support for reading the register set on PPC32,
from the ELF note in a dump.

Signed-off-by: Suzuki K. Poulose <suzuki at in.ibm.com>
---

 netdump.c |   71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/netdump.c b/netdump.c
index c0ee9ae..f7bf7d8 100644
--- a/netdump.c
+++ b/netdump.c
@@ -33,6 +33,7 @@ static size_t dump_Elf32_Nhdr(Elf32_Off offset, int);
 static void dump_Elf64_Ehdr(Elf64_Ehdr *);
 static void dump_Elf64_Phdr(Elf64_Phdr *, int);
 static size_t dump_Elf64_Nhdr(Elf64_Off offset, int);
+static void get_netdump_regs_ppc(struct bt_info *, ulong *, ulong *);
 static void get_netdump_regs_ppc64(struct bt_info *, ulong *, ulong *);
 static void get_netdump_regs_arm(struct bt_info *, ulong *, ulong *);
 static physaddr_t xen_kdump_p2m(physaddr_t);
@@ -2172,6 +2173,10 @@ get_netdump_regs(struct bt_info *bt, ulong *eip, ulong *esp)
 		machdep->get_stack_frame(bt, eip, esp);
 		break;
 
+	case EM_PPC:
+		return get_netdump_regs_ppc(bt, eip, esp);
+		break;
+
 	case EM_PPC64:
 		return get_netdump_regs_ppc64(bt, eip, esp);
 		break;
@@ -2551,6 +2556,40 @@ next_sysrq:
 }
 
 static void
+get_netdump_regs_ppc(struct bt_info *bt, ulong *eip, ulong *esp)
+{
+	Elf32_Nhdr *note;
+	size_t len;
+
+	if ((bt->task == tt->panic_task) ||
+		(is_task_active(bt->task) && nd->num_prstatus_notes > 1)) {
+		/*	
+		 * Registers are saved during the dump process for the 
+		 * panic task. Whereas in kdump, regs are captured for all 
+		 * CPUs if they responded to an IPI.
+		 */
+                if (nd->num_prstatus_notes > 1) {
+			if (!nd->nt_prstatus_percpu[bt->tc->processor])
+				error(FATAL, 
+		          	    "cannot determine NT_PRSTATUS ELF note "
+				    "for %s task: %lx\n", 
+					(bt->task == tt->panic_task) ?
+					"panic" : "active", bt->task);	
+                        note = (Elf32_Nhdr *)
+                                nd->nt_prstatus_percpu[bt->tc->processor];
+		} else
+			note = (Elf32_Nhdr *)nd->nt_prstatus;
+
+		len = sizeof(Elf32_Nhdr);
+		len = roundup(len + note->n_namesz, 4);
+		bt->machdep = (void *)((char *)note + len + 
+			MEMBER_OFFSET("elf_prstatus", "pr_reg"));
+	}
+
+	machdep->get_stack_frame(bt, eip, esp);
+}
+
+static void
 get_netdump_regs_ppc64(struct bt_info *bt, ulong *eip, ulong *esp)
 {
 	Elf64_Nhdr *note;
@@ -2838,6 +2877,7 @@ xen_minor_version(void)
  *  Contributed by: Sharyathi Nagesh (sharyath at in.ibm.com)
  */
 
+static void *get_ppc_regs_from_elf_notes(struct task_context *);
 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 *);
@@ -2876,6 +2916,7 @@ get_regs_from_elf_notes(struct task_context *tc)
 	switch (e_machine)
 	{
 	case EM_386:
+	case EM_PPC:
 	case EM_PPC64:
 	case EM_X86_64:
 	case EM_ARM:
@@ -2895,6 +2936,8 @@ get_regs_from_elf_notes(struct task_context *tc)
 	{
 	case EM_386:
 		return get_x86_regs_from_elf_notes(tc);
+	case EM_PPC:
+		return get_ppc_regs_from_elf_notes(tc);
 	case EM_PPC64:
 		return get_ppc64_regs_from_elf_notes(tc);
 	case EM_X86_64:
@@ -2964,6 +3007,34 @@ get_x86_64_regs_from_elf_notes(struct task_context *tc)
 }
 
 static void * 
+get_ppc_regs_from_elf_notes(struct task_context *tc)
+{
+	Elf32_Nhdr *note;
+	size_t len;
+	void *pt_regs;
+	extern struct vmcore_data *nd;
+
+	pt_regs = NULL;
+
+	/*
+	 * 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) {
+		note = (Elf32_Nhdr *)nd->nt_prstatus_percpu[tc->processor];
+	} else
+		note = (Elf32_Nhdr *)nd->nt_prstatus;
+
+	len = sizeof(Elf32_Nhdr);
+	len = roundup(len + note->n_namesz, 4);
+	pt_regs = (void *)((char *)note + len +
+			   MEMBER_OFFSET("elf_prstatus", "pr_reg"));
+
+	return pt_regs;
+}
+
+static void * 
 get_ppc64_regs_from_elf_notes(struct task_context *tc)
 {
 	Elf64_Nhdr *note;




More information about the Crash-utility mailing list