diff options
Diffstat (limited to 'runtime/io.c')
-rw-r--r-- | runtime/io.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/runtime/io.c b/runtime/io.c index 3371df16..8756a48d 100644 --- a/runtime/io.c +++ b/runtime/io.c @@ -17,3 +17,67 @@ void dlog (const char *fmt, ...) va_end(args); } + +static const char * (*_stp_kallsyms_lookup)(unsigned long addr, + unsigned long *symbolsize, + unsigned long *offset, + char **modname, char *namebuf)=(void *)KALLSYMS_LOOKUP; + + +#define STP_BUF_LEN 8191 + +/* FIXME. These need to be per-cpu */ +static char _stp_pbuf[STP_BUF_LEN+1]; +static int _stp_pbuf_len = STP_BUF_LEN; + +void _stp_print_buf (const char *fmt, ...) +{ + int num; + va_list args; + char *buf = _stp_pbuf + STP_BUF_LEN - _stp_pbuf_len; + va_start(args, fmt); + num = vscnprintf(buf, _stp_pbuf_len, fmt, args); + va_end(args); + if (num > 0) + _stp_pbuf_len -= num; +} + +void _stp_print_buf_init (void) +{ + _stp_pbuf_len = STP_BUF_LEN; + _stp_pbuf[0] = 0; +} + +void _stp_print_symbol(const char *fmt, unsigned long address) +{ + char *modname; + const char *name; + unsigned long offset, size; + char namebuf[KSYM_NAME_LEN+1]; + + name = _stp_kallsyms_lookup(address, &size, &offset, &modname, namebuf); + + if (!name) + _stp_print_buf("0x%lx", address); + else { + if (modname) + _stp_print_buf("%s+%#lx/%#lx [%s]", name, offset, + size, modname); + else + _stp_print_buf("%s+%#lx/%#lx", name, offset, size); + } +} + + +unsigned long cur_ret_addr (struct pt_regs *regs) +{ +#ifdef __x86_64__ + unsigned long *ra = (unsigned long *)regs->rsp; +#else + unsigned long *ra = (unsigned long *)regs->esp; +#endif + if (ra) + return *ra; + else + return 0; +} |