tracing: infrastructure for supporting binary record
[linux-2.6] / kernel / trace / trace_output.c
1 /*
2  * trace_output.c
3  *
4  * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
5  *
6  */
7
8 #include <linux/module.h>
9 #include <linux/mutex.h>
10 #include <linux/ftrace.h>
11
12 #include "trace_output.h"
13
14 /* must be a power of 2 */
15 #define EVENT_HASHSIZE  128
16
17 static DEFINE_MUTEX(trace_event_mutex);
18 static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly;
19
20 static int next_event_type = __TRACE_LAST_TYPE + 1;
21
22 /**
23  * trace_seq_printf - sequence printing of trace information
24  * @s: trace sequence descriptor
25  * @fmt: printf format string
26  *
27  * The tracer may use either sequence operations or its own
28  * copy to user routines. To simplify formating of a trace
29  * trace_seq_printf is used to store strings into a special
30  * buffer (@s). Then the output may be either used by
31  * the sequencer or pulled into another buffer.
32  */
33 int
34 trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
35 {
36         int len = (PAGE_SIZE - 1) - s->len;
37         va_list ap;
38         int ret;
39
40         if (!len)
41                 return 0;
42
43         va_start(ap, fmt);
44         ret = vsnprintf(s->buffer + s->len, len, fmt, ap);
45         va_end(ap);
46
47         /* If we can't write it all, don't bother writing anything */
48         if (ret >= len)
49                 return 0;
50
51         s->len += ret;
52
53         return len;
54 }
55
56 static int
57 trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
58 {
59         int len = (PAGE_SIZE - 1) - s->len;
60         int ret;
61
62         if (!len)
63                 return 0;
64
65         ret = bstr_printf(s->buffer + s->len, len, fmt, binary);
66
67         /* If we can't write it all, don't bother writing anything */
68         if (ret >= len)
69                 return 0;
70
71         s->len += ret;
72
73         return len;
74 }
75
76 /**
77  * trace_seq_puts - trace sequence printing of simple string
78  * @s: trace sequence descriptor
79  * @str: simple string to record
80  *
81  * The tracer may use either the sequence operations or its own
82  * copy to user routines. This function records a simple string
83  * into a special buffer (@s) for later retrieval by a sequencer
84  * or other mechanism.
85  */
86 int trace_seq_puts(struct trace_seq *s, const char *str)
87 {
88         int len = strlen(str);
89
90         if (len > ((PAGE_SIZE - 1) - s->len))
91                 return 0;
92
93         memcpy(s->buffer + s->len, str, len);
94         s->len += len;
95
96         return len;
97 }
98
99 int trace_seq_putc(struct trace_seq *s, unsigned char c)
100 {
101         if (s->len >= (PAGE_SIZE - 1))
102                 return 0;
103
104         s->buffer[s->len++] = c;
105
106         return 1;
107 }
108
109 int trace_seq_putmem(struct trace_seq *s, void *mem, size_t len)
110 {
111         if (len > ((PAGE_SIZE - 1) - s->len))
112                 return 0;
113
114         memcpy(s->buffer + s->len, mem, len);
115         s->len += len;
116
117         return len;
118 }
119
120 int trace_seq_putmem_hex(struct trace_seq *s, void *mem, size_t len)
121 {
122         unsigned char hex[HEX_CHARS];
123         unsigned char *data = mem;
124         int i, j;
125
126 #ifdef __BIG_ENDIAN
127         for (i = 0, j = 0; i < len; i++) {
128 #else
129         for (i = len-1, j = 0; i >= 0; i--) {
130 #endif
131                 hex[j++] = hex_asc_hi(data[i]);
132                 hex[j++] = hex_asc_lo(data[i]);
133         }
134         hex[j++] = ' ';
135
136         return trace_seq_putmem(s, hex, j);
137 }
138
139 int trace_seq_path(struct trace_seq *s, struct path *path)
140 {
141         unsigned char *p;
142
143         if (s->len >= (PAGE_SIZE - 1))
144                 return 0;
145         p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
146         if (!IS_ERR(p)) {
147                 p = mangle_path(s->buffer + s->len, p, "\n");
148                 if (p) {
149                         s->len = p - s->buffer;
150                         return 1;
151                 }
152         } else {
153                 s->buffer[s->len++] = '?';
154                 return 1;
155         }
156
157         return 0;
158 }
159
160 #ifdef CONFIG_KRETPROBES
161 static inline const char *kretprobed(const char *name)
162 {
163         static const char tramp_name[] = "kretprobe_trampoline";
164         int size = sizeof(tramp_name);
165
166         if (strncmp(tramp_name, name, size) == 0)
167                 return "[unknown/kretprobe'd]";
168         return name;
169 }
170 #else
171 static inline const char *kretprobed(const char *name)
172 {
173         return name;
174 }
175 #endif /* CONFIG_KRETPROBES */
176
177 static int
178 seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address)
179 {
180 #ifdef CONFIG_KALLSYMS
181         char str[KSYM_SYMBOL_LEN];
182         const char *name;
183
184         kallsyms_lookup(address, NULL, NULL, NULL, str);
185
186         name = kretprobed(str);
187
188         return trace_seq_printf(s, fmt, name);
189 #endif
190         return 1;
191 }
192
193 static int
194 seq_print_sym_offset(struct trace_seq *s, const char *fmt,
195                      unsigned long address)
196 {
197 #ifdef CONFIG_KALLSYMS
198         char str[KSYM_SYMBOL_LEN];
199         const char *name;
200
201         sprint_symbol(str, address);
202         name = kretprobed(str);
203
204         return trace_seq_printf(s, fmt, name);
205 #endif
206         return 1;
207 }
208
209 #ifndef CONFIG_64BIT
210 # define IP_FMT "%08lx"
211 #else
212 # define IP_FMT "%016lx"
213 #endif
214
215 int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
216                       unsigned long ip, unsigned long sym_flags)
217 {
218         struct file *file = NULL;
219         unsigned long vmstart = 0;
220         int ret = 1;
221
222         if (mm) {
223                 const struct vm_area_struct *vma;
224
225                 down_read(&mm->mmap_sem);
226                 vma = find_vma(mm, ip);
227                 if (vma) {
228                         file = vma->vm_file;
229                         vmstart = vma->vm_start;
230                 }
231                 if (file) {
232                         ret = trace_seq_path(s, &file->f_path);
233                         if (ret)
234                                 ret = trace_seq_printf(s, "[+0x%lx]",
235                                                        ip - vmstart);
236                 }
237                 up_read(&mm->mmap_sem);
238         }
239         if (ret && ((sym_flags & TRACE_ITER_SYM_ADDR) || !file))
240                 ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
241         return ret;
242 }
243
244 int
245 seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s,
246                       unsigned long sym_flags)
247 {
248         struct mm_struct *mm = NULL;
249         int ret = 1;
250         unsigned int i;
251
252         if (trace_flags & TRACE_ITER_SYM_USEROBJ) {
253                 struct task_struct *task;
254                 /*
255                  * we do the lookup on the thread group leader,
256                  * since individual threads might have already quit!
257                  */
258                 rcu_read_lock();
259                 task = find_task_by_vpid(entry->ent.tgid);
260                 if (task)
261                         mm = get_task_mm(task);
262                 rcu_read_unlock();
263         }
264
265         for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
266                 unsigned long ip = entry->caller[i];
267
268                 if (ip == ULONG_MAX || !ret)
269                         break;
270                 if (i && ret)
271                         ret = trace_seq_puts(s, " <- ");
272                 if (!ip) {
273                         if (ret)
274                                 ret = trace_seq_puts(s, "??");
275                         continue;
276                 }
277                 if (!ret)
278                         break;
279                 if (ret)
280                         ret = seq_print_user_ip(s, mm, ip, sym_flags);
281         }
282
283         if (mm)
284                 mmput(mm);
285         return ret;
286 }
287
288 int
289 seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
290 {
291         int ret;
292
293         if (!ip)
294                 return trace_seq_printf(s, "0");
295
296         if (sym_flags & TRACE_ITER_SYM_OFFSET)
297                 ret = seq_print_sym_offset(s, "%s", ip);
298         else
299                 ret = seq_print_sym_short(s, "%s", ip);
300
301         if (!ret)
302                 return 0;
303
304         if (sym_flags & TRACE_ITER_SYM_ADDR)
305                 ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
306         return ret;
307 }
308
309 static int
310 lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
311 {
312         int hardirq, softirq;
313         char *comm;
314
315         comm = trace_find_cmdline(entry->pid);
316         hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
317         softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
318
319         if (!trace_seq_printf(s, "%8.8s-%-5d %3d%c%c%c",
320                               comm, entry->pid, cpu,
321                               (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
322                                 (entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ?
323                                   'X' : '.',
324                               (entry->flags & TRACE_FLAG_NEED_RESCHED) ?
325                                 'N' : '.',
326                               (hardirq && softirq) ? 'H' :
327                                 hardirq ? 'h' : softirq ? 's' : '.'))
328                 return 0;
329
330         if (entry->preempt_count)
331                 return trace_seq_printf(s, "%x", entry->preempt_count);
332         return trace_seq_puts(s, ".");
333 }
334
335 static unsigned long preempt_mark_thresh = 100;
336
337 static int
338 lat_print_timestamp(struct trace_seq *s, u64 abs_usecs,
339                     unsigned long rel_usecs)
340 {
341         return trace_seq_printf(s, " %4lldus%c: ", abs_usecs,
342                                 rel_usecs > preempt_mark_thresh ? '!' :
343                                   rel_usecs > 1 ? '+' : ' ');
344 }
345
346 int trace_print_context(struct trace_iterator *iter)
347 {
348         struct trace_seq *s = &iter->seq;
349         struct trace_entry *entry = iter->ent;
350         char *comm = trace_find_cmdline(entry->pid);
351         unsigned long long t = ns2usecs(iter->ts);
352         unsigned long usec_rem = do_div(t, USEC_PER_SEC);
353         unsigned long secs = (unsigned long)t;
354
355         return trace_seq_printf(s, "%16s-%-5d [%03d] %5lu.%06lu: ",
356                                 comm, entry->pid, iter->cpu, secs, usec_rem);
357 }
358
359 int trace_print_lat_context(struct trace_iterator *iter)
360 {
361         u64 next_ts;
362         int ret;
363         struct trace_seq *s = &iter->seq;
364         struct trace_entry *entry = iter->ent,
365                            *next_entry = trace_find_next_entry(iter, NULL,
366                                                                &next_ts);
367         unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE);
368         unsigned long abs_usecs = ns2usecs(iter->ts - iter->tr->time_start);
369         unsigned long rel_usecs;
370
371         if (!next_entry)
372                 next_ts = iter->ts;
373         rel_usecs = ns2usecs(next_ts - iter->ts);
374
375         if (verbose) {
376                 char *comm = trace_find_cmdline(entry->pid);
377                 ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08lx]"
378                                        " %ld.%03ldms (+%ld.%03ldms): ", comm,
379                                        entry->pid, iter->cpu, entry->flags,
380                                        entry->preempt_count, iter->idx,
381                                        ns2usecs(iter->ts),
382                                        abs_usecs / USEC_PER_MSEC,
383                                        abs_usecs % USEC_PER_MSEC,
384                                        rel_usecs / USEC_PER_MSEC,
385                                        rel_usecs % USEC_PER_MSEC);
386         } else {
387                 ret = lat_print_generic(s, entry, iter->cpu);
388                 if (ret)
389                         ret = lat_print_timestamp(s, abs_usecs, rel_usecs);
390         }
391
392         return ret;
393 }
394
395 static const char state_to_char[] = TASK_STATE_TO_CHAR_STR;
396
397 static int task_state_char(unsigned long state)
398 {
399         int bit = state ? __ffs(state) + 1 : 0;
400
401         return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?';
402 }
403
404 /**
405  * ftrace_find_event - find a registered event
406  * @type: the type of event to look for
407  *
408  * Returns an event of type @type otherwise NULL
409  */
410 struct trace_event *ftrace_find_event(int type)
411 {
412         struct trace_event *event;
413         struct hlist_node *n;
414         unsigned key;
415
416         key = type & (EVENT_HASHSIZE - 1);
417
418         hlist_for_each_entry_rcu(event, n, &event_hash[key], node) {
419                 if (event->type == type)
420                         return event;
421         }
422
423         return NULL;
424 }
425
426 /**
427  * register_ftrace_event - register output for an event type
428  * @event: the event type to register
429  *
430  * Event types are stored in a hash and this hash is used to
431  * find a way to print an event. If the @event->type is set
432  * then it will use that type, otherwise it will assign a
433  * type to use.
434  *
435  * If you assign your own type, please make sure it is added
436  * to the trace_type enum in trace.h, to avoid collisions
437  * with the dynamic types.
438  *
439  * Returns the event type number or zero on error.
440  */
441 int register_ftrace_event(struct trace_event *event)
442 {
443         unsigned key;
444         int ret = 0;
445
446         mutex_lock(&trace_event_mutex);
447
448         if (!event->type)
449                 event->type = next_event_type++;
450         else if (event->type > __TRACE_LAST_TYPE) {
451                 printk(KERN_WARNING "Need to add type to trace.h\n");
452                 WARN_ON(1);
453         }
454
455         if (ftrace_find_event(event->type))
456                 goto out;
457
458         if (event->trace == NULL)
459                 event->trace = trace_nop_print;
460         if (event->raw == NULL)
461                 event->raw = trace_nop_print;
462         if (event->hex == NULL)
463                 event->hex = trace_nop_print;
464         if (event->binary == NULL)
465                 event->binary = trace_nop_print;
466
467         key = event->type & (EVENT_HASHSIZE - 1);
468
469         hlist_add_head_rcu(&event->node, &event_hash[key]);
470
471         ret = event->type;
472  out:
473         mutex_unlock(&trace_event_mutex);
474
475         return ret;
476 }
477
478 /**
479  * unregister_ftrace_event - remove a no longer used event
480  * @event: the event to remove
481  */
482 int unregister_ftrace_event(struct trace_event *event)
483 {
484         mutex_lock(&trace_event_mutex);
485         hlist_del(&event->node);
486         mutex_unlock(&trace_event_mutex);
487
488         return 0;
489 }
490
491 /*
492  * Standard events
493  */
494
495 enum print_line_t trace_nop_print(struct trace_iterator *iter, int flags)
496 {
497         return TRACE_TYPE_HANDLED;
498 }
499
500 /* TRACE_FN */
501 static enum print_line_t trace_fn_trace(struct trace_iterator *iter, int flags)
502 {
503         struct ftrace_entry *field;
504         struct trace_seq *s = &iter->seq;
505
506         trace_assign_type(field, iter->ent);
507
508         if (!seq_print_ip_sym(s, field->ip, flags))
509                 goto partial;
510
511         if ((flags & TRACE_ITER_PRINT_PARENT) && field->parent_ip) {
512                 if (!trace_seq_printf(s, " <-"))
513                         goto partial;
514                 if (!seq_print_ip_sym(s,
515                                       field->parent_ip,
516                                       flags))
517                         goto partial;
518         }
519         if (!trace_seq_printf(s, "\n"))
520                 goto partial;
521
522         return TRACE_TYPE_HANDLED;
523
524  partial:
525         return TRACE_TYPE_PARTIAL_LINE;
526 }
527
528 static enum print_line_t trace_fn_raw(struct trace_iterator *iter, int flags)
529 {
530         struct ftrace_entry *field;
531
532         trace_assign_type(field, iter->ent);
533
534         if (!trace_seq_printf(&iter->seq, "%lx %lx\n",
535                               field->ip,
536                               field->parent_ip))
537                 return TRACE_TYPE_PARTIAL_LINE;
538
539         return TRACE_TYPE_HANDLED;
540 }
541
542 static enum print_line_t trace_fn_hex(struct trace_iterator *iter, int flags)
543 {
544         struct ftrace_entry *field;
545         struct trace_seq *s = &iter->seq;
546
547         trace_assign_type(field, iter->ent);
548
549         SEQ_PUT_HEX_FIELD_RET(s, field->ip);
550         SEQ_PUT_HEX_FIELD_RET(s, field->parent_ip);
551
552         return TRACE_TYPE_HANDLED;
553 }
554
555 static enum print_line_t trace_fn_bin(struct trace_iterator *iter, int flags)
556 {
557         struct ftrace_entry *field;
558         struct trace_seq *s = &iter->seq;
559
560         trace_assign_type(field, iter->ent);
561
562         SEQ_PUT_FIELD_RET(s, field->ip);
563         SEQ_PUT_FIELD_RET(s, field->parent_ip);
564
565         return TRACE_TYPE_HANDLED;
566 }
567
568 static struct trace_event trace_fn_event = {
569         .type           = TRACE_FN,
570         .trace          = trace_fn_trace,
571         .raw            = trace_fn_raw,
572         .hex            = trace_fn_hex,
573         .binary         = trace_fn_bin,
574 };
575
576 /* TRACE_CTX an TRACE_WAKE */
577 static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter,
578                                              char *delim)
579 {
580         struct ctx_switch_entry *field;
581         char *comm;
582         int S, T;
583
584         trace_assign_type(field, iter->ent);
585
586         T = task_state_char(field->next_state);
587         S = task_state_char(field->prev_state);
588         comm = trace_find_cmdline(field->next_pid);
589         if (!trace_seq_printf(&iter->seq,
590                               " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n",
591                               field->prev_pid,
592                               field->prev_prio,
593                               S, delim,
594                               field->next_cpu,
595                               field->next_pid,
596                               field->next_prio,
597                               T, comm))
598                 return TRACE_TYPE_PARTIAL_LINE;
599
600         return TRACE_TYPE_HANDLED;
601 }
602
603 static enum print_line_t trace_ctx_print(struct trace_iterator *iter, int flags)
604 {
605         return trace_ctxwake_print(iter, "==>");
606 }
607
608 static enum print_line_t trace_wake_print(struct trace_iterator *iter,
609                                           int flags)
610 {
611         return trace_ctxwake_print(iter, "  +");
612 }
613
614 static int trace_ctxwake_raw(struct trace_iterator *iter, char S)
615 {
616         struct ctx_switch_entry *field;
617         int T;
618
619         trace_assign_type(field, iter->ent);
620
621         if (!S)
622                 task_state_char(field->prev_state);
623         T = task_state_char(field->next_state);
624         if (!trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n",
625                               field->prev_pid,
626                               field->prev_prio,
627                               S,
628                               field->next_cpu,
629                               field->next_pid,
630                               field->next_prio,
631                               T))
632                 return TRACE_TYPE_PARTIAL_LINE;
633
634         return TRACE_TYPE_HANDLED;
635 }
636
637 static enum print_line_t trace_ctx_raw(struct trace_iterator *iter, int flags)
638 {
639         return trace_ctxwake_raw(iter, 0);
640 }
641
642 static enum print_line_t trace_wake_raw(struct trace_iterator *iter, int flags)
643 {
644         return trace_ctxwake_raw(iter, '+');
645 }
646
647
648 static int trace_ctxwake_hex(struct trace_iterator *iter, char S)
649 {
650         struct ctx_switch_entry *field;
651         struct trace_seq *s = &iter->seq;
652         int T;
653
654         trace_assign_type(field, iter->ent);
655
656         if (!S)
657                 task_state_char(field->prev_state);
658         T = task_state_char(field->next_state);
659
660         SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid);
661         SEQ_PUT_HEX_FIELD_RET(s, field->prev_prio);
662         SEQ_PUT_HEX_FIELD_RET(s, S);
663         SEQ_PUT_HEX_FIELD_RET(s, field->next_cpu);
664         SEQ_PUT_HEX_FIELD_RET(s, field->next_pid);
665         SEQ_PUT_HEX_FIELD_RET(s, field->next_prio);
666         SEQ_PUT_HEX_FIELD_RET(s, T);
667
668         return TRACE_TYPE_HANDLED;
669 }
670
671 static enum print_line_t trace_ctx_hex(struct trace_iterator *iter, int flags)
672 {
673         return trace_ctxwake_hex(iter, 0);
674 }
675
676 static enum print_line_t trace_wake_hex(struct trace_iterator *iter, int flags)
677 {
678         return trace_ctxwake_hex(iter, '+');
679 }
680
681 static enum print_line_t trace_ctxwake_bin(struct trace_iterator *iter,
682                                            int flags)
683 {
684         struct ctx_switch_entry *field;
685         struct trace_seq *s = &iter->seq;
686
687         trace_assign_type(field, iter->ent);
688
689         SEQ_PUT_FIELD_RET(s, field->prev_pid);
690         SEQ_PUT_FIELD_RET(s, field->prev_prio);
691         SEQ_PUT_FIELD_RET(s, field->prev_state);
692         SEQ_PUT_FIELD_RET(s, field->next_pid);
693         SEQ_PUT_FIELD_RET(s, field->next_prio);
694         SEQ_PUT_FIELD_RET(s, field->next_state);
695
696         return TRACE_TYPE_HANDLED;
697 }
698
699 static struct trace_event trace_ctx_event = {
700         .type           = TRACE_CTX,
701         .trace          = trace_ctx_print,
702         .raw            = trace_ctx_raw,
703         .hex            = trace_ctx_hex,
704         .binary         = trace_ctxwake_bin,
705 };
706
707 static struct trace_event trace_wake_event = {
708         .type           = TRACE_WAKE,
709         .trace          = trace_wake_print,
710         .raw            = trace_wake_raw,
711         .hex            = trace_wake_hex,
712         .binary         = trace_ctxwake_bin,
713 };
714
715 /* TRACE_SPECIAL */
716 static enum print_line_t trace_special_print(struct trace_iterator *iter,
717                                              int flags)
718 {
719         struct special_entry *field;
720
721         trace_assign_type(field, iter->ent);
722
723         if (!trace_seq_printf(&iter->seq, "# %ld %ld %ld\n",
724                               field->arg1,
725                               field->arg2,
726                               field->arg3))
727                 return TRACE_TYPE_PARTIAL_LINE;
728
729         return TRACE_TYPE_HANDLED;
730 }
731
732 static enum print_line_t trace_special_hex(struct trace_iterator *iter,
733                                            int flags)
734 {
735         struct special_entry *field;
736         struct trace_seq *s = &iter->seq;
737
738         trace_assign_type(field, iter->ent);
739
740         SEQ_PUT_HEX_FIELD_RET(s, field->arg1);
741         SEQ_PUT_HEX_FIELD_RET(s, field->arg2);
742         SEQ_PUT_HEX_FIELD_RET(s, field->arg3);
743
744         return TRACE_TYPE_HANDLED;
745 }
746
747 static enum print_line_t trace_special_bin(struct trace_iterator *iter,
748                                            int flags)
749 {
750         struct special_entry *field;
751         struct trace_seq *s = &iter->seq;
752
753         trace_assign_type(field, iter->ent);
754
755         SEQ_PUT_FIELD_RET(s, field->arg1);
756         SEQ_PUT_FIELD_RET(s, field->arg2);
757         SEQ_PUT_FIELD_RET(s, field->arg3);
758
759         return TRACE_TYPE_HANDLED;
760 }
761
762 static struct trace_event trace_special_event = {
763         .type           = TRACE_SPECIAL,
764         .trace          = trace_special_print,
765         .raw            = trace_special_print,
766         .hex            = trace_special_hex,
767         .binary         = trace_special_bin,
768 };
769
770 /* TRACE_STACK */
771
772 static enum print_line_t trace_stack_print(struct trace_iterator *iter,
773                                            int flags)
774 {
775         struct stack_entry *field;
776         struct trace_seq *s = &iter->seq;
777         int i;
778
779         trace_assign_type(field, iter->ent);
780
781         for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
782                 if (i) {
783                         if (!trace_seq_puts(s, " <= "))
784                                 goto partial;
785
786                         if (!seq_print_ip_sym(s, field->caller[i], flags))
787                                 goto partial;
788                 }
789                 if (!trace_seq_puts(s, "\n"))
790                         goto partial;
791         }
792
793         return TRACE_TYPE_HANDLED;
794
795  partial:
796         return TRACE_TYPE_PARTIAL_LINE;
797 }
798
799 static struct trace_event trace_stack_event = {
800         .type           = TRACE_STACK,
801         .trace          = trace_stack_print,
802         .raw            = trace_special_print,
803         .hex            = trace_special_hex,
804         .binary         = trace_special_bin,
805 };
806
807 /* TRACE_USER_STACK */
808 static enum print_line_t trace_user_stack_print(struct trace_iterator *iter,
809                                                 int flags)
810 {
811         struct userstack_entry *field;
812         struct trace_seq *s = &iter->seq;
813
814         trace_assign_type(field, iter->ent);
815
816         if (!seq_print_userip_objs(field, s, flags))
817                 goto partial;
818
819         if (!trace_seq_putc(s, '\n'))
820                 goto partial;
821
822         return TRACE_TYPE_HANDLED;
823
824  partial:
825         return TRACE_TYPE_PARTIAL_LINE;
826 }
827
828 static struct trace_event trace_user_stack_event = {
829         .type           = TRACE_USER_STACK,
830         .trace          = trace_user_stack_print,
831         .raw            = trace_special_print,
832         .hex            = trace_special_hex,
833         .binary         = trace_special_bin,
834 };
835
836 /* TRACE_PRINT */
837 static enum print_line_t trace_print_print(struct trace_iterator *iter,
838                                            int flags)
839 {
840         struct print_entry *field;
841         struct trace_seq *s = &iter->seq;
842
843         trace_assign_type(field, iter->ent);
844
845         if (!seq_print_ip_sym(s, field->ip, flags))
846                 goto partial;
847
848         if (!trace_seq_printf(s, ": %s", field->buf))
849                 goto partial;
850
851         return TRACE_TYPE_HANDLED;
852
853  partial:
854         return TRACE_TYPE_PARTIAL_LINE;
855 }
856
857 static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags)
858 {
859         struct print_entry *field;
860
861         trace_assign_type(field, iter->ent);
862
863         if (!trace_seq_printf(&iter->seq, "# %lx %s", field->ip, field->buf))
864                 goto partial;
865
866         return TRACE_TYPE_HANDLED;
867
868  partial:
869         return TRACE_TYPE_PARTIAL_LINE;
870 }
871
872 static struct trace_event trace_print_event = {
873         .type           = TRACE_PRINT,
874         .trace          = trace_print_print,
875         .raw            = trace_print_raw,
876 };
877
878 /* TRACE_BPRINTK */
879 static enum print_line_t
880 trace_bprintk_print(struct trace_iterator *iter, int flags)
881 {
882         struct trace_entry *entry = iter->ent;
883         struct trace_seq *s = &iter->seq;
884         struct bprintk_entry *field;
885
886         trace_assign_type(field, entry);
887
888         if (!seq_print_ip_sym(s, field->ip, flags))
889                 goto partial;
890
891         if (!trace_seq_puts(s, ": "))
892                 goto partial;
893
894         if (!trace_seq_bprintf(s, field->fmt, field->buf))
895                 goto partial;
896
897         return TRACE_TYPE_HANDLED;
898
899  partial:
900         return TRACE_TYPE_PARTIAL_LINE;
901 }
902
903 static enum print_line_t
904 trace_bprintk_raw(struct trace_iterator *iter, int flags)
905 {
906         struct trace_entry *entry = iter->ent;
907         struct trace_seq *s = &iter->seq;
908         struct bprintk_entry *field;
909
910         trace_assign_type(field, entry);
911
912         if (!trace_seq_printf(s, ": %lx : ", field->ip))
913                 goto partial;
914
915         if (!trace_seq_bprintf(s, field->fmt, field->buf))
916                 goto partial;
917
918         return TRACE_TYPE_HANDLED;
919
920  partial:
921         return TRACE_TYPE_PARTIAL_LINE;
922 }
923
924 static struct trace_event trace_bprintk_event = {
925         .type           = TRACE_BPRINTK,
926         .trace          = trace_bprintk_print,
927         .raw            = trace_bprintk_raw,
928         .hex            = trace_nop_print,
929         .binary         = trace_nop_print,
930 };
931
932 static struct trace_event *events[] __initdata = {
933         &trace_fn_event,
934         &trace_ctx_event,
935         &trace_wake_event,
936         &trace_special_event,
937         &trace_stack_event,
938         &trace_user_stack_event,
939         &trace_print_event,
940         &trace_bprintk_event,
941         NULL
942 };
943
944 __init static int init_events(void)
945 {
946         struct trace_event *event;
947         int i, ret;
948
949         for (i = 0; events[i]; i++) {
950                 event = events[i];
951
952                 ret = register_ftrace_event(event);
953                 if (!ret) {
954                         printk(KERN_WARNING "event %d failed to register\n",
955                                event->type);
956                         WARN_ON_ONCE(1);
957                 }
958         }
959
960         return 0;
961 }
962 device_initcall(init_events);