Rename so-info to bin-info
[babeltrace.git] / lib / debuginfo.c
CommitLineData
c40a57e5
AB
1/*
2 * Babeltrace - Debug Information State Tracker
3 *
4 * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
5 * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
6 * Copyright (c) 2015 Antoine Busque <abusque@efficios.com>
ff9ce920 7 * Copyright (c) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
c40a57e5
AB
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 */
27
28#include <assert.h>
29#include <glib.h>
30#include <babeltrace/types.h>
31#include <babeltrace/ctf-ir/metadata.h>
32#include <babeltrace/debuginfo.h>
d5ddf820 33#include <babeltrace/bin-info.h>
ff9ce920 34#include <babeltrace/babeltrace-internal.h>
55cd033d 35#include <babeltrace/utils.h>
c40a57e5
AB
36
37struct proc_debug_info_sources {
38 /*
d5ddf820 39 * Hash table: base address (pointer to uint64_t) to bin info; owned by
c40a57e5
AB
40 * proc_debug_info_sources.
41 */
d5ddf820 42 GHashTable *baddr_to_bin_info;
c40a57e5
AB
43
44 /*
47857613
JG
45 * Hash table: IP (pointer to uint64_t) to (struct debug_info_source *);
46 * owned by proc_debug_info_sources.
c40a57e5
AB
47 */
48 GHashTable *ip_to_debug_info_src;
49};
50
51struct debug_info {
52 /*
47857613
JG
53 * Hash table of VPIDs (pointer to int64_t) to
54 * (struct ctf_proc_debug_infos*); owned by debug_info.
c40a57e5
AB
55 */
56 GHashTable *vpid_to_proc_dbg_info_src;
9c713367 57 GQuark q_statedump_bin_info;
c40a57e5
AB
58 GQuark q_statedump_debug_link;
59 GQuark q_statedump_build_id;
60 GQuark q_statedump_start;
61 GQuark q_dl_open;
62};
63
64static
65int debug_info_init(struct debug_info *info)
66{
9c713367
AB
67 info->q_statedump_bin_info = g_quark_from_string(
68 "lttng_ust_statedump:bin_info");
c40a57e5
AB
69 info->q_statedump_debug_link = g_quark_from_string(
70 "lttng_ust_statedump:debug_link)");
71 info->q_statedump_build_id = g_quark_from_string(
72 "lttng_ust_statedump:build_id");
73 info->q_statedump_start = g_quark_from_string(
74 "lttng_ust_statedump:start");
75 info->q_dl_open = g_quark_from_string("lttng_ust_dl:dlopen");
76
d5ddf820 77 return bin_info_init();
c40a57e5
AB
78}
79
80static
81void debug_info_source_destroy(struct debug_info_source *debug_info_src)
82{
83 if (!debug_info_src) {
84 return;
85 }
86
87 free(debug_info_src->func);
a7a607cf
JG
88 free(debug_info_src->src_path);
89 free(debug_info_src->bin_path);
36ae9941 90 free(debug_info_src->bin_loc);
c40a57e5
AB
91 g_free(debug_info_src);
92}
93
94static
d5ddf820 95struct debug_info_source *debug_info_source_create_from_bin(struct bin_info *bin,
c40a57e5
AB
96 uint64_t ip)
97{
98 int ret;
99 struct debug_info_source *debug_info_src = NULL;
100 struct source_location *src_loc = NULL;
101
102 debug_info_src = g_new0(struct debug_info_source, 1);
103
104 if (!debug_info_src) {
105 goto end;
106 }
107
108 /* Lookup function name */
d5ddf820 109 ret = bin_info_lookup_function_name(bin, ip, &debug_info_src->func);
c40a57e5
AB
110 if (ret) {
111 goto error;
112 }
113
114 /* Can't retrieve src_loc from ELF only, skip it */
d5ddf820 115 if (!bin->is_elf_only) {
44148130 116 /* Lookup source location */
d5ddf820 117 ret = bin_info_lookup_source_location(bin, ip, &src_loc);
44148130
JG
118 if (ret) {
119 goto error;
120 }
c40a57e5
AB
121 }
122
123 if (src_loc) {
124 debug_info_src->line_no = src_loc->line_no;
125
126 if (src_loc->filename) {
a7a607cf
JG
127 debug_info_src->src_path = strdup(src_loc->filename);
128 if (!debug_info_src->src_path) {
c40a57e5
AB
129 goto error;
130 }
ff9ce920 131
a7a607cf 132 debug_info_src->short_src_path = get_filename_from_path(
51a9f65d 133 debug_info_src->src_path);
c40a57e5
AB
134 }
135
136 source_location_destroy(src_loc);
137 }
138
d5ddf820
AB
139 if (bin->elf_path) {
140 debug_info_src->bin_path = strdup(bin->elf_path);
a7a607cf
JG
141 if (!debug_info_src->bin_path) {
142 goto error;
143 }
144
145 debug_info_src->short_bin_path = get_filename_from_path(
146 debug_info_src->bin_path);
36ae9941 147
d5ddf820 148 ret = bin_info_get_bin_loc(bin, ip, &(debug_info_src->bin_loc));
36ae9941
AB
149 if (ret) {
150 goto error;
151 }
a7a607cf
JG
152 }
153
c40a57e5
AB
154end:
155 return debug_info_src;
156
157error:
158 debug_info_source_destroy(debug_info_src);
159 return NULL;
160}
161
162static
163void proc_debug_info_sources_destroy(
164 struct proc_debug_info_sources *proc_dbg_info_src)
165{
166 if (!proc_dbg_info_src) {
167 return;
168 }
169
d5ddf820
AB
170 if (proc_dbg_info_src->baddr_to_bin_info) {
171 g_hash_table_destroy(proc_dbg_info_src->baddr_to_bin_info);
c40a57e5
AB
172 }
173
174 if (proc_dbg_info_src->ip_to_debug_info_src) {
175 g_hash_table_destroy(proc_dbg_info_src->ip_to_debug_info_src);
176 }
177
178 g_free(proc_dbg_info_src);
179}
180
181static
182struct proc_debug_info_sources *proc_debug_info_sources_create(void)
183{
184 struct proc_debug_info_sources *proc_dbg_info_src = NULL;
185
186 proc_dbg_info_src = g_new0(struct proc_debug_info_sources, 1);
187 if (!proc_dbg_info_src) {
188 goto end;
189 }
190
d5ddf820 191 proc_dbg_info_src->baddr_to_bin_info = g_hash_table_new_full(
47857613 192 g_int64_hash, g_int64_equal, (GDestroyNotify) g_free,
d5ddf820
AB
193 (GDestroyNotify) bin_info_destroy);
194 if (!proc_dbg_info_src->baddr_to_bin_info) {
c40a57e5
AB
195 goto error;
196 }
197
198 proc_dbg_info_src->ip_to_debug_info_src = g_hash_table_new_full(
47857613 199 g_int64_hash, g_int64_equal, (GDestroyNotify) g_free,
c40a57e5
AB
200 (GDestroyNotify) debug_info_source_destroy);
201 if (!proc_dbg_info_src->ip_to_debug_info_src) {
202 goto error;
203 }
204
205end:
206 return proc_dbg_info_src;
207
208error:
209 proc_debug_info_sources_destroy(proc_dbg_info_src);
210 return NULL;
211}
212
213static
214struct proc_debug_info_sources *proc_debug_info_sources_ht_get_entry(
215 GHashTable *ht, int64_t vpid)
216{
47857613 217 gpointer key = g_new0(int64_t, 1);
c40a57e5
AB
218 struct proc_debug_info_sources *proc_dbg_info_src = NULL;
219
47857613
JG
220 if (!key) {
221 goto end;
222 }
223
224 *((int64_t *) key) = vpid;
225
c40a57e5
AB
226 /* Exists? Return it */
227 proc_dbg_info_src = g_hash_table_lookup(ht, key);
228 if (proc_dbg_info_src) {
229 goto end;
230 }
231
232 /* Otherwise, create and return it */
233 proc_dbg_info_src = proc_debug_info_sources_create();
234 if (!proc_dbg_info_src) {
235 goto end;
236 }
237
238 g_hash_table_insert(ht, key, proc_dbg_info_src);
47857613
JG
239 /* Ownership passed to ht */
240 key = NULL;
c40a57e5 241end:
47857613 242 g_free(key);
c40a57e5
AB
243 return proc_dbg_info_src;
244}
245
246static
247struct debug_info_source *proc_debug_info_sources_get_entry(
248 struct proc_debug_info_sources *proc_dbg_info_src, uint64_t ip)
249{
250 struct debug_info_source *debug_info_src = NULL;
47857613 251 gpointer key = g_new0(uint64_t, 1);
c40a57e5
AB
252 GHashTableIter iter;
253 gpointer baddr, value;
254
47857613
JG
255 if (!key) {
256 goto end;
257 }
258
259 *((uint64_t *) key) = ip;
260
c40a57e5
AB
261 /* Look in IP to debug infos hash table first. */
262 debug_info_src = g_hash_table_lookup(
263 proc_dbg_info_src->ip_to_debug_info_src,
47857613 264 key);
c40a57e5
AB
265 if (debug_info_src) {
266 goto end;
267 }
268
d5ddf820
AB
269 /* Check in all bin_infos. */
270 g_hash_table_iter_init(&iter, proc_dbg_info_src->baddr_to_bin_info);
c40a57e5
AB
271
272 while (g_hash_table_iter_next(&iter, &baddr, &value))
273 {
d5ddf820 274 struct bin_info *bin = value;
c40a57e5 275
d5ddf820 276 if (!bin_info_has_address(value, ip)) {
c40a57e5
AB
277 continue;
278 }
279
47857613
JG
280 /*
281 * Found; add it to cache.
282 *
283 * FIXME: this should be bounded in size (and implement
284 * a caching policy), and entries should be prunned when
285 * libraries are unmapped.
286 */
d5ddf820 287 debug_info_src = debug_info_source_create_from_bin(bin, ip);
c40a57e5
AB
288 if (debug_info_src) {
289 g_hash_table_insert(
290 proc_dbg_info_src->ip_to_debug_info_src,
47857613
JG
291 key, debug_info_src);
292 /* Ownership passed to ht. */
293 key = NULL;
c40a57e5
AB
294 }
295 break;
296 }
297
298end:
47857613 299 free(key);
c40a57e5
AB
300 return debug_info_src;
301}
302
303BT_HIDDEN
304struct debug_info_source *debug_info_query(struct debug_info *debug_info,
305 int64_t vpid, uint64_t ip)
306{
307 struct debug_info_source *dbg_info_src = NULL;
308 struct proc_debug_info_sources *proc_dbg_info_src;
309
310 proc_dbg_info_src = proc_debug_info_sources_ht_get_entry(
311 debug_info->vpid_to_proc_dbg_info_src, vpid);
312 if (!proc_dbg_info_src) {
313 goto end;
314 }
315
316 dbg_info_src = proc_debug_info_sources_get_entry(
317 proc_dbg_info_src, ip);
318 if (!dbg_info_src) {
319 goto end;
320 }
321
322end:
323 return dbg_info_src;
324}
325
326BT_HIDDEN
327struct debug_info *debug_info_create(void)
328{
329 int ret;
330 struct debug_info *debug_info;
331
332 debug_info = g_new0(struct debug_info, 1);
333 if (!debug_info) {
334 goto end;
335 }
336
47857613
JG
337 debug_info->vpid_to_proc_dbg_info_src = g_hash_table_new_full(
338 g_int64_hash, g_int64_equal, (GDestroyNotify) g_free,
c40a57e5
AB
339 (GDestroyNotify) proc_debug_info_sources_destroy);
340 if (!debug_info->vpid_to_proc_dbg_info_src) {
341 goto error;
342 }
343
344 ret = debug_info_init(debug_info);
345 if (ret) {
346 goto error;
347 }
348
349end:
350 return debug_info;
351error:
352 g_free(debug_info);
353 return NULL;
354}
355
356BT_HIDDEN
357void debug_info_destroy(struct debug_info *debug_info)
358{
359 if (!debug_info) {
360 goto end;
361 }
362
363 if (debug_info->vpid_to_proc_dbg_info_src) {
364 g_hash_table_destroy(debug_info->vpid_to_proc_dbg_info_src);
365 }
366
367 g_free(debug_info);
368end:
369 return;
370}
371
372static
373void handle_statedump_build_id_event(struct debug_info *debug_info,
374 struct ctf_event_definition *event_def)
375{
376 struct proc_debug_info_sources *proc_dbg_info_src;
377 struct bt_definition *event_fields_def = NULL;
378 struct bt_definition *sec_def = NULL;
379 struct bt_definition *baddr_def = NULL;
380 struct bt_definition *vpid_def = NULL;
381 struct bt_definition *build_id_def = NULL;
382 struct definition_sequence *build_id_seq;
d5ddf820 383 struct bin_info *bin = NULL;
c40a57e5
AB
384 int i;
385 int64_t vpid;
386 uint64_t baddr;
387 uint8_t *build_id = NULL;
388 uint64_t build_id_len;
389
390 event_fields_def = (struct bt_definition *) event_def->event_fields;
391 sec_def = (struct bt_definition *)
392 event_def->stream->stream_event_context;
393
394 if (!event_fields_def || !sec_def) {
395 goto end;
396 }
397
398 baddr_def = bt_lookup_definition(event_fields_def, "_baddr");
399 if (!baddr_def) {
400 goto end;
401 }
402
403 vpid_def = bt_lookup_definition(sec_def, "_vpid");
404 if (!vpid_def) {
405 goto end;
406 }
407
408 build_id_def = bt_lookup_definition(event_fields_def, "_build_id");
409 if (!build_id_def) {
410 goto end;
411 }
412
413 if (baddr_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
414 goto end;
415 }
416
417 if (vpid_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
418 goto end;
419 }
420
421 if (build_id_def->declaration->id != BT_CTF_TYPE_ID_SEQUENCE) {
422 goto end;
423 }
424
425 baddr = bt_get_unsigned_int(baddr_def);
426 vpid = bt_get_signed_int(vpid_def);
427 build_id_seq = container_of(build_id_def,
428 struct definition_sequence, p);
429 build_id_len = build_id_seq->length->value._unsigned;
430
431 build_id = g_malloc(build_id_len);
432 if (!build_id) {
433 goto end;
434 }
435
436 for (i = 0; i < build_id_len; ++i) {
437 struct bt_definition **field;
438
439 field = (struct bt_definition **) &g_ptr_array_index(
440 build_id_seq->elems, i);
441 build_id[i] = bt_get_unsigned_int(*field);
442 }
443
444 proc_dbg_info_src = proc_debug_info_sources_ht_get_entry(
445 debug_info->vpid_to_proc_dbg_info_src, vpid);
446 if (!proc_dbg_info_src) {
447 goto end;
448 }
449
d5ddf820 450 bin = g_hash_table_lookup(proc_dbg_info_src->baddr_to_bin_info,
c40a57e5 451 (gpointer) &baddr);
d5ddf820 452 if (!bin) {
c40a57e5 453 /*
d5ddf820 454 * The build_id event comes after the bin has been
c40a57e5
AB
455 * created. If it isn't found, just ignore this event.
456 */
457 goto end;
458 }
459
d5ddf820 460 bin_info_set_build_id(bin, build_id, build_id_len);
c40a57e5
AB
461
462end:
463 free(build_id);
464 return;
465}
466
467static
468void handle_statedump_debug_link_event(struct debug_info *debug_info,
469 struct ctf_event_definition *event_def)
470{
471 struct proc_debug_info_sources *proc_dbg_info_src;
472 struct bt_definition *event_fields_def = NULL;
473 struct bt_definition *sec_def = NULL;
474 struct bt_definition *baddr_def = NULL;
475 struct bt_definition *vpid_def = NULL;
476 struct bt_definition *filename_def = NULL;
477 struct bt_definition *crc32_def = NULL;
d5ddf820 478 struct bin_info *bin = NULL;
c40a57e5
AB
479 int64_t vpid;
480 uint64_t baddr;
481 char *filename = NULL;
482 uint32_t crc32;
483
484 event_fields_def = (struct bt_definition *) event_def->event_fields;
485 sec_def = (struct bt_definition *)
486 event_def->stream->stream_event_context;
487
488 if (!event_fields_def || !sec_def) {
489 goto end;
490 }
491
492 baddr_def = bt_lookup_definition(event_fields_def, "_baddr");
493 if (!baddr_def) {
494 goto end;
495 }
496
497 vpid_def = bt_lookup_definition(sec_def, "_vpid");
498 if (!vpid_def) {
499 goto end;
500 }
501
502 filename_def = bt_lookup_definition(event_fields_def, "_filename");
503 if (!filename_def) {
504 goto end;
505 }
506
507 crc32_def = bt_lookup_definition(event_fields_def, "_crc32");
508 if (!crc32_def) {
509 goto end;
510 }
511
512 if (baddr_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
513 goto end;
514 }
515
516 if (vpid_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
517 goto end;
518 }
519
520 if (filename_def->declaration->id != BT_CTF_TYPE_ID_STRING) {
521 goto end;
522 }
523
524 if (crc32_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
525 goto end;
526 }
527
528 baddr = bt_get_unsigned_int(baddr_def);
529 vpid = bt_get_signed_int(vpid_def);
530
531 proc_dbg_info_src = proc_debug_info_sources_ht_get_entry(
532 debug_info->vpid_to_proc_dbg_info_src, vpid);
533 if (!proc_dbg_info_src) {
534 goto end;
535 }
536
d5ddf820 537 bin = g_hash_table_lookup(proc_dbg_info_src->baddr_to_bin_info,
c40a57e5 538 (gpointer) &baddr);
d5ddf820 539 if (!bin) {
c40a57e5 540 /*
d5ddf820 541 * The debug_link event comes after the bin has been
c40a57e5
AB
542 * created. If it isn't found, just ignore this event.
543 */
544 goto end;
545 }
546
547 filename = bt_get_string(filename_def);
548 crc32 = bt_get_unsigned_int(crc32_def);
549
d5ddf820 550 bin_info_set_debug_link(bin, filename, crc32);
c40a57e5
AB
551
552end:
553 return;
554}
555
556static
9f2b13ca
AB
557void handle_bin_info_event(struct debug_info *debug_info,
558 struct ctf_event_definition *event_def, bool has_pic_field)
c40a57e5
AB
559{
560 struct bt_definition *baddr_def = NULL;
561 struct bt_definition *memsz_def = NULL;
9c713367 562 struct bt_definition *path_def = NULL;
9f2b13ca 563 struct bt_definition *is_pic_def = NULL;
c40a57e5
AB
564 struct bt_definition *vpid_def = NULL;
565 struct bt_definition *event_fields_def = NULL;
566 struct bt_definition *sec_def = NULL;
567 struct proc_debug_info_sources *proc_dbg_info_src;
d5ddf820 568 struct bin_info *bin;
c40a57e5
AB
569 uint64_t baddr, memsz;
570 int64_t vpid;
9c713367 571 const char *path;
47857613 572 gpointer key = NULL;
9f2b13ca 573 bool is_pic;
c40a57e5
AB
574
575 event_fields_def = (struct bt_definition *) event_def->event_fields;
576 sec_def = (struct bt_definition *)
577 event_def->stream->stream_event_context;
578
579 if (!event_fields_def || !sec_def) {
580 goto end;
581 }
582
583 baddr_def = bt_lookup_definition(event_fields_def, "_baddr");
584 if (!baddr_def) {
585 goto end;
586 }
587
588 memsz_def = bt_lookup_definition(event_fields_def, "_memsz");
589 if (!memsz_def) {
590 goto end;
591 }
592
9c713367
AB
593 path_def = bt_lookup_definition(event_fields_def, "_path");
594 if (!path_def) {
c40a57e5
AB
595 goto end;
596 }
597
9f2b13ca
AB
598 if (has_pic_field) {
599 is_pic_def = bt_lookup_definition(event_fields_def, "_is_pic");
600 if (!is_pic_def) {
601 goto end;
602 }
603
604 if (is_pic_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
605 goto end;
606 }
607
608 is_pic = (bt_get_unsigned_int(is_pic_def) == 1);
609 } else {
610 /*
611 * dlopen has no is_pic field, because the shared
612 * object is always PIC.
613 */
614 is_pic = true;
615 }
616
c40a57e5
AB
617 vpid_def = bt_lookup_definition(sec_def, "_vpid");
618 if (!vpid_def) {
619 goto end;
620 }
621
622 if (baddr_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
623 goto end;
624 }
625
626 if (memsz_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
627 goto end;
628 }
629
9c713367 630 if (path_def->declaration->id != BT_CTF_TYPE_ID_STRING) {
c40a57e5
AB
631 goto end;
632 }
633
634 if (vpid_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
635 goto end;
636 }
637
638 baddr = bt_get_unsigned_int(baddr_def);
639 memsz = bt_get_unsigned_int(memsz_def);
9c713367 640 path = bt_get_string(path_def);
c40a57e5
AB
641 vpid = bt_get_signed_int(vpid_def);
642
9c713367 643 if (!path) {
c40a57e5
AB
644 goto end;
645 }
646
647 if (memsz == 0) {
648 /* Ignore VDSO. */
649 goto end;
650 }
651
652 proc_dbg_info_src = proc_debug_info_sources_ht_get_entry(
653 debug_info->vpid_to_proc_dbg_info_src, vpid);
654 if (!proc_dbg_info_src) {
655 goto end;
656 }
657
47857613
JG
658 key = g_new0(uint64_t, 1);
659 if (!key) {
660 goto end;
661 }
662
663 *((uint64_t *) key) = baddr;
664
d5ddf820 665 bin = g_hash_table_lookup(proc_dbg_info_src->baddr_to_bin_info,
47857613 666 key);
d5ddf820 667 if (bin) {
c40a57e5
AB
668 goto end;
669 }
670
d5ddf820
AB
671 bin = bin_info_create(path, baddr, memsz, is_pic);
672 if (!bin) {
c40a57e5
AB
673 goto end;
674 }
675
d5ddf820
AB
676 g_hash_table_insert(proc_dbg_info_src->baddr_to_bin_info,
677 key, bin);
47857613
JG
678 /* Ownership passed to ht. */
679 key = NULL;
c40a57e5
AB
680
681end:
47857613 682 g_free(key);
c40a57e5
AB
683 return;
684}
685
9f2b13ca 686static inline
9c713367 687void handle_statedump_bin_info_event(struct debug_info *debug_info,
9f2b13ca
AB
688 struct ctf_event_definition *event_def)
689{
690 handle_bin_info_event(debug_info, event_def, true);
691}
692
693static inline
694void handle_dlopen_event(struct debug_info *debug_info,
695 struct ctf_event_definition *event_def)
696{
697 handle_bin_info_event(debug_info, event_def, false);
698}
699
700
c40a57e5
AB
701static
702void handle_statedump_start(struct debug_info *debug_info,
703 struct ctf_event_definition *event_def)
704{
705 struct bt_definition *vpid_def = NULL;
706 struct bt_definition *sec_def = NULL;
707 struct proc_debug_info_sources *proc_dbg_info_src;
708 int64_t vpid;
709
710 sec_def = (struct bt_definition *)
711 event_def->stream->stream_event_context;
712 if (!sec_def) {
713 goto end;
714 }
715
716 vpid_def = bt_lookup_definition(sec_def, "_vpid");
717 if (!vpid_def) {
718 goto end;
719 }
720
721 vpid = bt_get_signed_int(vpid_def);
722
723 proc_dbg_info_src = proc_debug_info_sources_ht_get_entry(
724 debug_info->vpid_to_proc_dbg_info_src, vpid);
725 if (!proc_dbg_info_src) {
726 goto end;
727 }
728
d5ddf820 729 g_hash_table_remove_all(proc_dbg_info_src->baddr_to_bin_info);
c40a57e5
AB
730 g_hash_table_remove_all(proc_dbg_info_src->ip_to_debug_info_src);
731
732end:
733 return;
734}
735
736static
737void register_event_debug_infos(struct debug_info *debug_info,
738 struct ctf_event_definition *event)
739{
740 struct bt_definition *ip_def, *vpid_def;
741 int64_t vpid;
742 uint64_t ip;
743 struct bt_definition *sec_def;
744
745 /* Get stream event context definition. */
746 sec_def = (struct bt_definition *) event->stream->stream_event_context;
747 if (!sec_def) {
748 goto end;
749 }
750
751 /* Get "ip" and "vpid" definitions. */
752 vpid_def = bt_lookup_definition((struct bt_definition *) sec_def,
753 "_vpid");
754 ip_def = bt_lookup_definition((struct bt_definition *) sec_def, "_ip");
755
756 if (!vpid_def || !ip_def) {
757 goto end;
758 }
759
760 vpid = bt_get_signed_int(vpid_def);
761 ip = bt_get_unsigned_int(ip_def);
762
763 /* Get debug info for this context. */
764 ((struct definition_integer *) ip_def)->debug_info_src =
765 debug_info_query(debug_info, vpid, ip);
766
767end:
768 return;
769}
770
771BT_HIDDEN
772void debug_info_handle_event(struct debug_info *debug_info,
773 struct ctf_event_definition *event)
774{
775 struct ctf_event_declaration *event_class;
776 struct ctf_stream_declaration *stream_class;
777
778 if (!debug_info || !event) {
779 goto end;
780 }
781
782 stream_class = event->stream->stream_class;
783 event_class = g_ptr_array_index(stream_class->events_by_id,
784 event->stream->event_id);
785
9c713367 786 if (event_class->name == debug_info->q_statedump_bin_info) {
9f2b13ca 787 /* State dump */
9c713367 788 handle_statedump_bin_info_event(debug_info, event);
9f2b13ca
AB
789 } else if (event_class->name == debug_info->q_dl_open) {
790 handle_dlopen_event(debug_info, event);
c40a57e5
AB
791 } else if (event_class->name == debug_info->q_statedump_start) {
792 /* Start state dump */
793 handle_statedump_start(debug_info, event);
794 } else if (event_class->name == debug_info->q_statedump_debug_link) {
795 /* Debug link info */
796 handle_statedump_debug_link_event(debug_info, event);
797 } else if (event_class->name == debug_info->q_statedump_build_id) {
798 /* Build ID info */
799 handle_statedump_build_id_event(debug_info, event);
800 } else {
801 /* Other events: register debug infos */
802 register_event_debug_infos(debug_info, event);
803 }
804
805end:
806 return;
807}
This page took 0.056417 seconds and 4 git commands to generate.