Prep 1.29
[dwarves.git] / dwarves.c
blobef93239d26827711e23b405dd113986867d18507
1 /*
2 SPDX-License-Identifier: GPL-2.0-only
4 Copyright (C) 2006 Mandriva Conectiva S.A.
5 Copyright (C) 2006 Arnaldo Carvalho de Melo <acme@mandriva.com>
6 Copyright (C) 2007 Red Hat Inc.
7 Copyright (C) 2007 Arnaldo Carvalho de Melo <acme@redhat.com>
8 */
10 #include <assert.h>
11 #include <dirent.h>
12 #include <dwarf.h>
13 #include <errno.h>
14 #include <fcntl.h>
15 #include <fnmatch.h>
16 #include <libelf.h>
17 #include <limits.h>
18 #include <pthread.h>
19 #include <search.h>
20 #include <stdio.h>
21 #include <stdarg.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <sys/stat.h>
26 #include <sys/utsname.h>
28 #include "config.h"
29 #include "list.h"
30 #include "dwarves.h"
31 #include "dutil.h"
33 #define min(x, y) ((x) < (y) ? (x) : (y))
35 #define obstack_chunk_alloc malloc
36 #define obstack_chunk_free free
38 static void *obstack_zalloc(struct obstack *obstack, size_t size)
40 void *o = obstack_alloc(obstack, size);
42 if (o)
43 memset(o, 0, size);
44 return o;
47 void *cu__zalloc(struct cu *cu, size_t size)
49 if (cu->use_obstack)
50 return obstack_zalloc(&cu->obstack, size);
52 return zalloc(size);
55 void *cu__malloc(struct cu *cu, size_t size)
57 if (cu->use_obstack)
58 return obstack_alloc(&cu->obstack, size);
60 return malloc(size);
63 void cu__free(struct cu *cu, void *ptr)
65 if (!cu->use_obstack)
66 free(ptr);
68 // When using an obstack we'll free everything in cu__delete()
71 void cu__tag_free(struct cu *cu, struct tag *tag)
73 if (cu->dfops && cu->dfops->tag__free)
74 cu->dfops->tag__free(tag, cu);
75 else
76 cu__free(cu, tag);
79 void *cu__tag_alloc(struct cu *cu, size_t size)
81 if (cu->dfops && cu->dfops->tag__alloc)
82 return cu->dfops->tag__alloc(cu, size);
84 return cu__zalloc(cu, size);
87 int tag__is_base_type(const struct tag *tag, const struct cu *cu)
89 switch (tag->tag) {
90 case DW_TAG_base_type:
91 return 1;
93 case DW_TAG_typedef: {
94 const struct tag *type = cu__type(cu, tag->type);
96 if (type == NULL)
97 return 0;
98 return tag__is_base_type(type, cu);
101 return 0;
104 bool tag__is_array(const struct tag *tag, const struct cu *cu)
106 switch (tag->tag) {
107 case DW_TAG_array_type:
108 return true;
110 case DW_TAG_const_type:
111 case DW_TAG_typedef: {
112 const struct tag *type = cu__type(cu, tag->type);
114 if (type == NULL)
115 return 0;
116 return tag__is_array(type, cu);
119 return 0;
122 int __tag__has_type_loop(const struct tag *tag, const struct tag *type,
123 char *bf, size_t len, FILE *fp,
124 const char *fn, int line)
126 char bbf[2048], *abf = bbf;
128 if (type == NULL)
129 return 0;
131 if (tag->type == type->type) {
132 int printed;
134 if (bf != NULL)
135 abf = bf;
136 else
137 len = sizeof(bbf);
138 printed = snprintf(abf, len, "<ERROR(%s:%d): detected type loop: type=%d, tag=%s>",
139 fn, line, tag->type, dwarf_tag_name(tag->tag));
140 if (bf == NULL)
141 printed = fprintf(fp ?: stderr, "%s\n", abf);
142 return printed;
145 return 0;
148 static void lexblock__delete_tags(struct tag *tag, struct cu *cu)
150 struct lexblock *block = tag__lexblock(tag);
151 struct tag *pos, *n;
153 list_for_each_entry_safe_reverse(pos, n, &block->tags, node) {
154 list_del_init(&pos->node);
155 tag__delete(pos, cu);
159 void lexblock__delete(struct lexblock *block, struct cu *cu)
161 if (block == NULL)
162 return;
164 lexblock__delete_tags(&block->ip.tag, cu);
165 cu__tag_free(cu, &block->ip.tag);
168 static void template_parameter_pack__delete_tags(struct template_parameter_pack *pack, struct cu *cu)
170 struct tag *pos, *n;
172 list_for_each_entry_safe_reverse(pos, n, &pack->params, node) {
173 list_del_init(&pos->node);
174 tag__delete(pos, cu);
178 void template_parameter_pack__delete(struct template_parameter_pack *pack, struct cu *cu)
180 if (pack == NULL)
181 return;
183 template_parameter_pack__delete_tags(pack, cu);
184 cu__tag_free(cu, &pack->tag);
187 static void formal_parameter_pack__delete_tags(struct formal_parameter_pack *pack, struct cu *cu)
189 struct tag *pos, *n;
191 list_for_each_entry_safe_reverse(pos, n, &pack->params, node) {
192 list_del_init(&pos->node);
193 tag__delete(pos, cu);
197 void formal_parameter_pack__delete(struct formal_parameter_pack *pack, struct cu *cu)
199 if (pack == NULL)
200 return;
202 formal_parameter_pack__delete_tags(pack, cu);
203 cu__tag_free(cu, &pack->tag);
206 void tag__delete(struct tag *tag, struct cu *cu)
208 if (tag == NULL)
209 return;
211 assert(list_empty(&tag->node));
213 if (tag->attributes)
214 free(tag->attributes);
216 switch (tag->tag) {
217 case DW_TAG_union_type:
218 type__delete(tag__type(tag), cu); break;
219 case DW_TAG_class_type:
220 case DW_TAG_structure_type:
221 class__delete(tag__class(tag), cu); break;
222 case DW_TAG_enumeration_type:
223 enumeration__delete(tag__type(tag), cu); break;
224 case DW_TAG_subroutine_type:
225 ftype__delete(tag__ftype(tag), cu); break;
226 case DW_TAG_subprogram:
227 function__delete(tag__function(tag), cu); break;
228 case DW_TAG_lexical_block:
229 lexblock__delete(tag__lexblock(tag), cu); break;
230 case DW_TAG_GNU_template_parameter_pack:
231 template_parameter_pack__delete(tag__template_parameter_pack(tag), cu); break;
232 case DW_TAG_GNU_formal_parameter_pack:
233 formal_parameter_pack__delete(tag__formal_parameter_pack(tag), cu); break;
234 default:
235 cu__tag_free(cu, tag);
239 void tag__not_found_die(const char *file, int line, const char *func, int tag, const char *name)
241 fprintf(stderr, "%s::%s(%d, related to the type of tag DW_TAG_%s \"%s\"): tag not found, please report to "
242 "acme@kernel.org\n", file, func, line, dwarf_tag_name(tag), name);
243 exit(1);
246 struct tag *tag__follow_typedef(const struct tag *tag, const struct cu *cu)
248 struct tag *type = cu__type(cu, tag->type);
250 if (type != NULL && tag__is_typedef(type))
251 return tag__follow_typedef(type, cu);
253 return type;
256 struct tag *tag__strip_typedefs_and_modifiers(const struct tag *tag, const struct cu *cu)
258 struct tag *type = cu__type(cu, tag->type);
260 while (type != NULL && (tag__is_typedef(type) || tag__is_modifier(type)))
261 type = cu__type(cu, type->type);
263 return type;
266 size_t __tag__id_not_found_fprintf(FILE *fp, type_id_t id,
267 const char *fn, int line)
269 return fprintf(fp, "<ERROR(%s:%d): %d not found!>\n", fn, line, id);
272 static struct ase_type_name_to_size {
273 const char *name;
274 size_t size;
275 } base_type_name_to_size_table[] = {
276 { .name = "unsigned", .size = 32, },
277 { .name = "signed int", .size = 32, },
278 { .name = "unsigned int", .size = 32, },
279 { .name = "int", .size = 32, },
280 { .name = "short unsigned int", .size = 16, },
281 { .name = "signed short", .size = 16, },
282 { .name = "unsigned short", .size = 16, },
283 { .name = "short int", .size = 16, },
284 { .name = "short", .size = 16, },
285 { .name = "char", .size = 8, },
286 { .name = "signed char", .size = 8, },
287 { .name = "unsigned char", .size = 8, },
288 { .name = "signed long", .size = 0, },
289 { .name = "long int", .size = 0, },
290 { .name = "long", .size = 0, },
291 { .name = "signed long", .size = 0, },
292 { .name = "unsigned long", .size = 0, },
293 { .name = "long unsigned int", .size = 0, },
294 { .name = "bool", .size = 8, },
295 { .name = "_Bool", .size = 8, },
296 { .name = "long long unsigned int", .size = 64, },
297 { .name = "long long int", .size = 64, },
298 { .name = "long long", .size = 64, },
299 { .name = "signed long long", .size = 64, },
300 { .name = "unsigned long long", .size = 64, },
301 { .name = "double", .size = 64, },
302 { .name = "double double", .size = 64, },
303 { .name = "single float", .size = 32, },
304 { .name = "float", .size = 32, },
305 { .name = "long double", .size = sizeof(long double) * 8, },
306 { .name = "long double long double", .size = sizeof(long double) * 8, },
307 { .name = "__int128", .size = 128, },
308 { .name = "unsigned __int128", .size = 128, },
309 { .name = "__int128 unsigned", .size = 128, },
310 { .name = "_Float128", .size = 128, },
311 { .name = NULL },
314 bool base_type__language_defined(struct base_type *bt)
316 int i = 0;
317 char bf[64];
318 const char *name;
320 if (bt->name_has_encoding)
321 name = bt->name;
322 else
323 name = base_type__name(bt, bf, sizeof(bf));
325 while (base_type_name_to_size_table[i].name != NULL) {
326 if (bt->name_has_encoding) {
327 if (strcmp(base_type_name_to_size_table[i].name, bt->name) == 0)
328 return true;
329 } else if (strcmp(base_type_name_to_size_table[i].name, name) == 0)
330 return true;
331 ++i;
334 return false;
337 size_t base_type__name_to_size(struct base_type *bt, struct cu *cu)
339 int i = 0;
340 char bf[64];
341 const char *name, *orig_name;
343 if (bt->name_has_encoding)
344 name = bt->name;
345 else
346 name = base_type__name(bt, bf, sizeof(bf));
347 orig_name = name;
348 try_again:
349 while (base_type_name_to_size_table[i].name != NULL) {
350 if (bt->name_has_encoding) {
351 if (strcmp(base_type_name_to_size_table[i].name, bt->name) == 0) {
352 size_t size;
353 found:
354 size = base_type_name_to_size_table[i].size;
356 return size ?: ((size_t)cu->addr_size * 8);
358 } else if (strcmp(base_type_name_to_size_table[i].name, name) == 0)
359 goto found;
360 ++i;
363 if (strstarts(name, "signed ")) {
364 i = 0;
365 name += sizeof("signed");
366 goto try_again;
369 fprintf(stderr, "%s: %s %s\n",
370 __func__, dwarf_tag_name(bt->tag.tag), orig_name);
371 return 0;
374 static const char *base_type_fp_type_str[] = {
375 [BT_FP_SINGLE] = "single",
376 [BT_FP_DOUBLE] = "double",
377 [BT_FP_CMPLX] = "complex",
378 [BT_FP_CMPLX_DBL] = "complex double",
379 [BT_FP_CMPLX_LDBL] = "complex long double",
380 [BT_FP_LDBL] = "long double",
381 [BT_FP_INTVL] = "interval",
382 [BT_FP_INTVL_DBL] = "interval double",
383 [BT_FP_INTVL_LDBL] = "interval long double",
384 [BT_FP_IMGRY] = "imaginary",
385 [BT_FP_IMGRY_DBL] = "imaginary double",
386 [BT_FP_IMGRY_LDBL] = "imaginary long double",
389 const char *__base_type__name(const struct base_type *bt)
391 return bt->name;
394 const char *base_type__name(const struct base_type *bt, char *bf, size_t len)
396 if (bt->name_has_encoding)
397 return __base_type__name(bt);
399 if (bt->float_type)
400 snprintf(bf, len, "%s %s", base_type_fp_type_str[bt->float_type], bt->name);
401 else
402 snprintf(bf, len, "%s%s%s", bt->is_bool ? "bool " : "", bt->is_varargs ? "... " : "", bt->name);
403 return bf;
406 void namespace__delete(struct namespace *space, struct cu *cu)
408 struct tag *pos, *n;
410 if (space == NULL)
411 return;
413 namespace__for_each_tag_safe_reverse(space, pos, n) {
414 list_del_init(&pos->node);
416 /* Look for nested namespaces */
417 if (tag__has_namespace(pos))
418 namespace__delete(tag__namespace(pos), cu);
419 tag__delete(pos, cu);
422 tag__delete(&space->tag, cu);
425 void __type__init(struct type *type)
427 INIT_LIST_HEAD(&type->node);
428 INIT_LIST_HEAD(&type->type_enum);
429 INIT_LIST_HEAD(&type->template_type_params);
430 INIT_LIST_HEAD(&type->template_value_params);
431 type->template_parameter_pack = NULL;
432 type->sizeof_member = NULL;
433 type->member_prefix = NULL;
434 type->member_prefix_len = 0;
435 type->suffix_disambiguation = 0;
438 struct class_member *
439 type__find_first_biggest_size_base_type_member(struct type *type,
440 const struct cu *cu)
442 struct class_member *pos, *result = NULL;
443 size_t result_size = 0;
445 type__for_each_data_member(type, pos) {
446 if (pos->is_static)
447 continue;
449 struct tag *type = cu__type(cu, pos->tag.type);
450 size_t member_size = 0, power2;
451 struct class_member *inner = NULL;
453 if (type == NULL) {
454 tag__id_not_found_fprintf(stderr, pos->tag.type);
455 continue;
457 reevaluate:
458 switch (type->tag) {
459 case DW_TAG_base_type:
460 member_size = base_type__size(type);
461 break;
462 case DW_TAG_pointer_type:
463 case DW_TAG_reference_type:
464 member_size = cu->addr_size;
465 break;
466 case DW_TAG_class_type:
467 case DW_TAG_union_type:
468 case DW_TAG_structure_type:
469 if (tag__type(type)->nr_members == 0)
470 continue;
471 inner = type__find_first_biggest_size_base_type_member(tag__type(type), cu);
472 member_size = inner->byte_size;
473 break;
474 case DW_TAG_array_type:
475 case DW_TAG_const_type:
476 case DW_TAG_typedef:
477 case DW_TAG_rvalue_reference_type:
478 case DW_TAG_volatile_type:
479 case DW_TAG_atomic_type: {
480 struct tag *tag = cu__type(cu, type->type);
481 if (tag == NULL) {
482 tag__id_not_found_fprintf(stderr, type->type);
483 continue;
485 type = tag;
487 goto reevaluate;
488 case DW_TAG_enumeration_type:
489 member_size = tag__type(type)->size / 8;
490 break;
493 /* long long */
494 if (member_size > cu->addr_size)
495 return pos;
497 for (power2 = cu->addr_size; power2 > result_size; power2 /= 2)
498 if (member_size >= power2) {
499 if (power2 == cu->addr_size)
500 return inner ?: pos;
501 result_size = power2;
502 result = inner ?: pos;
506 return result;
509 static void cu__find_class_holes(struct cu *cu)
511 uint32_t id;
512 struct class *pos;
514 cu__for_each_struct(cu, id, pos)
515 class__find_holes(pos);
518 struct cus {
519 uint32_t nr_entries;
520 struct list_head cus;
521 pthread_mutex_t mutex;
522 void (*loader_exit)(struct cus *cus);
523 void *priv; // Used in dwarf_loader__exit()
526 void cus__lock(struct cus *cus)
528 pthread_mutex_lock(&cus->mutex);
531 void cus__unlock(struct cus *cus)
533 pthread_mutex_unlock(&cus->mutex);
536 bool cus__empty(const struct cus *cus)
538 return list_empty(&cus->cus);
541 uint32_t cus__nr_entries(const struct cus *cus)
543 return cus->nr_entries;
546 void __cus__remove(struct cus *cus, struct cu *cu)
548 cus->nr_entries--;
549 list_del_init(&cu->node);
552 void cus__remove(struct cus *cus, struct cu *cu)
554 cus__lock(cus);
555 __cus__remove(cus, cu);
556 cus__unlock(cus);
559 void __cus__add(struct cus *cus, struct cu *cu)
561 cus->nr_entries++;
562 list_add_tail(&cu->node, &cus->cus);
565 void cus__add(struct cus *cus, struct cu *cu)
567 cus__lock(cus);
568 __cus__add(cus, cu);
569 cus__unlock(cus);
571 cu__find_class_holes(cu);
574 static void ptr_table__init(struct ptr_table *pt)
576 pt->entries = NULL;
577 pt->nr_entries = pt->allocated_entries = 0;
580 static void ptr_table__exit(struct ptr_table *pt)
582 zfree(&pt->entries);
585 static int ptr_table__add(struct ptr_table *pt, void *ptr, uint32_t *idxp)
587 const uint32_t nr_entries = pt->nr_entries + 1;
588 const uint32_t rc = pt->nr_entries;
590 if (nr_entries > pt->allocated_entries) {
591 uint32_t allocated_entries = pt->allocated_entries + 2048;
592 void *entries = realloc(pt->entries,
593 sizeof(void *) * allocated_entries);
594 if (entries == NULL)
595 return -ENOMEM;
597 /* Zero out the new range */
598 memset(entries + pt->allocated_entries * sizeof(void *), 0,
599 (allocated_entries - pt->allocated_entries) * sizeof(void *));
601 pt->allocated_entries = allocated_entries;
602 pt->entries = entries;
605 pt->entries[rc] = ptr;
606 pt->nr_entries = nr_entries;
607 *idxp = rc;
608 return 0;
611 static int ptr_table__add_with_id(struct ptr_table *pt, void *ptr,
612 uint32_t id)
614 /* Assume we won't be fed with the same id more than once */
615 if (id >= pt->allocated_entries) {
616 uint32_t allocated_entries = roundup(id + 1, 2048);
617 void *entries = realloc(pt->entries,
618 sizeof(void *) * allocated_entries);
619 if (entries == NULL)
620 return -ENOMEM;
622 /* Zero out the new range */
623 memset(entries + pt->allocated_entries * sizeof(void *), 0,
624 (allocated_entries - pt->allocated_entries) * sizeof(void *));
626 pt->allocated_entries = allocated_entries;
627 pt->entries = entries;
630 pt->entries[id] = ptr;
631 if (id >= pt->nr_entries)
632 pt->nr_entries = id + 1;
633 return 0;
636 static void *ptr_table__entry(const struct ptr_table *pt, uint32_t id)
638 return id >= pt->nr_entries ? NULL : pt->entries[id];
641 static void cu__insert_function(struct cu *cu, struct tag *tag)
643 struct function *function = tag__function(tag);
644 struct rb_node **p = &cu->functions.rb_node;
645 struct rb_node *parent = NULL;
646 struct function *f;
648 while (*p != NULL) {
649 parent = *p;
650 f = rb_entry(parent, struct function, rb_node);
651 if (function->lexblock.ip.addr < f->lexblock.ip.addr)
652 p = &(*p)->rb_left;
653 else
654 p = &(*p)->rb_right;
656 rb_link_node(&function->rb_node, parent, p);
657 rb_insert_color(&function->rb_node, &cu->functions);
660 int cu__table_add_tag(struct cu *cu, struct tag *tag, uint32_t *type_id)
662 struct ptr_table *pt = &cu->tags_table;
664 if (tag__is_tag_type(tag))
665 pt = &cu->types_table;
666 else if (tag__is_function(tag)) {
667 pt = &cu->functions_table;
668 cu__insert_function(cu, tag);
671 return ptr_table__add(pt, tag, type_id) ? -ENOMEM : 0;
674 int cu__table_nullify_type_entry(struct cu *cu, uint32_t id)
676 return ptr_table__add_with_id(&cu->types_table, NULL, id);
679 int cu__add_tag(struct cu *cu, struct tag *tag, uint32_t *id)
681 int err = cu__table_add_tag(cu, tag, id);
683 if (err == 0)
684 list_add_tail(&tag->node, &cu->tags);
686 return err;
689 int cu__table_add_tag_with_id(struct cu *cu, struct tag *tag, uint32_t id)
691 struct ptr_table *pt = &cu->tags_table;
693 if (tag__is_tag_type(tag)) {
694 pt = &cu->types_table;
695 } else if (tag__is_function(tag)) {
696 pt = &cu->functions_table;
697 cu__insert_function(cu, tag);
700 return ptr_table__add_with_id(pt, tag, id);
703 int cu__add_tag_with_id(struct cu *cu, struct tag *tag, uint32_t id)
705 int err = cu__table_add_tag_with_id(cu, tag, id);
707 if (err == 0)
708 list_add_tail(&tag->node, &cu->tags);
710 return err;
713 int cus__fprintf_ptr_table_stats_csv_header(FILE *fp)
715 return fprintf(fp, "# cu,tags,allocated_tags,types,allocated_types,functions,allocated_functions\n");
718 int cu__fprintf_ptr_table_stats_csv(struct cu *cu, FILE *fp)
720 int printed = fprintf(fp, "%s,%u,%u,%u,%u,%u,%u\n", cu->name,
721 cu->tags_table.nr_entries, cu->tags_table.allocated_entries,
722 cu->types_table.nr_entries, cu->types_table.allocated_entries,
723 cu->functions_table.nr_entries, cu->functions_table.allocated_entries);
725 return printed;
728 #define OBSTACK_CHUNK_SIZE (128*1024)
730 struct cu *cu__new(const char *name, uint8_t addr_size,
731 const unsigned char *build_id, int build_id_len,
732 const char *filename, bool use_obstack)
734 struct cu *cu = zalloc(sizeof(*cu) + build_id_len);
736 if (cu != NULL) {
737 uint32_t void_id;
739 cu->use_obstack = use_obstack;
740 if (cu->use_obstack)
741 obstack_begin(&cu->obstack, OBSTACK_CHUNK_SIZE);
743 if (name == NULL || filename == NULL)
744 goto out_free;
746 cu->name = strdup(name);
747 if (cu->name == NULL)
748 goto out_free;
750 cu->filename = strdup(filename);
751 if (cu->filename == NULL)
752 goto out_free_name;
754 ptr_table__init(&cu->tags_table);
755 ptr_table__init(&cu->types_table);
756 ptr_table__init(&cu->functions_table);
758 * the first entry is historically associated with void,
759 * so make sure we don't use it
761 if (ptr_table__add(&cu->types_table, NULL, &void_id) < 0)
762 goto out_free_filename;
764 cu->functions = RB_ROOT;
766 cu->dfops = NULL;
767 INIT_LIST_HEAD(&cu->tags);
768 INIT_LIST_HEAD(&cu->tool_list);
769 INIT_LIST_HEAD(&cu->node);
771 cu->addr_size = addr_size;
772 cu->extra_dbg_info = 0;
774 cu->nr_inline_expansions = 0;
775 cu->size_inline_expansions = 0;
776 cu->nr_structures_changed = 0;
777 cu->nr_functions_changed = 0;
778 cu->max_len_changed_item = 0;
779 cu->function_bytes_added = 0;
780 cu->function_bytes_removed = 0;
781 cu->build_id_len = build_id_len;
782 if (build_id_len > 0)
783 memcpy(cu->build_id, build_id, build_id_len);
784 cu->priv = NULL;
787 return cu;
789 out_free_filename:
790 zfree(&cu->filename);
791 out_free_name:
792 zfree(&cu->name);
793 out_free:
794 free(cu);
795 return NULL;
798 void cu__delete(struct cu *cu)
800 if (cu == NULL)
801 return;
803 ptr_table__exit(&cu->tags_table);
804 ptr_table__exit(&cu->types_table);
805 ptr_table__exit(&cu->functions_table);
806 if (cu->dfops && cu->dfops->cu__delete)
807 cu->dfops->cu__delete(cu);
809 if (cu->use_obstack)
810 obstack_free(&cu->obstack, NULL);
812 zfree(&cu->filename);
813 zfree(&cu->name);
814 free(cu);
817 bool cu__same_build_id(const struct cu *cu, const struct cu *other)
819 return cu->build_id_len != 0 &&
820 cu->build_id_len == other->build_id_len &&
821 memcmp(cu->build_id, other->build_id, cu->build_id_len) == 0;
824 struct tag *cu__function(const struct cu *cu, const uint32_t id)
826 return cu ? ptr_table__entry(&cu->functions_table, id) : NULL;
829 struct tag *cu__tag(const struct cu *cu, const uint32_t id)
831 return cu ? ptr_table__entry(&cu->tags_table, id) : NULL;
834 struct tag *cu__type(const struct cu *cu, const type_id_t id)
836 return cu ? ptr_table__entry(&cu->types_table, id) : NULL;
839 struct tag *cu__find_first_typedef_of_type(const struct cu *cu,
840 const type_id_t type)
842 uint32_t id;
843 struct tag *pos;
845 if (cu == NULL || type == 0)
846 return NULL;
848 cu__for_each_type(cu, id, pos)
849 if (tag__is_typedef(pos) && pos->type == type)
850 return pos;
852 return NULL;
855 struct tag *cu__find_base_type_by_name(const struct cu *cu,
856 const char *name, type_id_t *idp)
858 uint32_t id;
859 struct tag *pos;
861 if (cu == NULL || name == NULL)
862 return NULL;
864 cu__for_each_type(cu, id, pos) {
865 if (pos->tag != DW_TAG_base_type)
866 continue;
868 const struct base_type *bt = tag__base_type(pos);
869 char bf[64];
870 const char *bname = base_type__name(bt, bf, sizeof(bf));
871 if (!bname || strcmp(bname, name) != 0)
872 continue;
874 if (idp != NULL)
875 *idp = id;
876 return pos;
879 return NULL;
882 struct tag *cu__find_base_type_by_name_and_size(const struct cu *cu, const char *name,
883 uint16_t bit_size, type_id_t *idp)
885 uint32_t id;
886 struct tag *pos;
888 if (name == NULL)
889 return NULL;
891 cu__for_each_type(cu, id, pos) {
892 if (pos->tag == DW_TAG_base_type) {
893 const struct base_type *bt = tag__base_type(pos);
894 char bf[64];
896 if (bt->bit_size == bit_size &&
897 strcmp(base_type__name(bt, bf, sizeof(bf)), name) == 0) {
898 if (idp != NULL)
899 *idp = id;
900 return pos;
905 return NULL;
908 struct tag *cu__find_enumeration_by_name_and_size(const struct cu *cu, const char *name,
909 uint16_t bit_size, type_id_t *idp)
911 uint32_t id;
912 struct tag *pos;
914 if (name == NULL)
915 return NULL;
917 cu__for_each_type(cu, id, pos) {
918 if (pos->tag == DW_TAG_enumeration_type) {
919 const struct type *t = tag__type(pos);
921 if (t->size == bit_size &&
922 strcmp(type__name(t), name) == 0) {
923 if (idp != NULL)
924 *idp = id;
925 return pos;
930 return NULL;
933 struct tag *cu__find_enumeration_by_name(const struct cu *cu, const char *name, type_id_t *idp)
935 uint32_t id;
936 struct tag *pos;
938 if (name == NULL)
939 return NULL;
941 cu__for_each_type(cu, id, pos) {
942 if (pos->tag == DW_TAG_enumeration_type) {
943 const struct type *type = tag__type(pos);
944 const char *tname = type__name(type);
946 if (tname && strcmp(tname, name) == 0) {
947 if (idp != NULL)
948 *idp = id;
949 return pos;
954 return NULL;
957 struct tag *cu__find_type_by_name(const struct cu *cu, const char *name, const int include_decls, type_id_t *idp)
959 if (cu == NULL || name == NULL)
960 return NULL;
962 uint32_t id;
963 struct tag *pos;
964 cu__for_each_type(cu, id, pos) {
965 struct type *type;
967 if (!tag__is_type(pos))
968 continue;
970 type = tag__type(pos);
971 const char *tname = type__name(type);
972 if (tname && strcmp(tname, name) == 0) {
973 if (!type->declaration)
974 goto found;
976 if (include_decls)
977 goto found;
981 return NULL;
982 found:
983 if (idp != NULL)
984 *idp = id;
985 return pos;
988 struct tag *cus__find_type_by_name(struct cus *cus, struct cu **cu, const char *name,
989 const int include_decls, type_id_t *id)
991 struct cu *pos;
992 struct tag *tag = NULL;
994 cus__lock(cus);
996 list_for_each_entry(pos, &cus->cus, node) {
997 tag = cu__find_type_by_name(pos, name, include_decls, id);
998 if (tag != NULL) {
999 if (cu != NULL)
1000 *cu = pos;
1001 break;
1005 cus__unlock(cus);
1007 return tag;
1010 static struct tag *__cu__find_struct_by_name(const struct cu *cu, const char *name,
1011 const int include_decls, bool unions, type_id_t *idp)
1013 if (cu == NULL || name == NULL)
1014 return NULL;
1016 uint32_t id;
1017 struct tag *pos;
1018 cu__for_each_type(cu, id, pos) {
1019 struct type *type;
1021 if (!(tag__is_struct(pos) || (unions && tag__is_union(pos))))
1022 continue;
1024 type = tag__type(pos);
1025 const char *tname = type__name(type);
1026 if (tname && strcmp(tname, name) == 0) {
1027 if (!type->declaration)
1028 goto found;
1030 if (include_decls)
1031 goto found;
1035 return NULL;
1036 found:
1037 if (idp != NULL)
1038 *idp = id;
1039 return pos;
1042 struct tag *cu__find_struct_by_name(const struct cu *cu, const char *name,
1043 const int include_decls, type_id_t *idp)
1045 return __cu__find_struct_by_name(cu, name, include_decls, false, idp);
1048 struct tag *cu__find_struct_or_union_by_name(const struct cu *cu, const char *name,
1049 const int include_decls, type_id_t *idp)
1051 return __cu__find_struct_by_name(cu, name, include_decls, true, idp);
1054 static struct tag *__cus__find_struct_by_name(struct cus *cus, struct cu **cu, const char *name,
1055 const int include_decls, bool unions, type_id_t *id)
1057 struct tag *tag = NULL;
1058 struct cu *pos;
1060 cus__lock(cus);
1062 list_for_each_entry(pos, &cus->cus, node) {
1063 struct tag *tag = __cu__find_struct_by_name(pos, name, include_decls, unions, id);
1064 if (tag != NULL) {
1065 if (cu != NULL)
1066 *cu = pos;
1067 break;
1071 cus__unlock(cus);
1073 return tag;
1076 struct tag *cus__find_struct_by_name(struct cus *cus, struct cu **cu, const char *name,
1077 const int include_decls, type_id_t *idp)
1079 return __cus__find_struct_by_name(cus, cu, name, include_decls, false, idp);
1082 struct tag *cus__find_struct_or_union_by_name(struct cus *cus, struct cu **cu, const char *name,
1083 const int include_decls, type_id_t *idp)
1085 return __cus__find_struct_by_name(cus, cu, name, include_decls, true, idp);
1088 struct function *cu__find_function_at_addr(const struct cu *cu,
1089 uint64_t addr)
1091 struct rb_node *n;
1093 if (cu == NULL)
1094 return NULL;
1096 n = cu->functions.rb_node;
1098 while (n) {
1099 struct function *f = rb_entry(n, struct function, rb_node);
1101 if (addr < f->lexblock.ip.addr)
1102 n = n->rb_left;
1103 else if (addr >= f->lexblock.ip.addr + f->lexblock.size)
1104 n = n->rb_right;
1105 else
1106 return f;
1109 return NULL;
1113 struct function *cus__find_function_at_addr(struct cus *cus, uint64_t addr, struct cu **cu)
1115 struct function *f = NULL;
1116 struct cu *pos;
1118 cus__lock(cus);
1120 list_for_each_entry(pos, &cus->cus, node) {
1121 f = cu__find_function_at_addr(pos, addr);
1123 if (f != NULL) {
1124 if (cu != NULL)
1125 *cu = pos;
1126 break;
1130 cus__unlock(cus);
1132 return f;
1135 static struct cu *__cus__find_cu_by_name(struct cus *cus, const char *name)
1137 struct cu *pos;
1139 list_for_each_entry(pos, &cus->cus, node)
1140 if (pos->name && strcmp(pos->name, name) == 0)
1141 goto out;
1143 pos = NULL;
1144 out:
1145 return pos;
1148 struct cu *cus__find_cu_by_name(struct cus *cus, const char *name)
1150 struct cu *pos;
1152 cus__lock(cus);
1154 pos = __cus__find_cu_by_name(cus, name);
1156 cus__unlock(cus);
1158 return pos;
1161 struct cu *cus__find_pair(struct cus *cus, const char *name)
1163 struct cu *cu;
1165 cus__lock(cus);
1167 if (cus->nr_entries == 1)
1168 cu = list_first_entry(&cus->cus, struct cu, node);
1169 else
1170 cu = __cus__find_cu_by_name(cus, name);
1172 cus__unlock(cus);
1174 return cu;
1177 struct tag *cu__find_function_by_name(const struct cu *cu, const char *name)
1179 if (cu == NULL || name == NULL)
1180 return NULL;
1182 uint32_t id;
1183 struct function *pos;
1184 cu__for_each_function(cu, id, pos) {
1185 const char *fname = function__name(pos);
1186 if (fname && strcmp(fname, name) == 0)
1187 return function__tag(pos);
1190 return NULL;
1193 static size_t array_type__nr_entries(const struct array_type *at)
1195 int i;
1196 size_t nr_entries = 1;
1198 for (i = 0; i < at->dimensions; ++i)
1199 nr_entries *= at->nr_entries[i];
1201 return nr_entries;
1204 size_t tag__size(const struct tag *tag, const struct cu *cu)
1206 size_t size;
1208 switch (tag->tag) {
1209 case DW_TAG_string_type:
1210 return tag__string_type(tag)->nr_entries;
1211 case DW_TAG_member: {
1212 struct class_member *member = tag__class_member(tag);
1213 if (member->is_static)
1214 return 0;
1215 /* Is it cached already? */
1216 size = member->byte_size;
1217 if (size != 0)
1218 return size;
1219 break;
1221 case DW_TAG_pointer_type:
1222 case DW_TAG_reference_type: return cu->addr_size;
1223 case DW_TAG_base_type: return base_type__size(tag);
1224 case DW_TAG_enumeration_type: return tag__type(tag)->size / 8;
1225 case DW_TAG_subroutine_type: return tag__ftype(tag)->byte_size ?: cu->addr_size;
1228 if (tag->type == 0) { /* struct class: unions, structs */
1229 struct type *type = tag__type(tag);
1231 /* empty base optimization trick */
1232 if (type->size == 1 && type->nr_members == 0)
1233 size = 0;
1234 else
1235 size = tag__type(tag)->size;
1236 } else {
1237 const struct tag *type = cu__type(cu, tag->type);
1239 if (type == NULL) {
1240 tag__id_not_found_fprintf(stderr, tag->type);
1241 return -1;
1242 } else if (tag__has_type_loop(tag, type, NULL, 0, NULL))
1243 return -1;
1244 size = tag__size(type, cu);
1247 if (tag->tag == DW_TAG_array_type)
1248 return size * array_type__nr_entries(tag__array_type(tag));
1250 return size;
1253 const char *variable__name(const struct variable *var)
1255 return var->name;
1258 const char *variable__type_name(const struct variable *var,
1259 const struct cu *cu,
1260 char *bf, size_t len)
1262 const struct tag *tag = cu__type(cu, var->ip.tag.type);
1263 return tag != NULL ? tag__name(tag, cu, bf, len, NULL) : NULL;
1266 void class_member__delete(struct class_member *member, struct cu *cu)
1268 cu__tag_free(cu, &member->tag);
1271 static struct class_member *class_member__clone(const struct class_member *from, struct cu *cu)
1273 struct class_member *member = cu__tag_alloc(cu, sizeof(*member));
1275 if (member != NULL) // FIXME: the type-format specific (DWARF notably) are isn't beying copied, so far this isn't important, not used in the current tools
1276 memcpy(member, from, sizeof(*member));
1278 return member;
1281 static void type__delete_class_members(struct type *type, struct cu *cu)
1283 struct class_member *pos, *next;
1285 type__for_each_tag_safe_reverse(type, pos, next) {
1286 list_del_init(&pos->tag.node);
1287 class_member__delete(pos, cu);
1291 void class__delete(struct class *class, struct cu *cu)
1293 if (class == NULL)
1294 return;
1296 type__delete_class_members(&class->type, cu);
1297 cu__tag_free(cu, class__tag(class));
1300 void type__delete(struct type *type, struct cu *cu)
1302 if (type == NULL)
1303 return;
1305 type__delete_class_members(type, cu);
1307 if (type->suffix_disambiguation)
1308 zfree(&type->namespace.name);
1310 template_parameter_pack__delete(type->template_parameter_pack, cu);
1311 type->template_parameter_pack = NULL;
1313 cu__tag_free(cu, type__tag(type));
1316 static void enumerator__delete(struct enumerator *enumerator, struct cu *cu)
1318 cu__tag_free(cu, &enumerator->tag);
1321 void enumeration__delete(struct type *type, struct cu *cu)
1323 struct enumerator *pos, *n;
1325 if (type == NULL)
1326 return;
1328 type__for_each_enumerator_safe_reverse(type, pos, n) {
1329 list_del_init(&pos->tag.node);
1330 enumerator__delete(pos, cu);
1333 if (type->suffix_disambiguation)
1334 zfree(&type->namespace.name);
1336 cu__tag_free(cu, type__tag(type));
1339 void class__add_vtable_entry(struct class *class, struct function *vtable_entry)
1341 ++class->nr_vtable_entries;
1342 list_add_tail(&vtable_entry->vtable_node, &class->vtable);
1345 void namespace__add_tag(struct namespace *space, struct tag *tag)
1347 list_add_tail(&tag->node, &space->tags);
1350 void type__add_member(struct type *type, struct class_member *member)
1352 if (member->is_static)
1353 ++type->nr_static_members;
1354 else
1355 ++type->nr_members;
1356 namespace__add_tag(&type->namespace, &member->tag);
1359 void type__add_template_type_param(struct type *type, struct template_type_param *ttparam)
1361 list_add_tail(&ttparam->tag.node, &type->template_type_params);
1364 void type__add_template_value_param(struct type *type, struct template_value_param *tvparam)
1366 list_add_tail(&tvparam->tag.node, &type->template_value_params);
1369 struct class_member *type__last_member(struct type *type)
1371 struct class_member *pos;
1373 list_for_each_entry_reverse(pos, &type->namespace.tags, tag.node)
1374 if (pos->tag.tag == DW_TAG_member)
1375 return pos;
1376 return NULL;
1379 static int type__clone_members(struct type *type, const struct type *from, struct cu *cu)
1381 struct class_member *pos;
1383 type->nr_members = type->nr_static_members = 0;
1384 INIT_LIST_HEAD(&type->namespace.tags);
1386 type__for_each_member(from, pos) {
1387 struct class_member *clone = class_member__clone(pos, cu);
1389 if (clone == NULL)
1390 return -1;
1391 type__add_member(type, clone);
1394 return 0;
1397 struct class *class__clone(const struct class *from, const char *new_class_name, struct cu *cu)
1399 struct class *class = cu__tag_alloc(cu, sizeof(*class));
1401 if (class != NULL) {
1402 memcpy(class, from, sizeof(*class));
1403 if (new_class_name != NULL) {
1404 class->type.namespace.name = strdup(new_class_name);
1405 if (class->type.namespace.name == NULL) {
1406 cu__free(cu, class);
1407 return NULL;
1410 if (type__clone_members(&class->type, &from->type, cu) != 0) {
1411 class__delete(class, cu);
1412 class = NULL;
1416 return class;
1419 void enumeration__add(struct type *type, struct enumerator *enumerator)
1421 ++type->nr_members;
1422 namespace__add_tag(&type->namespace, &enumerator->tag);
1425 void lexblock__add_lexblock(struct lexblock *block, struct lexblock *child)
1427 ++block->nr_lexblocks;
1428 list_add_tail(&child->ip.tag.node, &block->tags);
1431 const char *function__name(struct function *func)
1433 return func->name;
1436 static void parameter__delete(struct parameter *parm, struct cu *cu)
1438 cu__tag_free(cu, &parm->tag);
1441 void ftype__delete(struct ftype *type, struct cu *cu)
1443 struct parameter *pos, *n;
1445 if (type == NULL)
1446 return;
1448 ftype__for_each_parameter_safe_reverse(type, pos, n) {
1449 list_del_init(&pos->tag.node);
1450 parameter__delete(pos, cu);
1453 template_parameter_pack__delete(type->template_parameter_pack, cu);
1454 type->template_parameter_pack = NULL;
1456 cu__tag_free(cu, &type->tag);
1459 void function__delete(struct function *func, struct cu *cu)
1461 if (func == NULL)
1462 return;
1464 lexblock__delete_tags(&func->lexblock.ip.tag, cu);
1465 ftype__delete(&func->proto, cu);
1468 int ftype__has_parm_of_type(const struct ftype *ftype, const type_id_t target,
1469 const struct cu *cu)
1471 struct parameter *pos;
1473 if (ftype->tag.tag == DW_TAG_subprogram) {
1474 struct function *func = (struct function *)ftype;
1476 if (func->btf)
1477 ftype = tag__ftype(cu__type(cu, ftype->tag.type));
1480 ftype__for_each_parameter(ftype, pos) {
1481 struct tag *type = cu__type(cu, pos->tag.type);
1483 if (type != NULL && tag__is_pointer(type)) {
1484 if (type->type == target)
1485 return 1;
1488 return 0;
1491 void ftype__add_parameter(struct ftype *ftype, struct parameter *parm)
1493 ++ftype->nr_parms;
1494 list_add_tail(&parm->tag.node, &ftype->parms);
1497 void ftype__add_template_type_param(struct ftype *ftype, struct template_type_param *param)
1499 list_add_tail(&param->tag.node, &ftype->template_type_params);
1502 void ftype__add_template_value_param(struct ftype *ftype, struct template_value_param *param)
1504 list_add_tail(&param->tag.node, &ftype->template_value_params);
1507 void template_parameter_pack__add(struct template_parameter_pack *pack, struct template_type_param *param)
1509 list_add_tail(&param->tag.node, &pack->params);
1512 void formal_parameter_pack__add(struct formal_parameter_pack *pack, struct parameter *param)
1514 list_add_tail(&param->tag.node, &pack->params);
1517 void lexblock__add_tag(struct lexblock *block, struct tag *tag)
1519 list_add_tail(&tag->node, &block->tags);
1522 void lexblock__add_inline_expansion(struct lexblock *block,
1523 struct inline_expansion *exp)
1525 ++block->nr_inline_expansions;
1526 block->size_inline_expansions += exp->size;
1527 lexblock__add_tag(block, &exp->ip.tag);
1530 void lexblock__add_variable(struct lexblock *block, struct variable *var)
1532 ++block->nr_variables;
1533 lexblock__add_tag(block, &var->ip.tag);
1536 void lexblock__add_label(struct lexblock *block, struct label *label)
1538 ++block->nr_labels;
1539 lexblock__add_tag(block, &label->ip.tag);
1542 static bool __class__has_flexible_array(struct class *class, const struct cu *cu)
1544 struct class_member *member = type__last_member(&class->type);
1546 if (member == NULL)
1547 return false;
1549 struct tag *type = cu__type(cu, member->tag.type);
1551 if (type->tag != DW_TAG_array_type)
1552 return false;
1554 struct array_type *array = tag__array_type(type);
1556 if (array->dimensions > 1)
1557 return false;
1559 if (array->nr_entries == NULL || array->nr_entries[0] == 0)
1560 return true;
1562 return false;
1565 bool class__has_flexible_array(struct class *class, const struct cu *cu)
1567 if (!class->flexible_array_verified) {
1568 class->has_flexible_array = __class__has_flexible_array(class, cu);
1569 class->flexible_array_verified = true;
1572 return class->has_flexible_array;
1575 const struct class_member *class__find_bit_hole(const struct class *class,
1576 const struct class_member *trailer,
1577 const uint16_t bit_hole_size)
1579 struct class_member *pos;
1580 const size_t byte_hole_size = bit_hole_size / 8;
1582 type__for_each_data_member(&class->type, pos)
1583 if (pos == trailer)
1584 break;
1585 else if (pos->hole >= byte_hole_size ||
1586 pos->bit_hole >= bit_hole_size)
1587 return pos;
1589 return NULL;
1592 void class__find_holes(struct class *class)
1594 const struct type *ctype = &class->type;
1595 struct class_member *pos, *last = NULL;
1596 uint32_t cur_bitfield_end = ctype->size * 8, cur_bitfield_size = 0;
1597 int bit_holes = 0, byte_holes = 0;
1598 uint32_t bit_start, bit_end, last_seen_bit = 0;
1599 bool in_bitfield = false;
1601 if (!tag__is_struct(class__tag(class)))
1602 return;
1604 if (class->holes_searched)
1605 return;
1607 class->nr_holes = 0;
1608 class->nr_bit_holes = 0;
1610 type__for_each_member(ctype, pos) {
1611 /* XXX for now just skip these */
1612 if (pos->tag.tag == DW_TAG_inheritance &&
1613 (pos->virtuality == DW_VIRTUALITY_virtual || pos->byte_size == 0))
1614 continue;
1616 if (pos->is_static)
1617 continue;
1619 pos->bit_hole = 0;
1620 pos->hole = 0;
1622 bit_start = pos->bit_offset;
1623 if (pos->bitfield_size) {
1624 bit_end = bit_start + pos->bitfield_size;
1625 } else {
1626 bit_end = bit_start + pos->byte_size * 8;
1629 bit_holes = 0;
1630 byte_holes = 0;
1631 if (in_bitfield) {
1632 /* check if we have some trailing bitfield bits left */
1633 int bitfield_end = min(bit_start, cur_bitfield_end);
1634 bit_holes = bitfield_end - last_seen_bit;
1635 last_seen_bit = bitfield_end;
1637 if (pos->bitfield_size) {
1638 uint32_t aligned_start = pos->byte_offset * 8;
1639 /* we can have some alignment byte padding left,
1640 * but we need to be careful about bitfield spanning
1641 * multiple aligned boundaries */
1642 if (last_seen_bit < aligned_start && aligned_start <= bit_start) {
1643 byte_holes = pos->byte_offset - last_seen_bit / 8;
1644 last_seen_bit = aligned_start;
1646 bit_holes += bit_start - last_seen_bit;
1647 } else {
1648 byte_holes = bit_start/8 - last_seen_bit/8;
1650 last_seen_bit = bit_end;
1652 if (pos->bitfield_size) {
1653 in_bitfield = true;
1654 /* if it's a new bitfield set or same, but with
1655 * bigger-sized type, readjust size and end bit */
1656 if (bit_end > cur_bitfield_end || pos->bit_size > cur_bitfield_size) {
1657 cur_bitfield_size = pos->bit_size;
1658 cur_bitfield_end = pos->byte_offset * 8 + cur_bitfield_size;
1660 * if current bitfield "borrowed" bits from
1661 * previous bitfield, it will have byte_offset
1662 * of previous bitfield's backing integral
1663 * type, but its end bit will be in a new
1664 * bitfield "area", so we need to adjust
1665 * bitfield end appropriately
1667 if (bit_end > cur_bitfield_end) {
1668 cur_bitfield_end += cur_bitfield_size;
1671 } else {
1672 in_bitfield = false;
1673 cur_bitfield_size = 0;
1674 cur_bitfield_end = bit_end;
1677 if (last) {
1678 last->hole = byte_holes;
1679 last->bit_hole = bit_holes;
1680 } else {
1681 class->pre_hole = byte_holes;
1682 class->pre_bit_hole = bit_holes;
1684 if (bit_holes)
1685 class->nr_bit_holes++;
1686 if (byte_holes > 0)
1687 class->nr_holes++;
1689 last = pos;
1692 if (in_bitfield) {
1693 int bitfield_end = min(ctype->size * 8, cur_bitfield_end);
1694 class->bit_padding = bitfield_end - last_seen_bit;
1695 last_seen_bit = bitfield_end;
1696 } else {
1697 class->bit_padding = 0;
1699 class->padding = ctype->size - last_seen_bit / 8;
1701 class->holes_searched = true;
1704 bool class__has_embedded_flexible_array(struct class *cls, const struct cu *cu)
1706 struct type *ctype = &cls->type;
1707 struct class_member *pos;
1709 if (!tag__is_struct(class__tag(cls)))
1710 return false;
1712 if (cls->embedded_flexible_array_searched)
1713 return cls->has_embedded_flexible_array;
1715 type__for_each_member(ctype, pos) {
1716 /* XXX for now just skip these */
1717 if (pos->tag.tag == DW_TAG_inheritance &&
1718 pos->virtuality == DW_VIRTUALITY_virtual)
1719 continue;
1721 if (pos->is_static)
1722 continue;
1724 struct tag *member_type = tag__strip_typedefs_and_modifiers(&pos->tag, cu);
1725 if (member_type == NULL)
1726 continue;
1728 if (!tag__is_struct(member_type))
1729 continue;
1731 cls->has_embedded_flexible_array = class__has_flexible_array(tag__class(member_type), cu);
1732 if (cls->has_embedded_flexible_array)
1733 break;
1735 if (member_type == class__tag(cls))
1736 continue;
1738 cls->has_embedded_flexible_array = class__has_embedded_flexible_array(tag__class(member_type), cu);
1739 if (cls->has_embedded_flexible_array)
1740 break;
1743 cls->embedded_flexible_array_searched = true;
1745 return cls->has_embedded_flexible_array;
1748 static size_t type__natural_alignment(struct type *type, const struct cu *cu);
1750 size_t tag__natural_alignment(struct tag *tag, const struct cu *cu)
1752 size_t natural_alignment = 1;
1754 if (tag == NULL) // Maybe its a non supported type, like DW_TAG_subrange_type, ADA stuff
1755 return natural_alignment;
1757 if (tag__is_pointer(tag)) {
1758 natural_alignment = cu->addr_size;
1759 } else if (tag->tag == DW_TAG_base_type) {
1760 natural_alignment = base_type__size(tag);
1761 } else if (tag__is_enumeration(tag)) {
1762 natural_alignment = tag__type(tag)->size / 8;
1763 } else if (tag__is_struct(tag) || tag__is_union(tag)) {
1764 natural_alignment = type__natural_alignment(tag__type(tag), cu);
1765 } else if (tag->tag == DW_TAG_array_type) {
1766 tag = tag__strip_typedefs_and_modifiers(tag, cu);
1767 if (tag != NULL) // Maybe its a non supported type, like DW_TAG_subrange_type, ADA stuff
1768 natural_alignment = tag__natural_alignment(tag, cu);
1772 * Cope with zero sized types, like:
1774 * struct u64_stats_sync {
1775 * #if BITS_PER_LONG==32 && defined(CONFIG_SMP)
1776 * seqcount_t seq;
1777 * #endif
1778 * };
1781 return natural_alignment ?: 1;
1784 static size_t type__natural_alignment(struct type *type, const struct cu *cu)
1786 struct class_member *member;
1788 if (type->natural_alignment != 0)
1789 return type->natural_alignment;
1791 type__for_each_member(type, member) {
1792 /* XXX for now just skip these */
1793 if (member->tag.tag == DW_TAG_inheritance &&
1794 member->virtuality == DW_VIRTUALITY_virtual)
1795 continue;
1796 if (member->is_static) continue;
1798 struct tag *member_type = tag__strip_typedefs_and_modifiers(&member->tag, cu);
1800 if (member_type == NULL) // Maybe its a DW_TAG_subrange_type, ADA stuff still not supported
1801 continue;
1803 size_t member_natural_alignment = tag__natural_alignment(member_type, cu);
1805 if (type->natural_alignment < member_natural_alignment)
1806 type->natural_alignment = member_natural_alignment;
1809 return type->natural_alignment;
1813 * Sometimes the only indication that a struct is __packed__ is for it to
1814 * appear embedded in another and at an offset that is not natural for it,
1815 * so, in !__packed__ parked struct, check for that and mark the types of
1816 * members at unnatural alignments.
1818 void type__check_structs_at_unnatural_alignments(struct type *type, const struct cu *cu)
1820 struct class_member *member;
1822 type__for_each_member(type, member) {
1823 struct tag *member_type = tag__strip_typedefs_and_modifiers(&member->tag, cu);
1825 if (member_type == NULL) {
1826 // just be conservative and ignore
1827 // Found first when a FORTRAN95 DWARF file was processed
1828 // and the DW_TAG_string_type wasn't yet supported
1829 continue;
1832 if (!tag__is_struct(member_type))
1833 continue;
1835 size_t natural_alignment = tag__natural_alignment(member_type, cu);
1837 /* Would this break the natural alignment */
1838 if ((member->byte_offset % natural_alignment) != 0) {
1839 struct class *cls = tag__class(member_type);
1841 cls->is_packed = true;
1842 cls->type.packed_attributes_inferred = 1;
1847 bool class__infer_packed_attributes(struct class *cls, const struct cu *cu)
1849 struct type *ctype = &cls->type;
1850 struct class_member *pos;
1851 uint16_t max_natural_alignment = 1;
1853 if (!tag__is_struct(class__tag(cls)))
1854 return false;
1856 if (ctype->packed_attributes_inferred)
1857 return cls->is_packed;
1859 class__find_holes(cls);
1861 if (cls->padding != 0 || cls->nr_holes != 0) {
1862 type__check_structs_at_unnatural_alignments(ctype, cu);
1863 cls->is_packed = false;
1864 goto out;
1867 type__for_each_member(ctype, pos) {
1868 /* XXX for now just skip these */
1869 if (pos->tag.tag == DW_TAG_inheritance &&
1870 pos->virtuality == DW_VIRTUALITY_virtual)
1871 continue;
1873 if (pos->is_static)
1874 continue;
1876 struct tag *member_type = tag__strip_typedefs_and_modifiers(&pos->tag, cu);
1877 size_t natural_alignment = tag__natural_alignment(member_type, cu);
1879 /* Always aligned: */
1880 if (natural_alignment == sizeof(char))
1881 continue;
1883 if (max_natural_alignment < natural_alignment)
1884 max_natural_alignment = natural_alignment;
1886 if ((pos->byte_offset % natural_alignment) == 0)
1887 continue;
1889 cls->is_packed = true;
1890 goto out;
1893 if ((max_natural_alignment != 1 && ctype->alignment == 1) ||
1894 (class__size(cls) % max_natural_alignment) != 0)
1895 cls->is_packed = true;
1897 out:
1898 ctype->packed_attributes_inferred = 1;
1900 return cls->is_packed;
1904 * If structs embedded in unions, nameless or not, have a size which isn't
1905 * isn't a multiple of the union size, then it must be packed, even if
1906 * it has no holes nor padding, as an array of such unions would have the
1907 * natural alignments of non-multiple structs inside it broken.
1909 void union__infer_packed_attributes(struct type *type, const struct cu *cu)
1911 const uint32_t union_size = type->size;
1912 struct class_member *member;
1914 if (type->packed_attributes_inferred)
1915 return;
1917 type__for_each_member(type, member) {
1918 struct tag *member_type = tag__strip_typedefs_and_modifiers(&member->tag, cu);
1920 if (!tag__is_struct(member_type))
1921 continue;
1923 size_t natural_alignment = tag__natural_alignment(member_type, cu);
1925 /* Would this break the natural alignment */
1926 if ((union_size % natural_alignment) != 0) {
1927 struct class *cls = tag__class(member_type);
1929 cls->is_packed = true;
1930 cls->type.packed_attributes_inferred = 1;
1934 type->packed_attributes_inferred = 1;
1937 /** class__has_hole_ge - check if class has a hole greater or equal to @size
1938 * @class - class instance
1939 * @size - hole size to check
1941 int class__has_hole_ge(const struct class *class, const uint16_t size)
1943 struct class_member *pos;
1945 if (class->nr_holes == 0)
1946 return 0;
1948 type__for_each_data_member(&class->type, pos)
1949 if (pos->hole >= size)
1950 return 1;
1952 return 0;
1955 struct class_member *type__find_member_by_name(const struct type *type, const char *name)
1957 if (name == NULL)
1958 return NULL;
1960 struct class_member *pos;
1961 type__for_each_data_member(type, pos) {
1962 const char *curr_name = class_member__name(pos);
1963 if (curr_name && strcmp(curr_name, name) == 0)
1964 return pos;
1967 return NULL;
1970 static int strcommon(const char *a, const char *b)
1972 int i = 0;
1974 while (*a != '\0' && *a == *b) {
1975 ++a;
1976 ++b;
1977 ++i;
1980 return i;
1983 static void enumeration__calc_prefix(struct type *enumeration)
1985 if (enumeration->member_prefix)
1986 return;
1988 const char *previous_name = NULL, *curr_name = "";
1989 int common_part = INT32_MAX;
1990 struct enumerator *entry;
1992 type__for_each_enumerator(enumeration, entry) {
1993 const char *curr_name = enumerator__name(entry);
1995 if (previous_name) {
1996 int curr_common_part = strcommon(curr_name, previous_name);
1997 if (common_part > curr_common_part)
1998 common_part = curr_common_part;
2002 previous_name = curr_name;
2005 enumeration->member_prefix = NULL;
2006 enumeration->member_prefix_len = 0;
2008 if (common_part != INT32_MAX) {
2009 enumeration->member_prefix = strndup(curr_name, common_part);
2010 if (enumeration->member_prefix != NULL)
2011 enumeration->member_prefix_len = common_part;
2015 void enumerations__calc_prefix(struct list_head *enumerations)
2017 struct tag_cu_node *pos;
2019 list_for_each_entry(pos, enumerations, node)
2020 enumeration__calc_prefix(tag__type(pos->tc.tag));
2023 uint32_t type__nr_members_of_type(const struct type *type, const type_id_t type_id)
2025 struct class_member *pos;
2026 uint32_t nr_members_of_type = 0;
2028 type__for_each_member(type, pos)
2029 if (pos->tag.type == type_id)
2030 ++nr_members_of_type;
2032 return nr_members_of_type;
2035 static void lexblock__account_inline_expansions(struct lexblock *block,
2036 const struct cu *cu)
2038 struct tag *pos, *type;
2040 if (block->nr_inline_expansions == 0)
2041 return;
2043 list_for_each_entry(pos, &block->tags, node) {
2044 if (pos->tag == DW_TAG_lexical_block) {
2045 lexblock__account_inline_expansions(tag__lexblock(pos),
2046 cu);
2047 continue;
2048 } else if (pos->tag != DW_TAG_inlined_subroutine)
2049 continue;
2051 type = cu__function(cu, pos->type);
2052 if (type != NULL) {
2053 struct function *ftype = tag__function(type);
2055 ftype->cu_total_nr_inline_expansions++;
2056 ftype->cu_total_size_inline_expansions +=
2057 tag__inline_expansion(pos)->size;
2063 void cu__account_inline_expansions(struct cu *cu)
2065 struct tag *pos;
2066 struct function *fpos;
2068 list_for_each_entry(pos, &cu->tags, node) {
2069 if (!tag__is_function(pos))
2070 continue;
2071 fpos = tag__function(pos);
2072 lexblock__account_inline_expansions(&fpos->lexblock, cu);
2073 cu->nr_inline_expansions += fpos->lexblock.nr_inline_expansions;
2074 cu->size_inline_expansions += fpos->lexblock.size_inline_expansions;
2078 static int list__for_all_tags(struct list_head *list, struct cu *cu,
2079 int (*iterator)(struct tag *tag,
2080 struct cu *cu, void *cookie),
2081 void *cookie)
2083 struct tag *pos, *n;
2085 if (list_empty(list) || !list->next)
2086 return 0;
2088 list_for_each_entry_safe_reverse(pos, n, list, node) {
2089 if (tag__has_namespace(pos)) {
2090 struct namespace *space = tag__namespace(pos);
2093 * See comment in type__for_each_enumerator, the
2094 * enumerators (enum entries) are shared, but the
2095 * enumeration tag must be deleted.
2097 if (!namespace__shared_tags(space) &&
2098 list__for_all_tags(&space->tags, cu,
2099 iterator, cookie))
2100 return 1;
2102 * vtable functions are already in the class tags list
2104 } else if (tag__is_function(pos)) {
2105 if (list__for_all_tags(&tag__ftype(pos)->parms,
2106 cu, iterator, cookie))
2107 return 1;
2108 if (list__for_all_tags(&tag__function(pos)->lexblock.tags,
2109 cu, iterator, cookie))
2110 return 1;
2111 } else if (pos->tag == DW_TAG_subroutine_type) {
2112 if (list__for_all_tags(&tag__ftype(pos)->parms,
2113 cu, iterator, cookie))
2114 return 1;
2115 } else if (pos->tag == DW_TAG_lexical_block) {
2116 if (list__for_all_tags(&tag__lexblock(pos)->tags,
2117 cu, iterator, cookie))
2118 return 1;
2121 if (iterator(pos, cu, cookie))
2122 return 1;
2124 return 0;
2127 int cu__for_all_tags(struct cu *cu,
2128 int (*iterator)(struct tag *tag,
2129 struct cu *cu, void *cookie),
2130 void *cookie)
2132 return list__for_all_tags(&cu->tags, cu, iterator, cookie);
2135 void cus__for_each_cu(struct cus *cus,
2136 int (*iterator)(struct cu *cu, void *cookie),
2137 void *cookie,
2138 struct cu *(*filter)(struct cu *cu))
2140 struct cu *pos;
2142 cus__lock(cus);
2144 list_for_each_entry(pos, &cus->cus, node) {
2145 struct cu *cu = pos;
2146 if (filter != NULL) {
2147 cu = filter(pos);
2148 if (cu == NULL)
2149 continue;
2151 if (iterator(cu, cookie))
2152 break;
2155 cus__unlock(cus);
2158 int cus__load_dir(struct cus *cus, struct conf_load *conf,
2159 const char *dirname, const char *filename_mask,
2160 const int recursive)
2162 struct dirent *entry;
2163 int err = -1;
2164 DIR *dir = opendir(dirname);
2166 if (dir == NULL)
2167 goto out;
2169 err = 0;
2170 while ((entry = readdir(dir)) != NULL) {
2171 char pathname[PATH_MAX];
2172 struct stat st;
2174 if (strcmp(entry->d_name, ".") == 0 ||
2175 strcmp(entry->d_name, "..") == 0)
2176 continue;
2178 snprintf(pathname, sizeof(pathname), "%.*s/%s",
2179 (int)(sizeof(pathname) - sizeof(entry->d_name) - 1), dirname, entry->d_name);
2181 err = lstat(pathname, &st);
2182 if (err != 0)
2183 break;
2185 if (S_ISDIR(st.st_mode)) {
2186 if (!recursive)
2187 continue;
2189 err = cus__load_dir(cus, conf, pathname,
2190 filename_mask, recursive);
2191 if (err != 0)
2192 break;
2193 } else if (fnmatch(filename_mask, entry->d_name, 0) == 0) {
2194 err = cus__load_file(cus, conf, pathname);
2195 if (err != 0)
2196 break;
2200 if (err == -1)
2201 puts(dirname);
2202 closedir(dir);
2203 out:
2204 return err;
2208 * This should really do demand loading of DSOs, STABS anyone? 8-)
2210 extern struct debug_fmt_ops dwarf__ops, ctf__ops, btf__ops;
2212 static struct debug_fmt_ops *debug_fmt_table[] = {
2213 &dwarf__ops,
2214 &btf__ops,
2215 &ctf__ops,
2216 NULL,
2219 static int debugging_formats__loader(const char *name)
2221 int i = 0;
2222 while (debug_fmt_table[i] != NULL) {
2223 if (strcmp(debug_fmt_table[i]->name, name) == 0)
2224 return i;
2225 ++i;
2227 return -1;
2230 int cus__load_file(struct cus *cus, struct conf_load *conf,
2231 const char *filename)
2233 int i = 0, err = 0;
2234 int loader;
2236 if (conf && conf->format_path != NULL) {
2237 char *fpath = strdup(conf->format_path);
2238 if (fpath == NULL)
2239 return -ENOMEM;
2240 char *fp = fpath;
2241 while (1) {
2242 char *sep = strchr(fp, ',');
2244 if (sep != NULL)
2245 *sep = '\0';
2247 err = -ENOTSUP;
2248 loader = debugging_formats__loader(fp);
2249 if (loader == -1)
2250 break;
2252 if (conf->conf_fprintf)
2253 conf->conf_fprintf->has_alignment_info = debug_fmt_table[loader]->has_alignment_info;
2255 err = 0;
2256 if (debug_fmt_table[loader]->load_file(cus, conf,
2257 filename) == 0)
2258 break;
2260 err = -EINVAL;
2261 if (sep == NULL)
2262 break;
2264 fp = sep + 1;
2266 free(fpath);
2267 return err;
2270 while (debug_fmt_table[i] != NULL) {
2271 if (conf && conf->conf_fprintf)
2272 conf->conf_fprintf->has_alignment_info = debug_fmt_table[i]->has_alignment_info;
2273 if (debug_fmt_table[i]->load_file(cus, conf, filename) == 0)
2274 return 0;
2275 ++i;
2278 return -EINVAL;
2281 #define BUILD_ID_SIZE 20
2282 #define SBUILD_ID_SIZE (BUILD_ID_SIZE * 2 + 1)
2284 #define NOTE_ALIGN(sz) (((sz) + 3) & ~3)
2286 #define NT_GNU_BUILD_ID 3
2288 #ifndef min
2289 #define min(x, y) ({ \
2290 typeof(x) _min1 = (x); \
2291 typeof(y) _min2 = (y); \
2292 (void) (&_min1 == &_min2); \
2293 _min1 < _min2 ? _min1 : _min2; })
2294 #endif
2296 #ifndef DW_LANG_C89
2297 #define DW_LANG_C89 0x0001
2298 #endif
2299 #ifndef DW_LANG_C
2300 #define DW_LANG_C 0x0002
2301 #endif
2302 #ifndef DW_LANG_Ada83
2303 #define DW_LANG_Ada83 0x0003
2304 #endif
2305 #ifndef DW_LANG_C_plus_plus
2306 #define DW_LANG_C_plus_plus 0x0004
2307 #endif
2308 #ifndef DW_LANG_Cobol74
2309 #define DW_LANG_Cobol74 0x0005
2310 #endif
2311 #ifndef DW_LANG_Cobol85
2312 #define DW_LANG_Cobol85 0x0006
2313 #endif
2314 #ifndef DW_LANG_Fortran77
2315 #define DW_LANG_Fortran77 0x0007
2316 #endif
2317 #ifndef DW_LANG_Fortran90
2318 #define DW_LANG_Fortran90 0x0008
2319 #endif
2320 #ifndef DW_LANG_Pascal83
2321 #define DW_LANG_Pascal83 0x0009
2322 #endif
2323 #ifndef DW_LANG_Modula2
2324 #define DW_LANG_Modula2 0x000a
2325 #endif
2326 #ifndef DW_LANG_Java
2327 #define DW_LANG_Java 0x000b
2328 #endif
2329 #ifndef DW_LANG_C99
2330 #define DW_LANG_C99 0x000c
2331 #endif
2332 #ifndef DW_LANG_Ada95
2333 #define DW_LANG_Ada95 0x000d
2334 #endif
2335 #ifndef DW_LANG_Fortran95
2336 #define DW_LANG_Fortran95 0x000e
2337 #endif
2338 #ifndef DW_LANG_PLI
2339 #define DW_LANG_PLI 0x000f
2340 #endif
2341 #ifndef DW_LANG_ObjC
2342 #define DW_LANG_ObjC 0x0010
2343 #endif
2344 #ifndef DW_LANG_ObjC_plus_plus
2345 #define DW_LANG_ObjC_plus_plus 0x0011
2346 #endif
2347 #ifndef DW_LANG_UPC
2348 #define DW_LANG_UPC 0x0012
2349 #endif
2350 #ifndef DW_LANG_D
2351 #define DW_LANG_D 0x0013
2352 #endif
2353 #ifndef DW_LANG_Python
2354 #define DW_LANG_Python 0x0014
2355 #endif
2356 #ifndef DW_LANG_OpenCL
2357 #define DW_LANG_OpenCL 0x0015
2358 #endif
2359 #ifndef DW_LANG_Go
2360 #define DW_LANG_Go 0x0016
2361 #endif
2362 #ifndef DW_LANG_Modula3
2363 #define DW_LANG_Modula3 0x0017
2364 #endif
2365 #ifndef DW_LANG_Haskell
2366 #define DW_LANG_Haskell 0x0018
2367 #endif
2368 #ifndef DW_LANG_C_plus_plus_03
2369 #define DW_LANG_C_plus_plus_03 0x0019
2370 #endif
2371 #ifndef DW_LANG_C_plus_plus_11
2372 #define DW_LANG_C_plus_plus_11 0x001a
2373 #endif
2374 #ifndef DW_LANG_OCaml
2375 #define DW_LANG_OCaml 0x001b
2376 #endif
2377 #ifndef DW_LANG_Rust
2378 #define DW_LANG_Rust 0x001c
2379 #endif
2380 #ifndef DW_LANG_C11
2381 #define DW_LANG_C11 0x001d
2382 #endif
2383 #ifndef DW_LANG_Swift
2384 #define DW_LANG_Swift 0x001e
2385 #endif
2386 #ifndef DW_LANG_Julia
2387 #define DW_LANG_Julia 0x001f
2388 #endif
2389 #ifndef DW_LANG_Dylan
2390 #define DW_LANG_Dylan 0x0020
2391 #endif
2392 #ifndef DW_LANG_C_plus_plus_14
2393 #define DW_LANG_C_plus_plus_14 0x0021
2394 #endif
2395 #ifndef DW_LANG_Fortran03
2396 #define DW_LANG_Fortran03 0x0022
2397 #endif
2398 #ifndef DW_LANG_Fortran08
2399 #define DW_LANG_Fortran08 0x0023
2400 #endif
2401 #ifndef DW_LANG_RenderScript
2402 #define DW_LANG_RenderScript 0x0024
2403 #endif
2404 #ifndef DW_LANG_BLISS
2405 #define DW_LANG_BLISS 0x0025
2406 #endif
2408 static const char *languages[] = {
2409 [DW_LANG_Ada83] = "ada83",
2410 [DW_LANG_Ada95] = "ada95",
2411 [DW_LANG_BLISS] = "bliss",
2412 [DW_LANG_C11] = "c11",
2413 [DW_LANG_C89] = "c89",
2414 [DW_LANG_C99] = "c99",
2415 [DW_LANG_C] = "c",
2416 [DW_LANG_Cobol74] = "cobol74",
2417 [DW_LANG_Cobol85] = "cobol85",
2418 [DW_LANG_C_plus_plus_03] = "c++03",
2419 [DW_LANG_C_plus_plus_11] = "c++11",
2420 [DW_LANG_C_plus_plus_14] = "c++14",
2421 [DW_LANG_C_plus_plus] = "c++",
2422 [DW_LANG_D] = "d",
2423 [DW_LANG_Dylan] = "dylan",
2424 [DW_LANG_Fortran03] = "fortran03",
2425 [DW_LANG_Fortran08] = "fortran08",
2426 [DW_LANG_Fortran77] = "fortran77",
2427 [DW_LANG_Fortran90] = "fortran90",
2428 [DW_LANG_Fortran95] = "fortran95",
2429 [DW_LANG_Go] = "go",
2430 [DW_LANG_Haskell] = "haskell",
2431 [DW_LANG_Java] = "java",
2432 [DW_LANG_Julia] = "julia",
2433 [DW_LANG_Modula2] = "modula2",
2434 [DW_LANG_Modula3] = "modula3",
2435 [DW_LANG_ObjC] = "objc",
2436 [DW_LANG_ObjC_plus_plus] = "objc++",
2437 [DW_LANG_OCaml] = "ocaml",
2438 [DW_LANG_OpenCL] = "opencl",
2439 [DW_LANG_Pascal83] = "pascal83",
2440 [DW_LANG_PLI] = "pli",
2441 [DW_LANG_Python] = "python",
2442 [DW_LANG_RenderScript] = "renderscript",
2443 [DW_LANG_Rust] = "rust",
2444 [DW_LANG_Swift] = "swift",
2445 [DW_LANG_UPC] = "upc",
2448 const char *lang__int2str(int id)
2450 const char *lang = NULL;
2452 if (id < ARRAY_SIZE(languages))
2453 lang = languages[id];
2454 else if (id == DW_LANG_Mips_Assembler)
2455 return "asm";
2457 return lang ?: "UNKNOWN";
2460 int lang__str2int(const char *lang)
2462 if (strcasecmp(lang, "asm") == 0)
2463 return DW_LANG_Mips_Assembler;
2465 // c89 is the first, bliss is the last, see /usr/include/dwarf.h
2466 for (int id = DW_LANG_C89; id <= DW_LANG_BLISS; ++id)
2467 if (languages[id] && strcasecmp(lang, languages[id]) == 0)
2468 return id;
2470 return -1;
2473 static int lang_id_cmp(const void *pa, const void *pb)
2475 int a = *(int *)pa,
2476 b = *(int *)pb;
2477 return a - b;
2480 int languages__parse(struct languages *languages, const char *tool)
2482 int nr_allocated = 4;
2483 char *lang = languages->str;
2485 languages->entries = zalloc(sizeof(int) * nr_allocated);
2486 if (languages->entries == NULL)
2487 goto out_enomem;
2489 while (1) {
2490 char *sep = strchr(lang, ',');
2492 if (sep)
2493 *sep = '\0';
2495 int id = lang__str2int(lang);
2497 if (sep)
2498 *sep = ',';
2500 if (id < 0) {
2501 fprintf(stderr, "%s: unknown language \"%s\"\n", tool, lang);
2502 goto out_free;
2505 if (languages->nr_entries >= nr_allocated) {
2506 nr_allocated *= 2;
2507 int *entries = realloc(languages->entries, nr_allocated);
2509 if (entries == NULL)
2510 goto out_enomem;
2512 languages->entries = entries;
2515 languages->entries[languages->nr_entries++] = id;
2517 if (!sep)
2518 break;
2520 lang = sep + 1;
2523 qsort(languages->entries, languages->nr_entries, sizeof(int), lang_id_cmp);
2525 return 0;
2526 out_enomem:
2527 fprintf(stderr, "%s: not enough memory to parse --lang\n", tool);
2528 out_free:
2529 zfree(&languages->entries);
2530 languages->nr_entries = 0;
2531 return -1;
2534 bool languages__in(struct languages *languages, int lang)
2536 return bsearch(&lang, languages->entries, languages->nr_entries, sizeof(int), lang_id_cmp) != NULL;
2539 int languages__init(struct languages *languages, const char *tool)
2541 if (languages->str == NULL) { // use PAHOLE_ as the namespace for all these tools
2542 languages->str = getenv("PAHOLE_LANG_EXCLUDE");
2544 if (languages->str == NULL)
2545 return 0;
2547 languages->exclude = true;
2550 return languages__parse(languages, tool);
2553 bool languages__cu_filtered(struct languages *languages, struct cu *cu, bool verbose)
2555 if (languages->nr_entries == 0)
2556 return false;
2558 bool in = languages__in(languages, cu->language);
2560 if ((!in && !languages->exclude) ||
2561 (in && languages->exclude)) {
2562 if (verbose)
2563 printf("Filtering CU %s written in %s.\n", cu->name, lang__int2str(cu->language));
2564 return true;
2567 return false;
2570 static int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
2572 int fd, err = -1;
2574 if (size < BUILD_ID_SIZE)
2575 goto out;
2577 fd = open(filename, O_RDONLY);
2578 if (fd < 0)
2579 goto out;
2581 while (1) {
2582 char bf[BUFSIZ];
2583 GElf_Nhdr nhdr;
2584 size_t namesz, descsz;
2586 if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr))
2587 break;
2589 namesz = NOTE_ALIGN(nhdr.n_namesz);
2590 descsz = NOTE_ALIGN(nhdr.n_descsz);
2591 if (nhdr.n_type == NT_GNU_BUILD_ID &&
2592 nhdr.n_namesz == sizeof("GNU")) {
2593 if (read(fd, bf, namesz) != (ssize_t)namesz)
2594 break;
2595 if (memcmp(bf, "GNU", sizeof("GNU")) == 0) {
2596 size_t sz = min(descsz, size);
2597 if (read(fd, build_id, sz) == (ssize_t)sz) {
2598 memset(build_id + sz, 0, size - sz);
2599 err = 0;
2600 break;
2602 } else if (read(fd, bf, descsz) != (ssize_t)descsz)
2603 break;
2604 } else {
2605 int n = namesz + descsz;
2607 if (n > (int)sizeof(bf)) {
2608 n = sizeof(bf);
2609 fprintf(stderr, "%s: truncating reading of build id in sysfs file %s: n_namesz=%u, n_descsz=%u.\n",
2610 __func__, filename, nhdr.n_namesz, nhdr.n_descsz);
2612 if (read(fd, bf, n) != n)
2613 break;
2616 close(fd);
2617 out:
2618 return err;
2621 static int elf_read_build_id(Elf *elf, void *bf, size_t size)
2623 int err = -1;
2624 GElf_Ehdr ehdr;
2625 GElf_Shdr shdr;
2626 Elf_Data *data;
2627 Elf_Scn *sec;
2628 Elf_Kind ek;
2629 void *ptr;
2631 if (size < BUILD_ID_SIZE)
2632 goto out;
2634 ek = elf_kind(elf);
2635 if (ek != ELF_K_ELF)
2636 goto out;
2638 if (gelf_getehdr(elf, &ehdr) == NULL) {
2639 fprintf(stderr, "%s: cannot get elf header.\n", __func__);
2640 goto out;
2644 * Check following sections for notes:
2645 * '.note.gnu.build-id'
2646 * '.notes'
2647 * '.note' (VDSO specific)
2649 do {
2650 sec = elf_section_by_name(elf, &shdr, ".note.gnu.build-id", NULL);
2651 if (sec)
2652 break;
2654 sec = elf_section_by_name(elf, &shdr, ".notes", NULL);
2655 if (sec)
2656 break;
2658 sec = elf_section_by_name(elf, &shdr, ".note", NULL);
2659 if (sec)
2660 break;
2662 return err;
2664 } while (0);
2666 data = elf_getdata(sec, NULL);
2667 if (data == NULL)
2668 goto out;
2670 ptr = data->d_buf;
2671 while (ptr < (data->d_buf + data->d_size)) {
2672 GElf_Nhdr *nhdr = ptr;
2673 size_t namesz = NOTE_ALIGN(nhdr->n_namesz),
2674 descsz = NOTE_ALIGN(nhdr->n_descsz);
2675 const char *name;
2677 ptr += sizeof(*nhdr);
2678 name = ptr;
2679 ptr += namesz;
2680 if (nhdr->n_type == NT_GNU_BUILD_ID &&
2681 nhdr->n_namesz == sizeof("GNU")) {
2682 if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
2683 size_t sz = min(size, descsz);
2684 memcpy(bf, ptr, sz);
2685 memset(bf + sz, 0, size - sz);
2686 err = descsz;
2687 break;
2690 ptr += descsz;
2693 out:
2694 return err;
2697 static int filename__read_build_id(const char *filename, void *bf, size_t size)
2699 int fd, err = -1;
2700 Elf *elf;
2702 if (size < BUILD_ID_SIZE)
2703 goto out;
2705 fd = open(filename, O_RDONLY);
2706 if (fd < 0)
2707 goto out;
2709 elf = elf_begin(fd, ELF_C_READ, NULL);
2710 if (elf == NULL) {
2711 fprintf(stderr, "%s: cannot read %s ELF file.\n", __func__, filename);
2712 goto out_close;
2715 err = elf_read_build_id(elf, bf, size);
2717 elf_end(elf);
2718 out_close:
2719 close(fd);
2720 out:
2721 return err;
2724 static int build_id__sprintf(const unsigned char *build_id, int len, char *bf)
2726 char *bid = bf;
2727 const unsigned char *raw = build_id;
2728 int i;
2730 for (i = 0; i < len; ++i) {
2731 sprintf(bid, "%02x", *raw);
2732 ++raw;
2733 bid += 2;
2736 return (bid - bf) + 1;
2739 static int sysfs__sprintf_build_id(const char *root_dir, char *sbuild_id)
2741 char notes[PATH_MAX];
2742 unsigned char build_id[BUILD_ID_SIZE];
2743 int ret;
2745 if (!root_dir)
2746 root_dir = "";
2748 snprintf(notes, sizeof(notes), "%s/sys/kernel/notes", root_dir);
2750 ret = sysfs__read_build_id(notes, build_id, sizeof(build_id));
2751 if (ret < 0)
2752 return ret;
2754 return build_id__sprintf(build_id, sizeof(build_id), sbuild_id);
2757 static int filename__sprintf_build_id(const char *pathname, char *sbuild_id)
2759 unsigned char build_id[BUILD_ID_SIZE];
2760 int ret;
2762 ret = filename__read_build_id(pathname, build_id, sizeof(build_id));
2763 if (ret < 0)
2764 return ret;
2765 else if (ret != sizeof(build_id))
2766 return -EINVAL;
2768 return build_id__sprintf(build_id, sizeof(build_id), sbuild_id);
2771 static int vmlinux_path__nr_entries;
2772 static char **vmlinux_path;
2774 const char *vmlinux_path__btf_filename(void)
2776 static const char *vmlinux_btf;
2778 if (vmlinux_btf == NULL) {
2779 vmlinux_btf = getenv("PAHOLE_VMLINUX_BTF_FILENAME");
2780 if (vmlinux_btf == NULL)
2781 vmlinux_btf = "/sys/kernel/btf/vmlinux";
2784 return vmlinux_btf;
2787 static void vmlinux_path__exit(void)
2789 while (--vmlinux_path__nr_entries >= 0)
2790 zfree(&vmlinux_path[vmlinux_path__nr_entries]);
2791 vmlinux_path__nr_entries = 0;
2793 zfree(&vmlinux_path);
2796 static const char * const vmlinux_paths[] = {
2797 "vmlinux",
2798 "/boot/vmlinux"
2801 static const char * const vmlinux_paths_upd[] = {
2802 "/boot/vmlinux-%s",
2803 "/usr/lib/debug/boot/vmlinux-%s",
2804 "/lib/modules/%s/build/vmlinux",
2805 "/usr/lib/debug/lib/modules/%s/vmlinux",
2806 "/usr/lib/debug/boot/vmlinux-%s.debug"
2809 static int vmlinux_path__add(const char *new_entry)
2811 vmlinux_path[vmlinux_path__nr_entries] = strdup(new_entry);
2812 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2813 return -1;
2814 ++vmlinux_path__nr_entries;
2816 return 0;
2819 static int vmlinux_path__add_debuginfod_client(void)
2821 const char *home_dir = getenv("HOME");
2822 if (home_dir == NULL)
2823 return -1;
2825 char running_sbuild_id[SBUILD_ID_SIZE];
2827 if (sysfs__sprintf_build_id(NULL, running_sbuild_id) < 0)
2828 return -1;
2830 char bf[PATH_MAX];
2831 snprintf(bf, sizeof(bf), "%s/.cache/debuginfod_client/%s/debuginfo", home_dir, running_sbuild_id);
2833 return vmlinux_path__add(bf);
2836 static int vmlinux_path__init(void)
2838 struct utsname uts;
2839 char bf[PATH_MAX];
2840 char *kernel_version;
2841 unsigned int i;
2843 // Add 1 for the debuginfod client HOME based cache
2844 vmlinux_path = malloc(sizeof(char *) * (ARRAY_SIZE(vmlinux_paths) +
2845 ARRAY_SIZE(vmlinux_paths_upd) + 1));
2846 if (vmlinux_path == NULL)
2847 return -1;
2849 for (i = 0; i < ARRAY_SIZE(vmlinux_paths); i++)
2850 if (vmlinux_path__add(vmlinux_paths[i]) < 0)
2851 goto out_fail;
2853 if (uname(&uts) < 0)
2854 goto out_fail;
2856 kernel_version = uts.release;
2858 for (i = 0; i < ARRAY_SIZE(vmlinux_paths_upd); i++) {
2859 snprintf(bf, sizeof(bf), vmlinux_paths_upd[i], kernel_version);
2860 if (vmlinux_path__add(bf) < 0)
2861 goto out_fail;
2864 vmlinux_path__add_debuginfod_client();
2866 return 0;
2868 out_fail:
2869 vmlinux_path__exit();
2870 return -1;
2873 static const char *__vmlinux_path__find_running_kernel(void)
2875 char running_sbuild_id[SBUILD_ID_SIZE];
2877 sysfs__sprintf_build_id(NULL, running_sbuild_id);
2879 for (int i = 0; i < vmlinux_path__nr_entries; ++i) {
2880 char sbuild_id[SBUILD_ID_SIZE];
2882 if (filename__sprintf_build_id(vmlinux_path[i], sbuild_id) > 0 &&
2883 strcmp(sbuild_id, running_sbuild_id) == 0) {
2884 return vmlinux_path[i];
2888 return NULL;
2891 const char *vmlinux_path__find_running_kernel(void)
2893 elf_version(EV_CURRENT);
2894 vmlinux_path__init();
2896 const char *vmlinux = __vmlinux_path__find_running_kernel();
2898 if (vmlinux) {
2899 // vmlinux_path__exit() will nuke all its entries
2900 vmlinux = strdup(vmlinux);
2903 vmlinux_path__exit();
2905 return vmlinux;
2908 static int cus__load_running_kernel(struct cus *cus, struct conf_load *conf)
2910 int err = 0;
2911 bool btf_only = false;
2913 if (!conf || conf->format_path == NULL)
2914 goto try_btf;
2916 if (!strstr(conf->format_path, "btf"))
2917 goto try_elf;
2919 btf_only = strcmp(conf->format_path, "btf") == 0;
2920 try_btf:
2921 if (access(vmlinux_path__btf_filename(), R_OK) == 0) {
2922 int loader = debugging_formats__loader("btf");
2923 if (loader == -1)
2924 goto try_elf;
2926 if (conf && conf->conf_fprintf)
2927 conf->conf_fprintf->has_alignment_info = debug_fmt_table[loader]->has_alignment_info;
2929 if (debug_fmt_table[loader]->load_file(cus, conf, vmlinux_path__btf_filename()) == 0)
2930 return 0;
2932 try_elf:
2933 if (btf_only)
2934 return -1;
2936 elf_version(EV_CURRENT);
2937 vmlinux_path__init();
2939 const char *vmlinux = __vmlinux_path__find_running_kernel();
2941 err = cus__load_file(cus, conf, vmlinux);
2943 vmlinux_path__exit();
2945 return err;
2948 int cus__load_files(struct cus *cus, struct conf_load *conf,
2949 char *filenames[])
2951 int i = 0;
2953 while (filenames[i] != NULL) {
2954 int err = cus__load_file(cus, conf, filenames[i]);
2955 if (err) {
2956 errno = -err;
2957 return -++i;
2959 ++i;
2962 return i ? 0 : cus__load_running_kernel(cus, conf);
2965 int cus__fprintf_load_files_err(struct cus *cus __maybe_unused, const char *tool, char *argv[], int err, FILE *output)
2967 /* errno is not properly preserved in some cases, sigh */
2968 return fprintf(output, "%s: %s: %s\n", tool, argv[-err - 1],
2969 errno ? strerror(errno) : "No debugging information found");
2972 struct cus *cus__new(void)
2974 struct cus *cus = zalloc(sizeof(*cus));
2976 if (cus != NULL) {
2977 INIT_LIST_HEAD(&cus->cus);
2978 pthread_mutex_init(&cus->mutex, NULL);
2981 return cus;
2984 void cus__delete(struct cus *cus)
2986 struct cu *pos, *n;
2988 if (cus == NULL)
2989 return;
2991 cus__lock(cus);
2993 list_for_each_entry_safe(pos, n, &cus->cus, node) {
2994 list_del_init(&pos->node);
2995 cu__delete(pos);
2998 if (cus->loader_exit)
2999 cus->loader_exit(cus);
3001 cus__unlock(cus);
3003 free(cus);
3006 void cus__set_priv(struct cus *cus, void *priv)
3008 cus->priv = priv;
3011 void *cus__priv(struct cus *cus)
3013 return cus->priv;
3016 void cus__set_loader_exit(struct cus *cus, void (*loader_exit)(struct cus *cus))
3018 cus->loader_exit = loader_exit;
3021 int dwarves__init(void)
3023 int i = 0;
3024 int err = 0;
3026 while (debug_fmt_table[i] != NULL) {
3027 if (debug_fmt_table[i]->init) {
3028 err = debug_fmt_table[i]->init();
3029 if (err)
3030 goto out_fail;
3032 ++i;
3035 return 0;
3036 out_fail:
3037 while (i-- != 0)
3038 if (debug_fmt_table[i]->exit)
3039 debug_fmt_table[i]->exit();
3040 return err;
3043 void dwarves__exit(void)
3045 int i = 0;
3047 while (debug_fmt_table[i] != NULL) {
3048 if (debug_fmt_table[i]->exit)
3049 debug_fmt_table[i]->exit();
3050 ++i;
3054 struct argp_state;
3056 void dwarves_print_version(FILE *fp, struct argp_state *state __maybe_unused)
3058 fprintf(fp, "v%u.%u\n", DWARVES_MAJOR_VERSION, DWARVES_MINOR_VERSION);
3061 bool print_numeric_version;
3063 void dwarves_print_numeric_version(FILE *fp)
3065 fprintf(fp, "%u%u\n", DWARVES_MAJOR_VERSION, DWARVES_MINOR_VERSION);