summaryrefslogtreecommitdiffstats
path: root/runtime/io.c
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/io.c')
-rw-r--r--runtime/io.c64
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;
+}