[Crash-utility] [PATCH v1 1/2] [ppc] Compressed KDUMP support for PPC32

Suzuki K. Poulose suzuki at in.ibm.com
Wed Jan 18 09:21:51 UTC 2012


This patch adds support for PPC32. Adds a ppc routine for processing the
elf_notes.

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

 diskdump.c |   59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 ppc.c      |    6 ++++++
 2 files changed, 64 insertions(+), 1 deletions(-)

diff --git a/diskdump.c b/diskdump.c
index 5519af7..f55186a 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -272,6 +272,32 @@ x86_process_elf_notes(void *note_ptr, unsigned long size_note)
 	}
 }
 
+void
+ppc_process_elf_notes(void *note_buf, unsigned long size_note)
+{
+	Elf32_Nhdr *nt;
+	size_t index, len;
+	int num = 0;
+
+	for (index = 0; index < size_note; index += len) {
+		nt = note_buf + index;
+
+		if(nt->n_type == NT_PRSTATUS) {
+			dd->nt_prstatus_percpu[num] = nt;
+			num ++;
+		}
+		len += sizeof(Elf32_Nhdr);
+		len = roundup(len + nt->n_namesz, 4);
+		len = roundup(len + nt->n_descsz, 4);
+	}
+
+	if (num > 0) {
+		dd->num_prstatus_notes = num;
+		pc->flags2 |= ELF_NOTES;
+	}
+	return;
+}
+
 static int 
 read_dump_header(char *file)
 {
@@ -471,6 +497,8 @@ restart:
 		dd->machine_type = EM_X86_64;
 	else if (machine_type("IA64"))
 		dd->machine_type = EM_IA_64;
+	else if (machine_type("PPC"))
+		dd->machine_type = EM_PPC;
 	else if (machine_type("PPC64"))
 		dd->machine_type = EM_PPC64;
 	else if (machine_type("S390X"))
@@ -912,6 +940,31 @@ extern void get_netdump_regs_x86(struct bt_info *, ulong *, ulong *);
 extern void get_netdump_regs_x86_64(struct bt_info *, ulong *, ulong *);
 
 static void
+get_diskdump_regs_ppc(struct bt_info *bt, ulong *eip, ulong *esp)
+{
+	Elf32_Nhdr *note;
+	int len;
+
+	if (KDUMP_CMPRS_VALID() &&
+		(bt->task == tt->panic_task || 
+		(is_task_active(bt->task) && dd->num_prstatus_notes > 1))) {
+		note  = (Elf32_Nhdr*) dd->nt_prstatus_percpu[bt->tc->processor];
+		if (!note)
+			error(FATAL,
+				    "cannot determine NT_PRSTATUS ELF note "
+				    "for %s task: %lx\n",
+					(bt->task == tt->panic_task) ?
+					"panic" : "active", bt->task);
+		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_diskdump_regs_ppc64(struct bt_info *bt, ulong *eip, ulong *esp)
 {
 	if ((bt->task == tt->panic_task) && DISKDUMP_VALID())
@@ -952,6 +1005,10 @@ get_diskdump_regs(struct bt_info *bt, ulong *eip, ulong *esp)
 		machdep->get_stack_frame(bt, eip, esp);
 		break;
 
+	case EM_PPC:
+		return get_diskdump_regs_ppc(bt, eip, esp);
+		break;
+
 	case EM_PPC64:
 		return get_diskdump_regs_ppc64(bt, eip, esp);
 		break;
@@ -1117,7 +1174,7 @@ dump_nt_prstatus_offset(FILE *fp)
 						(tot == 0) ? "" : "                      ",
 						(ulong)(offset + tot));
 
-			} else if (machine_type("X86")) {
+			} else if (machine_type("X86") || machine_type("PPC")) {
 				note32 = (void *)dd->notes_buf + tot;
 				len = sizeof(Elf32_Nhdr);
 				len = roundup(len + note32->n_namesz, 4);
diff --git a/ppc.c b/ppc.c
index 89b409b..078da4e 100755
--- a/ppc.c
+++ b/ppc.c
@@ -67,6 +67,8 @@ static void ppc_display_machine_stats(void);
 static void ppc_dump_line_number(ulong);
 static struct line_number_hook ppc_line_number_hooks[];
 
+/* Defined in diskdump.c , as it needs diskdump header details */
+extern ppc_process_elf_notes(void *, ulong);
 /*
  *  Do all necessary machine-specific setup here.  This is called twice,
  *  before and after GDB has been initialized.
@@ -79,6 +81,10 @@ ppc_init(int when)
 
 	switch (when)
 	{
+	case SETUP_ENV:
+		machdep->process_elf_notes = ppc_process_elf_notes;
+		break;
+
 	case PRE_SYMTAB:
 		machdep->verify_symbol = ppc_verify_symbol;
                 if (pc->flags & KERNEL_DEBUG_QUERY)




More information about the Crash-utility mailing list