aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-11-24 16:16:07 -0500
committerSteven Rostedt <rostedt@goodmis.org>2009-11-24 16:16:07 -0500
commit0350519c5c8c0389fbec716fcc7c0ffd1dae05dd (patch)
tree3361b13d89f138140081f728faf21e6cfabdbcd8
parentb1448ef5b7dfe05230123941f28f8bde7f9ea162 (diff)
Separate out function parsing from library
The mapping of addresses to their functions is separated out from the library. The reading of the data belongs to the application, but we add a way to register a mapping between function and address with pevert_register_function Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--parse-events.c134
-rw-r--r--parse-events.h1
-rw-r--r--trace-util.c32
3 files changed, 99 insertions, 68 deletions
diff --git a/parse-events.c b/parse-events.c
index c03dc08..ce35f83 100644
--- a/parse-events.c
+++ b/parse-events.c
@@ -88,7 +88,7 @@ static struct cmdline_list {
88 struct cmdline_list *next; 88 struct cmdline_list *next;
89 char *comm; 89 char *comm;
90 int pid; 90 int pid;
91} *cmdlist = NULL; 91} *cmdlist;
92 92
93static int cmdline_init(void) 93static int cmdline_init(void)
94{ 94{
@@ -152,9 +152,16 @@ static struct func_map {
152 unsigned long long addr; 152 unsigned long long addr;
153 char *func; 153 char *func;
154 char *mod; 154 char *mod;
155} *func_list; 155} *func_map;
156static unsigned int func_count; 156static unsigned int func_count;
157 157
158static struct func_list {
159 struct func_list *next;
160 unsigned long long addr;
161 char *func;
162 char *mod;
163} *funclist;
164
158static int func_cmp(const void *a, const void *b) 165static int func_cmp(const void *a, const void *b)
159{ 166{
160 const struct func_map *fa = a; 167 const struct func_map *fa = a;
@@ -168,67 +175,6 @@ static int func_cmp(const void *a, const void *b)
168 return 0; 175 return 0;
169} 176}
170 177
171void parse_proc_kallsyms(char *file, unsigned int size __unused)
172{
173 struct func_list {
174 struct func_list *next;
175 unsigned long long addr;
176 char *func;
177 char *mod;
178 } *list = NULL, *item;
179 char *line;
180 char *next = NULL;
181 char *addr_str;
182 char ch;
183 int ret;
184 int i;
185
186 line = strtok_r(file, "\n", &next);
187 while (line) {
188 item = malloc_or_die(sizeof(*item));
189 item->mod = NULL;
190 ret = sscanf(line, "%as %c %as\t[%as",
191 (float *)(void *)&addr_str, /* workaround gcc warning */
192 &ch,
193 (float *)(void *)&item->func,
194 (float *)(void *)&item->mod);
195 item->addr = strtoull(addr_str, NULL, 16);
196 free(addr_str);
197
198 /* truncate the extra ']' */
199 if (item->mod)
200 item->mod[strlen(item->mod) - 1] = 0;
201
202
203 item->next = list;
204 list = item;
205 line = strtok_r(NULL, "\n", &next);
206 func_count++;
207 }
208
209 func_list = malloc_or_die(sizeof(*func_list) * func_count + 1);
210
211 i = 0;
212 while (list) {
213 func_list[i].func = list->func;
214 func_list[i].addr = list->addr;
215 func_list[i].mod = list->mod;
216 i++;
217 item = list;
218 list = list->next;
219 free(item);
220 }
221
222 qsort(func_list, func_count, sizeof(*func_list), func_cmp);
223
224 /*
225 * Add a special record at the end.
226 */
227 func_list[func_count].func = NULL;
228 func_list[func_count].addr = 0;
229 func_list[func_count].mod = NULL;
230}
231
232/* 178/*
233 * We are searching for a record in between, not an exact 179 * We are searching for a record in between, not an exact
234 * match. 180 * match.
@@ -250,29 +196,81 @@ static int func_bcmp(const void *a, const void *b)
250 return 1; 196 return 1;
251} 197}
252 198
199static int func_map_init(void)
200{
201 struct func_list *item;
202 int i;
203
204 func_map = malloc_or_die(sizeof(*func_map) * func_count + 1);
205
206 i = 0;
207 while (funclist) {
208 func_map[i].func = funclist->func;
209 func_map[i].addr = funclist->addr;
210 func_map[i].mod = funclist->mod;
211 i++;
212 item = funclist;
213 funclist = funclist->next;
214 free(item);
215 }
216
217 qsort(func_map, func_count, sizeof(*func_map), func_cmp);
218
219 /*
220 * Add a special record at the end.
221 */
222 func_map[func_count].func = NULL;
223 func_map[func_count].addr = 0;
224 func_map[func_count].mod = NULL;
225
226 return 0;
227}
228
253static struct func_map *find_func(unsigned long long addr) 229static struct func_map *find_func(unsigned long long addr)
254{ 230{
255 struct func_map *func; 231 struct func_map *func;
256 struct func_map key; 232 struct func_map key;
257 233
234 if (!func_map)
235 func_map_init();
236
258 key.addr = addr; 237 key.addr = addr;
259 238
260 func = bsearch(&key, func_list, func_count, sizeof(*func_list), 239 func = bsearch(&key, func_map, func_count, sizeof(*func_map),
261 func_bcmp); 240 func_bcmp);
262 241
263 return func; 242 return func;
264} 243}
265 244
245int pevent_register_function(char *func, unsigned long long addr,
246 char *mod)
247{
248 struct func_list *item;
249
250 item = malloc_or_die(sizeof(*item));
251
252 item->next = funclist;
253 item->func = func;
254 item->mod = mod;
255 item->addr = addr;
256
257 funclist = item;
258
259 func_count++;
260
261 return 0;
262}
263
266void print_funcs(void) 264void print_funcs(void)
267{ 265{
268 int i; 266 int i;
269 267
270 for (i = 0; i < (int)func_count; i++) { 268 for (i = 0; i < (int)func_count; i++) {
271 printf("%016llx %s", 269 printf("%016llx %s",
272 func_list[i].addr, 270 func_map[i].addr,
273 func_list[i].func); 271 func_map[i].func);
274 if (func_list[i].mod) 272 if (func_map[i].mod)
275 printf(" [%s]\n", func_list[i].mod); 273 printf(" [%s]\n", func_map[i].mod);
276 else 274 else
277 printf("\n"); 275 printf("\n");
278 } 276 }
diff --git a/parse-events.h b/parse-events.h
index 41a57cc..98c21c3 100644
--- a/parse-events.h
+++ b/parse-events.h
@@ -307,5 +307,6 @@ enum trace_flag_type {
307}; 307};
308 308
309int pevent_register_comm(char *comm, int pid); 309int pevent_register_comm(char *comm, int pid);
310int pevent_register_function(char *name, unsigned long long addr, char *mod);
310 311
311#endif /* _PARSE_EVENTS_H */ 312#endif /* _PARSE_EVENTS_H */
diff --git a/trace-util.c b/trace-util.c
index 563a75e..2fe5ff6 100644
--- a/trace-util.c
+++ b/trace-util.c
@@ -22,3 +22,35 @@ void parse_cmdlines(char *file, int size __unused)
22 line = strtok_r(NULL, "\n", &next); 22 line = strtok_r(NULL, "\n", &next);
23 } 23 }
24} 24}
25
26void parse_proc_kallsyms(char *file, unsigned int size __unused)
27{
28 unsigned long long addr;
29 char *func;
30 char *line;
31 char *next = NULL;
32 char *addr_str;
33 char *mod;
34 char ch;
35 int ret;
36
37 line = strtok_r(file, "\n", &next);
38 while (line) {
39 mod = NULL;
40 ret = sscanf(line, "%as %c %as\t[%as",
41 (float *)(void *)&addr_str, /* workaround gcc warning */
42 &ch,
43 (float *)(void *)&func,
44 (float *)(void *)&mod);
45 addr = strtoull(addr_str, NULL, 16);
46 free(addr_str);
47
48 /* truncate the extra ']' */
49 if (mod)
50 mod[strlen(mod) - 1] = 0;
51
52 pevent_register_function(func, addr, mod);
53
54 line = strtok_r(NULL, "\n", &next);
55 }
56}