[PATCH] Systemtap ppc64 runtime

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] Systemtap ppc64 runtime

Hien Nguyen
This patch implements the _stp_stack_print() function for the ppc64
runtime. In order for this implementation to work, the kernel needs to
be configured with CONFIG_KALLSYMS_ALL=y.

Some background. we use the kallsyms_lookup_name() to get access to some
of the unexported functions in the kernel. Under ppc64, the
kallsysms_lookup_name(".funcname") gives us the function entry address,
but the kallsyms_lookup_name("funcname") gives us the function
descriptor. We want the latter case. See the reference
http://www.linuxbase.org/spec/ELF/ppc64/PPC-elf64abi-1.7.html#FUNC-DES

The patch should apply to the snapshoot systemtap-20052910.tar.bz2.


Hien.



--- src-20051029/runtime/runtime.h 2005-10-28 15:49:28.000000000 -0700
+++ src-20051029.works/runtime/runtime.h 2005-10-31 10:18:18.000000000 -0800
@@ -70,6 +70,10 @@
     unsigned long *symbolsize,
     unsigned long *offset,
     char **modname, char *namebuf);
+#if defined (__powerpc64__)
+static int (*_stp_validate_sp)(unsigned long sp, struct task_struct *p,
+ unsigned long nbytes);
+#endif
 
 /* TEST_MODE is always defined by systemtap */
 #ifdef TEST_MODE
@@ -131,8 +135,21 @@
 #endif
 int init_module (void)
 {
+/*
+ * In order for the kallsyms_lookup_name hack to work under ppc64, we need
+ * CONFIG_KALLSYMS_ALL=y.
+ * On ppc64 the kallsyms_lookup_name(.funcname) returns the function entry,
+ * but kallsyms_lookup_name(funcname) returns the function descriptor
+ * (func_descr_t). The latter is what we want, and those symbols are only
+ * available with CONFIG_KALLSYMS_ALL=y.
+ */
   _stp_kta = (int (*)(unsigned long))kallsyms_lookup_name("__kernel_text_address");
 
+#if defined (__powerpc64__)
+_stp_validate_sp = (int (*)(unsigned long, struct task_struct *,
+ unsigned long)) kallsyms_lookup_name("validate_sp");
+#endif
+
 #ifdef SYSTEMTAP
   if (stap_num_symbols > 0)
     _stp_kallsyms_lookup = & _stp_kallsyms_lookup_tabled;
--- src-20051029/runtime/stack.c 2005-10-28 15:49:28.000000000 -0700
+++ src-20051029.works/runtime/stack.c 2005-10-31 10:31:50.000000000 -0800
@@ -161,7 +161,77 @@
  break;
  }
 }
+#elif defined (__powerpc64__)
+static int kstack_depth_to_print = 5;
 
+static void __stp_stack_sprint (String str, unsigned long *_sp,
+ int verbose, int levels)
+{
+ struct task_struct *p = current;
+ unsigned long ip, newsp, lr = 0;
+ int count = 0;
+ unsigned long sp = (unsigned long)_sp;
+ int firstframe = 1;
+
+ if (sp == 0) {
+ if (p) {
+ sp = p->thread.ksp;
+ } else {
+ sp = __get_SP();
+ p = current;
+ }
+ }
+
+ if (!_stp_validate_sp)
+ return;
+
+ lr = 0;
+ do {
+ if (!_stp_validate_sp(sp, p, 112))
+ return;
+
+ _sp = (unsigned long *) sp;
+ newsp = _sp[0];
+ ip = _sp[2];
+ if (!firstframe || ip != lr) {
+ if (verbose) {
+ _stp_sprintf(str, "[%016lx] [%016lx] ", sp, ip);
+ _stp_symbol_sprint(str, ip);
+ if (firstframe)
+ _stp_string_cat(str, " (unreliable)");
+ }
+ else
+ _stp_sprintf(str,"%lx ", ip);
+ }
+ firstframe = 0;
+ /*
+ * See if this is an exception frame.
+ * We look for the "regshere" marker in the current frame.
+ */
+ if (_stp_validate_sp(sp, p, sizeof(struct pt_regs) + 400)
+ && _sp[12] == 0x7265677368657265ul) {
+ struct pt_regs *regs = (struct pt_regs *)
+ (sp + STACK_FRAME_OVERHEAD);
+ if (verbose) {
+ _stp_sprintf(str, "--- Exception: %lx at ",
+ regs->trap);
+ _stp_symbol_sprint(str, regs->nip);
+ _stp_string_cat(str, "\n");
+ lr = regs->link;
+ _stp_string_cat(str, "    LR =");
+ _stp_symbol_sprint(str, lr);
+ _stp_string_cat(str, "\n");
+ firstframe = 1;
+ }
+ else {
+ _stp_sprintf(str, "%lx ",regs->nip);
+ _stp_sprintf(str, "%lx ",regs->link);
+ }
+ }
+
+ sp = newsp;
+ } while (count++ < kstack_depth_to_print);
+}
 
 #else
 #error "Unsupported architecture"


Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] Systemtap ppc64 runtime

Martin Hunt
On Tue, 2005-11-01 at 08:57 -0800, Hien Nguyen wrote:
> This patch implements the _stp_stack_print() function for the ppc64
> runtime. In order for this implementation to work, the kernel needs to
> be configured with CONFIG_KALLSYMS_ALL=y.

Looks reasonable.  Go ahead and check it in.

Martin