From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27456 invoked by alias); 1 Nov 2005 16:57:09 -0000 Mailing-List: contact systemtap-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Post: List-Help: , Sender: systemtap-owner@sourceware.org Received: (qmail 27375 invoked by uid 22791); 1 Nov 2005 16:57:05 -0000 Subject: [PATCH] Systemtap ppc64 runtime From: Hien Nguyen To: systemtap@sources.redhat.com Content-Type: text/plain Date: Tue, 01 Nov 2005 16:57:00 -0000 Message-Id: <1130864221.1047.4.camel@dyn9047022138.beaverton.ibm.com> Mime-Version: 1.0 X-Mailer: Evolution 2.2.3 (2.2.3-2.fc4) Content-Transfer-Encoding: 7bit X-SW-Source: 2005-q4/txt/msg00116.txt.bz2 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"