]> sourceware.org Git - systemtap.git/commitdiff
Added ppc64 _stp_stack_print
authorhien <hien>
Wed, 2 Nov 2005 18:51:09 +0000 (18:51 +0000)
committerhien <hien>
Wed, 2 Nov 2005 18:51:09 +0000 (18:51 +0000)
runtime/runtime.h
runtime/stack.c

index fba6f15342c71a9a8bed32958ca24c53f2b3c2bf..f226358f7a5ee4e35ff68cc34f3c30af76f8a300 100644 (file)
@@ -71,6 +71,10 @@ static const char * (*_stp_kallsyms_lookup)(unsigned long addr,
                                            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
@@ -132,8 +136,21 @@ static const char * _stp_kallsyms_lookup_tabled (unsigned long addr,
 #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;
index 206d656aeed2baba5e12b3b79d5a680f13c48d0b..10c27248d83d30f9c92bdfb2cba7a9e69b82c129 100644 (file)
@@ -161,7 +161,77 @@ static void __stp_stack_sprint (String str, unsigned long *stack, int verbose, i
                        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"
This page took 0.030425 seconds and 5 git commands to generate.