Main Page | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

io.c

Go to the documentation of this file.
00001 /* -*- linux-c -*- */
00002 /** @file io.c
00003  * @brief I/O functions
00004  */
00005 
00006 /** Logs data.
00007  * This function is compatible with printk.  In fact it currently
00008  * sends all output to vprintk, after sending "STP: ". This allows
00009  * us to easily detect SystemTap output in the log file.
00010  *
00011  * @param fmt A variable number of args.
00012  * @bug Lines are limited in length by printk buffer.
00013  * @todo Needs replaced with something much faster that does not
00014  * use the system log.
00015  */
00016 void dlog (const char *fmt, ...)
00017 {
00018   va_list args;
00019   printk("STP: ");
00020   va_start(args, fmt);
00021   vprintk(fmt, args);
00022   va_end(args);
00023 }
00024 
00025 
00026 /** Lookup symbol.
00027  * This simply calls the kernel function kallsyms_lookup().
00028  * That function is not exported, so this workaround is required.
00029  * See the kernel source, kernel/kallsyms.c for more information.
00030  */
00031 static const char * (*_stp_kallsyms_lookup)(unsigned long addr,
00032                             unsigned long *symbolsize,
00033                             unsigned long *offset,
00034                             char **modname, char *namebuf)=(void *)KALLSYMS_LOOKUP;
00035 
00036 
00037 #define STP_BUF_LEN 8191
00038 
00039 /** Static buffer for printing */
00040 static char _stp_pbuf[STP_BUF_LEN+1];
00041 static int _stp_pbuf_len = STP_BUF_LEN;
00042 
00043 /** Print into the print buffer.
00044  * Like printf, except output goes into  _stp_pbuf,
00045  * which will contain the null-terminated output.
00046  * Safe because overflowing _stp_pbuf is not allowed.
00047  * Size is limited by length of print buffer.
00048  *
00049  * @param fmt A variable number of args.
00050  * @note Formatting output should never be done within
00051  * a probe. Use at module exit time.
00052  * @sa _stp_print_buf_init
00053  */
00054 
00055 void _stp_print_buf (const char *fmt, ...)
00056 {
00057   int num;
00058   va_list args;
00059   char *buf = _stp_pbuf + STP_BUF_LEN - _stp_pbuf_len;
00060   va_start(args, fmt);
00061   num = vscnprintf(buf, _stp_pbuf_len, fmt, args);
00062   va_end(args);
00063   if (num > 0)
00064     _stp_pbuf_len -= num;
00065 }
00066 
00067 /** Clear the print buffer.
00068  * Output from _stp_print_buf() will accumulate in the buffer
00069  * until this is called.
00070  */
00071 
00072 void _stp_print_buf_init (void)
00073 {
00074   _stp_pbuf_len = STP_BUF_LEN;
00075   _stp_pbuf[0] = 0;
00076 }
00077 
00078 /** Print addresses symbolically into the print buffer.
00079  * @param fmt A variable number of args.
00080  * @param address The address to lookup.
00081  * @note Formatting output should never be done within
00082  * a probe. Use at module exit time.
00083  */
00084 
00085 void _stp_print_symbol(const char *fmt, unsigned long address)
00086 {
00087         char *modname;
00088         const char *name;
00089         unsigned long offset, size;
00090         char namebuf[KSYM_NAME_LEN+1];
00091 
00092         name = _stp_kallsyms_lookup(address, &size, &offset, &modname, namebuf);
00093 
00094         if (!name)
00095                 _stp_print_buf("0x%lx", address);
00096         else {
00097           if (modname)
00098             _stp_print_buf("%s+%#lx/%#lx [%s]", name, offset,
00099                            size, modname);
00100           else
00101             _stp_print_buf("%s+%#lx/%#lx", name, offset, size);
00102         }
00103 }
00104 
00105 /** Get the current return address.
00106  * Call from kprobes (not jprobes).
00107  * @param regs The pt_regs saved by the kprobe.
00108  * @return The return address saved in esp or rsp.
00109  * @note i386 and x86_64 only.
00110  */
00111  
00112 unsigned long cur_ret_addr (struct pt_regs *regs)
00113 {
00114 #ifdef __x86_64__
00115   unsigned long *ra = (unsigned long *)regs->rsp;
00116 #else
00117   unsigned long *ra = (unsigned long *)regs->esp;
00118 #endif
00119   if (ra)
00120     return *ra;
00121   else
00122     return 0;
00123 }

Generated on Tue Mar 22 10:27:36 2005 for SystemTap.