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

Signed-off-by: Suzuki K. Poulose <[email protected]>
---

 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 ([email protected])
  */
 
+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;

--
Crash-utility mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility

Reply via email to