diff options
author | hunt <hunt> | 2007-01-31 20:13:02 +0000 |
---|---|---|
committer | hunt <hunt> | 2007-01-31 20:13:02 +0000 |
commit | 1b276fc2991255d65c28fa2df03b7b9ecc7d4f7b (patch) | |
tree | 09dddc7115d2691e05ee392c2316c0793013a709 /runtime/regs.c | |
parent | dcc4fec4fbb6caddbc82c758f57c014cfc37d088 (diff) | |
download | systemtap-steved-1b276fc2991255d65c28fa2df03b7b9ecc7d4f7b.tar.gz systemtap-steved-1b276fc2991255d65c28fa2df03b7b9ecc7d4f7b.tar.xz systemtap-steved-1b276fc2991255d65c28fa2df03b7b9ecc7d4f7b.zip |
2007-01-31 Martin Hunt <hunt@redhat.com>
* string.c (_stp_string_init): Deleted.
(_stp_sprintf): Deleted.
(_stp_vsprintf): Deleted.
(_stp_string_cat_cstr): Deleted.
(_stp_string_cat_string): Deleted.
(_stp_string_cat_char): Deleted.
(_stp_string_ptr): Deleted.
(_stp_string_cat): Deleted.
(_stp_snprintf): Moved from vsprintf.c.
(_stp_vscnprintf): Moved from vsprintf.c.
* string.h (STP_STRING_SIZE): Deleted.
(STP_NUM_STRINGS): Deleted.
Remove all references to type "String".
* vsprintf.c (_stp_vscnprintf): Moved to string.c.
(_stp_snprintf): Moved to string.c
* sym.c (_stp_symbol_sprint): Replaced with
_stp_symbol_print, which writes to the print buffer.
(_stp_symbol_sprint_basic): Replaced with
_stp_symbol_snprint.
* runtime.h: Include io.c.
* stat-common.c: Use new _stp_print* functions.
* stat.c: Ditto.
* regs.c: Renamed to regs-ia64.c.
* current.c: Renamed regs.c.
* regs-ia64.c: New file (renamed from regs.c).
* stack.c (_stp_stack_sprint): Renamed _stp_stack_print
and now just prints to the print buffer. Calls
__stp_stack_print instead of __stp_stack_sprint.
(_stp_stack_snprint): New function. Calls _stp_stack_print and
then copies the print buffer into a string.
(_stp_stack_printj): Deleted.
(_stp_ustack_sprint): Deleted.
* stack-*.c: Rewritten to print instead of writing to strings.
Uses new _stp_print* functions.
* print.c (_stp_printf): Create new function instead of macro.
(_stp_print): Ditto.
(_stp_print_char): New function.
* map.c: Use _stp_print() and _stp_print_char()
instead of _stp_print_cstr().
* io.c (_stp_vlog): Use _stp_print() instead
of _stp_string_cat_cstr().
* copy.c (_stp_string_from_user): Deleted.
Diffstat (limited to 'runtime/regs.c')
-rw-r--r-- | runtime/regs.c | 279 |
1 files changed, 217 insertions, 62 deletions
diff --git a/runtime/regs.c b/runtime/regs.c index 6a879966..ead4ed8f 100644 --- a/runtime/regs.c +++ b/runtime/regs.c @@ -1,5 +1,6 @@ /* -*- linux-c -*- - * register access functions + * Functions to access the members of pt_regs struct + * Copyright (C) 2005 Red Hat Inc. * Copyright (C) 2005 Intel Corporation. * * This file is part of systemtap, and is free software. You can @@ -8,82 +9,236 @@ * later version. */ -#ifndef _REG_C_ -#define _REG_C_ +#ifndef _REGS_C_ +#define _REGS_C_ -#if defined __ia64__ +#include "regs.h" -struct ia64_stap_get_arbsp_param { - unsigned long ip; - unsigned long *address; -}; +/** @file current.c + * @brief Functions to get the current state. + */ +/** @addtogroup current Current State + * Functions to get the current state. + * @{ + */ -static void ia64_stap_get_arbsp(struct unw_frame_info *info, void *arg) -{ - unsigned long ip; - struct ia64_stap_get_arbsp_param *lp = arg; - do { - unw_get_ip(info, &ip); - if (ip == 0) - break; - if (ip == lp->ip) { - unw_get_bsp(info, (unsigned long*)&lp->address); - return; - } - } while (unw_unwind(info) >= 0); - lp->address = 0; +/** Get the current return address. + * Call from kprobes (not jprobes). + * @param regs The pt_regs saved by the kprobe. + * @return The return address saved in the stack pointer. + * @note i386 and x86_64 only so far. + */ + +unsigned long _stp_ret_addr (struct pt_regs *regs) +{ +#ifdef __x86_64__ + unsigned long *ra = (unsigned long *)regs->rsp; + if (ra) + return *ra; + else + return 0; +#elif defined (__i386__) + return regs->esp; +#elif defined (__powerpc64__) + return REG_LINK(regs); +#elif defined (__ia64__) + return regs->b0; +#elif defined (__s390__) || defined (__s390x__) + return regs->gprs[14]; +#else + #error Unimplemented architecture +#endif } -static long ia64_fetch_register(int regno, struct pt_regs *pt_regs) +/** Get the current return address for a return probe. + * Call from kprobe return probe. + * @param ri Pointer to the struct kretprobe_instance. + * @return The return address + */ +#define _stp_ret_addr_r(ri) (ri->ret_addr) + +/** Get the probe address for a kprobe. + * Call from a kprobe. This will return the + * address of the function that is being probed. + * @param kp Pointer to the struct kprobe. + * @return The function's address + */ +#define _stp_probe_addr(kp) (kp->addr) + +/** Get the probe address for a return probe. + * Call from kprobe return probe. This will return the + * address of the function that is being probed. + * @param ri Pointer to the struct kretprobe_instance. + * @return The function's address + */ +#define _stp_probe_addr_r(ri) (ri->rp->kp.addr) + +#ifdef __x86_64__ +void _stp_print_regs(struct pt_regs * regs) { - struct ia64_stap_get_arbsp_param pa; + unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs; + unsigned int fsindex,gsindex; + unsigned int ds,cs,es; + + _stp_printf("RIP: %016lx\nRSP: %016lx EFLAGS: %08lx\n", regs->rip, regs->rsp, regs->eflags); + _stp_printf("RAX: %016lx RBX: %016lx RCX: %016lx\n", + regs->rax, regs->rbx, regs->rcx); + _stp_printf("RDX: %016lx RSI: %016lx RDI: %016lx\n", + regs->rdx, regs->rsi, regs->rdi); + _stp_printf("RBP: %016lx R08: %016lx R09: %016lx\n", + regs->rbp, regs->r8, regs->r9); + _stp_printf("R10: %016lx R11: %016lx R12: %016lx\n", + regs->r10, regs->r11, regs->r12); + _stp_printf("R13: %016lx R14: %016lx R15: %016lx\n", + regs->r13, regs->r14, regs->r15); + + asm("movl %%ds,%0" : "=r" (ds)); + asm("movl %%cs,%0" : "=r" (cs)); + asm("movl %%es,%0" : "=r" (es)); + asm("movl %%fs,%0" : "=r" (fsindex)); + asm("movl %%gs,%0" : "=r" (gsindex)); + + rdmsrl(MSR_FS_BASE, fs); + rdmsrl(MSR_GS_BASE, gs); + rdmsrl(MSR_KERNEL_GS_BASE, shadowgs); + + asm("movq %%cr0, %0": "=r" (cr0)); + asm("movq %%cr2, %0": "=r" (cr2)); + asm("movq %%cr3, %0": "=r" (cr3)); + asm("movq %%cr4, %0": "=r" (cr4)); + + _stp_printf("FS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n", + fs,fsindex,gs,gsindex,shadowgs); + _stp_printf("CS: %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds, es, cr0); + _stp_printf("CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, cr4); +} - if (regno >= 8 && regno <= 11) - return *(unsigned long *)(&pt_regs->r8 + regno - 8); - else if (regno < 32 || regno > 127) - return 0; +#elif defined (__ia64__) +void _stp_print_regs(struct pt_regs * regs) +{ + unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri; + + _stp_printf("\nPid: %d, CPU %d, comm: %20s\n", current->pid, + smp_processor_id(), current->comm); + _stp_printf("psr : %016lx ifs : %016lx ip : [<%016lx>] \n", + regs->cr_ipsr, regs->cr_ifs, ip); + _stp_printf("unat: %016lx pfs : %016lx rsc : %016lx\n", + regs->ar_unat, regs->ar_pfs, regs->ar_rsc); + _stp_printf("rnat: %016lx bsps: %016lx pr : %016lx\n", + regs->ar_rnat, regs->ar_bspstore, regs->pr); + _stp_printf("ldrs: %016lx ccv : %016lx fpsr: %016lx\n", + regs->loadrs, regs->ar_ccv, regs->ar_fpsr); + _stp_printf("csd : %016lx ssd : %016lx\n", + regs->ar_csd, regs->ar_ssd); + _stp_printf("b0 : %016lx b6 : %016lx b7 : %016lx\n", + regs->b0, regs->b6, regs->b7); + _stp_printf("f6 : %05lx%016lx f7 : %05lx%016lx\n", + regs->f6.u.bits[1], regs->f6.u.bits[0], + regs->f7.u.bits[1], regs->f7.u.bits[0]); + _stp_printf("f8 : %05lx%016lx f9 : %05lx%016lx\n", + regs->f8.u.bits[1], regs->f8.u.bits[0], + regs->f9.u.bits[1], regs->f9.u.bits[0]); + _stp_printf("f10 : %05lx%016lx f11 : %05lx%016lx\n", + regs->f10.u.bits[1], regs->f10.u.bits[0], + regs->f11.u.bits[1], regs->f11.u.bits[0]); +} - pa.ip = pt_regs->cr_iip; - unw_init_running(ia64_stap_get_arbsp, &pa); - if (pa.address == 0) - return 0; +#elif defined (__i386__) - return *ia64_rse_skip_regs(pa.address, regno-32); +/** Write the registers to a string. + * @param regs The pt_regs saved by the kprobe. + * @note i386 and x86_64 only so far. + */ +void _stp_print_regs(struct pt_regs * regs) +{ + unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L; + + _stp_printf ("EIP: %08lx\n",regs->eip); + _stp_printf ("ESP: %08lx\n",regs->esp); + _stp_printf ("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", + regs->eax,regs->ebx,regs->ecx,regs->edx); + _stp_printf ("ESI: %08lx EDI: %08lx EBP: %08lx", + regs->esi, regs->edi, regs->ebp); + _stp_printf (" DS: %04x ES: %04x\n", + 0xffff & regs->xds,0xffff & regs->xes); + + __asm__("movl %%cr0, %0": "=r" (cr0)); + __asm__("movl %%cr2, %0": "=r" (cr2)); + __asm__("movl %%cr3, %0": "=r" (cr3)); + /* This could fault if %cr4 does not exist */ + __asm__("1: movl %%cr4, %0 \n" + "2: \n" + ".section __ex_table,\"a\" \n" + ".long 1b,2b \n" + ".previous \n" + : "=r" (cr4): "0" (0)); + _stp_printf ("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4); } -static void ia64_store_register(int regno, - struct pt_regs *pt_regs, - unsigned long value) +#elif defined (__powerpc64__) + +void _stp_print_regs(struct pt_regs * regs) { - struct ia64_stap_get_arbsp_param pa; - unsigned long rsc_save = 0; - unsigned long *addr; - - if (regno >= 8 && regno <= 11) { - addr =&pt_regs->r8; - addr += regno - 8; - *(addr) = value; + int i; + + _stp_printf("NIP: %016lX XER: %08X LR: %016lX CTR: %016lX\n", + regs->nip, (unsigned int)regs->xer, regs->link, regs->ctr); + _stp_printf("REGS: %p TRAP: %04lx\n", regs, regs->trap); + _stp_printf("MSR: %016lx CR: %08X\n", + regs->msr, (unsigned int)regs->ccr); + _stp_printf("DAR: %016lx DSISR: %016lx\n", + regs->dar, regs->dsisr); + +#ifdef CONFIG_SMP + _stp_printf(" CPU: %d", smp_processor_id()); +#endif /* CONFIG_SMP */ + + for (i = 0; i < 32; i++) { + if ((i % 4) == 0) { + _stp_printf("\n GPR%02d: ", i); + } + + _stp_printf("%016lX ", regs->gpr[i]); + if (i == 13 && !FULL_REGS(regs)) + break; } - else if (regno < 32 || regno > 127) - return; - - pa.ip = pt_regs->cr_iip; - unw_init_running(ia64_stap_get_arbsp, &pa); - if (pa.address == 0) - return; - *ia64_rse_skip_regs(pa.address, regno-32) = value; - //Invalidate all stacked registers outside the current frame - asm volatile( "mov %0=ar.rsc;;\n\t" - "mov ar.rsc=0;;\n\t" - "{\n\tloadrs;;\n\t\n\t\n\t}\n\t" - "mov ar.rsc=%1\n\t" - :"=r" (rsc_save):"r" (rsc_save):"memory"); - - return; + _stp_printf("\nNIP [%016lx] ", regs->nip); + _stp_printf("LR [%016lx]\n", regs->link); } -#endif /* if defined __ia64__ */ +#elif defined (__s390x__) || defined (__s390__) + +#ifdef __s390x__ +#define GPRSIZE "%016lX " +#else /* s390 */ +#define GPRSIZE "%08lX " +#endif + +void _stp_print_regs(struct pt_regs * regs) +{ + char *mode; + int i; + + mode = (regs->psw.mask & PSW_MASK_PSTATE) ? "User" : "Krnl"; + _stp_printf("%s PSW : ["GPRSIZE"] ["GPRSIZE"]", + mode, (void *) regs->psw.mask, + (void *) regs->psw.addr); + +#ifdef CONFIG_SMP + _stp_printf(" CPU: %d", smp_processor_id()); +#endif /* CONFIG_SMP */ + + for (i = 0; i < 16; i++) { + if ((i % 4) == 0) { + _stp_printf("\n GPRS%02d: ", i); + } + _stp_printf(GPRSIZE, regs->gprs[i]); + } + _stp_printf("\n"); +} +#endif -#endif /* _REG_C_ */ +/** @} */ +#endif /* _REGS_C_ */ |