Poor-mans ftrace with spatch
[akaros.git] / kern / src / kdebug.c
1 /* Copyright (c) 2011 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * Arch-independent kernel debugging */
6
7 #include <kdebug.h>
8 #include <kmalloc.h>
9 #include <string.h>
10 #include <assert.h>
11
12 struct symtab_entry gbl_symtab[1] __attribute__((weak)) = {{0, 0}};
13
14 /* Returns a null-terminated string with the function name for a given PC /
15  * instruction pointer.  kfree() the result. */
16 char *get_fn_name(uintptr_t pc)
17 {
18         struct symtab_entry *i, *prev = 0, *found = 0;
19         char *buf;
20         size_t name_len;
21         /* Table is in ascending order.  As soon as we get to an entry greater than
22          * us, we were in the previous one.  This is only true if we were given a
23          * good PC.  Random addresses will just find the previous symbol. */
24         for (i = &gbl_symtab[0]; i->name; i++) {
25                 if (i->addr > pc) {
26                         found = prev;
27                         break;
28                 }
29                 prev = i;
30         }
31         if (!found)
32                 return 0;
33         assert(found->name);
34         name_len = strlen(found->name) + 1;
35         buf = kmalloc(name_len, 0);
36         if (!buf)
37                 return 0;
38         strncpy(buf, found->name, name_len);
39         buf[name_len] = 0;
40         return buf;
41 }
42
43 uintptr_t get_symbol_addr(char *sym)
44 {
45         struct symtab_entry *i;
46         for (i = &gbl_symtab[0]; i->name; i++) {
47                 if (strcmp(i->name, sym) == 0)
48                         return i->addr;
49         }
50         return 0;
51 }
52
53 static const char *blacklist[] = {
54         "addnode",
55         "addqueue",
56         "allocroute",
57         "balancetree",
58         "calcd",
59         "freeroute",
60         "genrandom",    /* not noisy, just never returns */
61         "rangecompare",
62         "walkadd",
63 };
64
65 static bool is_blacklisted(const char *s)
66 {
67         for (int i = 0; i < ARRAY_SIZE(blacklist); i++) {
68                 if (!strcmp(blacklist[i], s))
69                         return TRUE;
70         }
71         return FALSE;
72 }
73
74 static int tab_depth = 0;
75
76 void __print_func_entry(const char *func, const char *file)
77 {
78         if (is_blacklisted(func))
79                 return;
80         for (int i = 0; i < tab_depth; i++)
81                 printk("\t");
82         printk("%s() in %s\n", func, file);
83         tab_depth++;
84 }
85
86 void __print_func_exit(const char *func, const char *file)
87 {
88         if (is_blacklisted(func))
89                 return;
90         tab_depth--;
91         for (int i = 0; i < tab_depth; i++)
92                 printk("\t");
93         printk("---- %s()\n", func);
94 }