Re: [PATCH 0/3] Display local variables & function parameters from stack frames

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




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

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux