pahole: Describe expected use of 'default' in the man page
[dwarves.git] / ctf_loader.c
blob2570b0946851d80f18c654f876d620bdb8588d7b
1 /* ctfdump.c: CTF dumper.
3 * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
4 */
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <stdio.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <stddef.h>
14 #include <malloc.h>
15 #include <string.h>
16 #include <limits.h>
17 #include <libgen.h>
18 #include <zlib.h>
20 #include <gelf.h>
22 #include "libctf.h"
23 #include "ctf.h"
24 #include "dutil.h"
25 #include "dwarves.h"
27 static void *tag__alloc(const size_t size)
29 struct tag *tag = zalloc(size);
31 if (tag != NULL)
32 tag->top_level = 1;
34 return tag;
37 static int ctf__load_ftype(struct ctf *ctf, struct ftype *proto, uint16_t tag,
38 uint16_t type, uint16_t vlen, uint16_t *args, long id)
40 proto->tag.tag = tag;
41 proto->tag.type = type;
42 INIT_LIST_HEAD(&proto->parms);
44 int i;
45 for (i = 0; i < vlen; i++) {
46 uint16_t type = ctf__get16(ctf, &args[i]);
48 if (type == 0)
49 proto->unspec_parms = 1;
50 else {
51 struct parameter *p = tag__alloc(sizeof(*p));
53 if (p == NULL)
54 goto out_free_parameters;
55 p->tag.tag = DW_TAG_formal_parameter;
56 p->tag.type = ctf__get16(ctf, &args[i]);
57 ftype__add_parameter(proto, p);
61 vlen *= sizeof(*args);
63 /* Round up to next multiple of 4 to maintain
64 * 32-bit alignment.
66 if (vlen & 0x2)
67 vlen += 0x2;
69 if (id < 0) {
70 uint32_t type_id;
72 cu__add_tag(ctf->priv, &proto->tag, &type_id);
73 } else {
74 cu__add_tag_with_id(ctf->priv, &proto->tag, id);
77 return vlen;
78 out_free_parameters:
79 ftype__delete(proto);
80 return -ENOMEM;
83 static struct function *function__new(uint16_t **ptr, GElf_Sym *sym,
84 struct ctf *ctf)
86 struct function *func = tag__alloc(sizeof(*func));
88 if (func != NULL) {
89 func->lexblock.ip.addr = elf_sym__value(sym);
90 func->lexblock.size = elf_sym__size(sym);
91 func->name = elf_sym__name(sym, ctf->symtab);
92 func->vtable_entry = -1;
93 func->external = elf_sym__bind(sym) == STB_GLOBAL;
94 INIT_LIST_HEAD(&func->vtable_node);
95 INIT_LIST_HEAD(&func->tool_node);
96 INIT_LIST_HEAD(&func->lexblock.tags);
98 uint16_t val = ctf__get16(ctf, *ptr);
99 uint16_t tag = CTF_GET_KIND(val);
100 uint16_t vlen = CTF_GET_VLEN(val);
102 ++*ptr;
104 if (tag != CTF_TYPE_KIND_FUNC) {
105 fprintf(stderr,
106 "%s: Expected function type, got %u\n",
107 __func__, tag);
108 goto out_delete;
110 uint16_t type = ctf__get16(ctf, *ptr);
111 long id = -1; /* FIXME: not needed for funcs... */
113 ++*ptr;
115 if (ctf__load_ftype(ctf, &func->proto, DW_TAG_subprogram,
116 type, vlen, *ptr, id) < 0)
117 return NULL;
119 * Round up to next multiple of 4 to maintain 32-bit alignment.
121 if (vlen & 0x1)
122 ++vlen;
123 *ptr += vlen;
126 return func;
127 out_delete:
128 free(func);
129 return NULL;
132 static int ctf__load_funcs(struct ctf *ctf)
134 struct ctf_header *hp = ctf__get_buffer(ctf);
135 uint16_t *func_ptr = (ctf__get_buffer(ctf) + sizeof(*hp) +
136 ctf__get32(ctf, &hp->ctf_func_off));
138 GElf_Sym sym;
139 uint32_t idx;
140 ctf__for_each_symtab_function(ctf, idx, sym)
141 if (function__new(&func_ptr, &sym, ctf) == NULL)
142 return -ENOMEM;
144 return 0;
147 static struct base_type *base_type__new(const char *name, uint32_t attrs,
148 uint8_t float_type, size_t size)
150 struct base_type *bt = tag__alloc(sizeof(*bt));
152 if (bt != NULL) {
153 bt->name = name;
154 bt->bit_size = size;
155 bt->is_signed = attrs & CTF_TYPE_INT_SIGNED;
156 bt->is_bool = attrs & CTF_TYPE_INT_BOOL;
157 bt->is_varargs = attrs & CTF_TYPE_INT_VARARGS;
158 bt->name_has_encoding = false;
159 bt->float_type = float_type;
160 INIT_LIST_HEAD(&bt->node);
162 return bt;
165 static void type__init(struct type *type, uint16_t tag, const char *name, size_t size)
167 __type__init(type);
168 INIT_LIST_HEAD(&type->namespace.tags);
169 type->size = size;
170 type->namespace.tag.tag = tag;
171 type->namespace.name = name;
174 static struct type *type__new(uint16_t tag, const char *name, size_t size)
176 struct type *type = tag__alloc(sizeof(*type));
178 if (type != NULL)
179 type__init(type, tag, name, size);
181 return type;
184 static struct class *class__new(const char *name, size_t size)
186 struct class *class = tag__alloc(sizeof(*class));
188 if (class != NULL) {
189 type__init(&class->type, DW_TAG_structure_type, name, size);
190 INIT_LIST_HEAD(&class->vtable);
193 return class;
196 static int create_new_base_type(struct ctf *ctf, void *ptr,
197 struct ctf_full_type *tp, uint32_t id)
199 uint32_t *enc = ptr;
200 uint32_t eval = ctf__get32(ctf, enc);
201 uint32_t attrs = CTF_TYPE_INT_ATTRS(eval);
202 uint32_t name = ctf__get32(ctf, &tp->base.ctf_name);
203 struct base_type *base = base_type__new(ctf__string(ctf, name), attrs, 0,
204 CTF_TYPE_INT_BITS(eval));
205 if (base == NULL)
206 return -ENOMEM;
208 base->tag.tag = DW_TAG_base_type;
209 cu__add_tag_with_id(ctf->priv, &base->tag, id);
211 return sizeof(*enc);
214 static int create_new_base_type_float(struct ctf *ctf, void *ptr,
215 struct ctf_full_type *tp,
216 uint32_t id)
218 uint32_t name = ctf__get32(ctf, &tp->base.ctf_name);
219 uint32_t *enc = ptr, eval = ctf__get32(ctf, enc);
220 struct base_type *base = base_type__new(ctf__string(ctf, name), 0, eval,
221 CTF_TYPE_FP_BITS(eval));
222 if (base == NULL)
223 return -ENOMEM;
225 base->tag.tag = DW_TAG_base_type;
226 cu__add_tag_with_id(ctf->priv, &base->tag, id);
228 return sizeof(*enc);
231 static int create_new_array(struct ctf *ctf, void *ptr, uint32_t id)
233 struct ctf_array *ap = ptr;
234 struct array_type *array = tag__alloc(sizeof(*array));
236 if (array == NULL)
237 return -ENOMEM;
239 /* FIXME: where to get the number of dimensions?
240 * it it flattened? */
241 array->dimensions = 1;
242 array->nr_entries = malloc(sizeof(uint32_t));
244 if (array->nr_entries == NULL) {
245 free(array);
246 return -ENOMEM;
249 array->nr_entries[0] = ctf__get32(ctf, &ap->ctf_array_nelems);
250 array->tag.tag = DW_TAG_array_type;
251 array->tag.type = ctf__get16(ctf, &ap->ctf_array_type);
253 cu__add_tag_with_id(ctf->priv, &array->tag, id);
255 return sizeof(*ap);
258 static int create_new_subroutine_type(struct ctf *ctf, void *ptr,
259 int vlen, struct ctf_full_type *tp,
260 uint32_t id)
262 uint16_t *args = ptr;
263 unsigned int type = ctf__get16(ctf, &tp->base.ctf_type);
264 struct ftype *proto = tag__alloc(sizeof(*proto));
266 if (proto == NULL)
267 return -ENOMEM;
269 vlen = ctf__load_ftype(ctf, proto, DW_TAG_subroutine_type,
270 type, vlen, args, id);
271 return vlen < 0 ? -ENOMEM : vlen;
274 static int create_full_members(struct ctf *ctf, void *ptr,
275 int vlen, struct type *class)
277 struct ctf_full_member *mp = ptr;
278 int i;
280 for (i = 0; i < vlen; i++) {
281 struct class_member *member = zalloc(sizeof(*member));
283 if (member == NULL)
284 return -ENOMEM;
286 member->tag.tag = DW_TAG_member;
287 member->tag.type = ctf__get16(ctf, &mp[i].ctf_member_type);
288 member->name = ctf__string(ctf, ctf__get32(ctf, &mp[i].ctf_member_name));
289 member->bit_offset = (ctf__get32(ctf, &mp[i].ctf_member_offset_high) << 16) |
290 ctf__get32(ctf, &mp[i].ctf_member_offset_low);
291 /* sizes and offsets will be corrected at class__fixup_ctf_bitfields */
292 type__add_member(class, member);
295 return sizeof(*mp);
298 static int create_short_members(struct ctf *ctf, void *ptr,
299 int vlen, struct type *class)
301 struct ctf_short_member *mp = ptr;
302 int i;
304 for (i = 0; i < vlen; i++) {
305 struct class_member *member = zalloc(sizeof(*member));
307 if (member == NULL)
308 return -ENOMEM;
310 member->tag.tag = DW_TAG_member;
311 member->tag.type = ctf__get16(ctf, &mp[i].ctf_member_type);
312 member->name = ctf__string(ctf, ctf__get32(ctf, &mp[i].ctf_member_name));
313 member->bit_offset = ctf__get16(ctf, &mp[i].ctf_member_offset);
314 /* sizes and offsets will be corrected at class__fixup_ctf_bitfields */
316 type__add_member(class, member);
319 return sizeof(*mp);
322 static int create_new_class(struct ctf *ctf, void *ptr,
323 int vlen, struct ctf_full_type *tp,
324 uint64_t size, uint32_t id)
326 int member_size;
327 const char *name = ctf__string(ctf, ctf__get32(ctf, &tp->base.ctf_name));
328 struct class *class = class__new(name, size);
330 if (size >= CTF_SHORT_MEMBER_LIMIT) {
331 member_size = create_full_members(ctf, ptr, vlen, &class->type);
332 } else {
333 member_size = create_short_members(ctf, ptr, vlen, &class->type);
336 if (member_size < 0)
337 goto out_free;
339 cu__add_tag_with_id(ctf->priv, &class->type.namespace.tag, id);
341 return (vlen * member_size);
342 out_free:
343 class__delete(class);
344 return -ENOMEM;
347 static int create_new_union(struct ctf *ctf, void *ptr,
348 int vlen, struct ctf_full_type *tp,
349 uint64_t size, uint32_t id)
351 int member_size;
352 const char *name = ctf__string(ctf, ctf__get32(ctf, &tp->base.ctf_name));
353 struct type *un = type__new(DW_TAG_union_type, name, size);
355 if (size >= CTF_SHORT_MEMBER_LIMIT) {
356 member_size = create_full_members(ctf, ptr, vlen, un);
357 } else {
358 member_size = create_short_members(ctf, ptr, vlen, un);
361 if (member_size < 0)
362 goto out_free;
364 cu__add_tag_with_id(ctf->priv, &un->namespace.tag, id);
366 return (vlen * member_size);
367 out_free:
368 type__delete(un);
369 return -ENOMEM;
372 static struct enumerator *enumerator__new(const char *name, uint32_t value)
374 struct enumerator *en = tag__alloc(sizeof(*en));
376 if (en != NULL) {
377 en->name = name;
378 en->value = value;
379 en->tag.tag = DW_TAG_enumerator;
382 return en;
385 static int create_new_enumeration(struct ctf *ctf, void *ptr,
386 int vlen, struct ctf_full_type *tp,
387 uint16_t size, uint32_t id)
389 struct ctf_enum *ep = ptr;
390 uint16_t i;
391 const char *name = ctf__string(ctf, ctf__get32(ctf, &tp->base.ctf_name));
392 struct type *enumeration = type__new(DW_TAG_enumeration_type, name, size ?: (sizeof(int) * 8));
394 if (enumeration == NULL)
395 return -ENOMEM;
397 for (i = 0; i < vlen; i++) {
398 const char *name = ctf__string(ctf, ctf__get32(ctf, &ep[i].ctf_enum_name));
399 uint32_t value = ctf__get32(ctf, &ep[i].ctf_enum_val);
400 struct enumerator *enumerator = enumerator__new(name, value);
402 if (enumerator == NULL)
403 goto out_free;
405 enumeration__add(enumeration, enumerator);
408 cu__add_tag_with_id(ctf->priv, &enumeration->namespace.tag, id);
410 return (vlen * sizeof(*ep));
411 out_free:
412 enumeration__delete(enumeration);
413 return -ENOMEM;
416 static int create_new_forward_decl(struct ctf *ctf, struct ctf_full_type *tp,
417 uint64_t size, uint32_t id)
419 const char *name = ctf__string(ctf, ctf__get32(ctf, &tp->base.ctf_name));
420 struct class *fwd = class__new(name, size);
422 if (fwd == NULL)
423 return -ENOMEM;
424 fwd->type.declaration = 1;
425 cu__add_tag_with_id(ctf->priv, &fwd->type.namespace.tag, id);
426 return 0;
429 static int create_new_typedef(struct ctf *ctf, struct ctf_full_type *tp,
430 uint64_t size, uint32_t id)
432 const char *name = ctf__string(ctf, ctf__get32(ctf, &tp->base.ctf_name));
433 unsigned int type_id = ctf__get16(ctf, &tp->base.ctf_type);
434 struct type *type = type__new(DW_TAG_typedef, name, size);
436 if (type == NULL)
437 return -ENOMEM;
439 type->namespace.tag.type = type_id;
440 cu__add_tag_with_id(ctf->priv, &type->namespace.tag, id);
442 return 0;
445 static int create_new_tag(struct ctf *ctf, int type,
446 struct ctf_full_type *tp, uint32_t id)
448 unsigned int type_id = ctf__get16(ctf, &tp->base.ctf_type);
449 struct tag *tag = zalloc(sizeof(*tag));
451 if (tag == NULL)
452 return -ENOMEM;
454 switch (type) {
455 case CTF_TYPE_KIND_CONST: tag->tag = DW_TAG_const_type; break;
456 case CTF_TYPE_KIND_PTR: tag->tag = DW_TAG_pointer_type; break;
457 case CTF_TYPE_KIND_RESTRICT: tag->tag = DW_TAG_restrict_type; break;
458 case CTF_TYPE_KIND_VOLATILE: tag->tag = DW_TAG_volatile_type; break;
459 default:
460 free(tag);
461 printf("%s: unknown type %d\n\n", __func__, type);
462 return 0;
465 tag->type = type_id;
466 cu__add_tag_with_id(ctf->priv, tag, id);
468 return 0;
471 static int ctf__load_types(struct ctf *ctf)
473 void *ctf_buffer = ctf__get_buffer(ctf);
474 struct ctf_header *hp = ctf_buffer;
475 void *ctf_contents = ctf_buffer + sizeof(*hp),
476 *type_section = (ctf_contents + ctf__get32(ctf, &hp->ctf_type_off)),
477 *strings_section = (ctf_contents + ctf__get32(ctf, &hp->ctf_str_off));
478 struct ctf_full_type *type_ptr = type_section,
479 *end = strings_section;
480 uint32_t type_index = 0x0001;
482 if (hp->ctf_parent_name || hp->ctf_parent_label)
483 type_index += 0x8000;
485 while (type_ptr < end) {
486 uint16_t val = ctf__get16(ctf, &type_ptr->base.ctf_info);
487 uint16_t type = CTF_GET_KIND(val);
488 int vlen = CTF_GET_VLEN(val);
489 void *ptr = type_ptr;
490 uint16_t base_size = ctf__get16(ctf, &type_ptr->base.ctf_size);
491 uint64_t size = base_size;
493 if (base_size == 0xffff) {
494 size = ctf__get32(ctf, &type_ptr->ctf_size_high);
495 size <<= 32;
496 size |= ctf__get32(ctf, &type_ptr->ctf_size_low);
497 ptr += sizeof(struct ctf_full_type);
498 } else
499 ptr += sizeof(struct ctf_short_type);
501 if (type == CTF_TYPE_KIND_INT) {
502 vlen = create_new_base_type(ctf, ptr, type_ptr, type_index);
503 } else if (type == CTF_TYPE_KIND_FLT) {
504 vlen = create_new_base_type_float(ctf, ptr, type_ptr, type_index);
505 } else if (type == CTF_TYPE_KIND_ARR) {
506 vlen = create_new_array(ctf, ptr, type_index);
507 } else if (type == CTF_TYPE_KIND_FUNC) {
508 vlen = create_new_subroutine_type(ctf, ptr, vlen, type_ptr, type_index);
509 } else if (type == CTF_TYPE_KIND_STR) {
510 vlen = create_new_class(ctf, ptr,
511 vlen, type_ptr, size, type_index);
512 } else if (type == CTF_TYPE_KIND_UNION) {
513 vlen = create_new_union(ctf, ptr,
514 vlen, type_ptr, size, type_index);
515 } else if (type == CTF_TYPE_KIND_ENUM) {
516 vlen = create_new_enumeration(ctf, ptr, vlen, type_ptr,
517 size, type_index);
518 } else if (type == CTF_TYPE_KIND_FWD) {
519 vlen = create_new_forward_decl(ctf, type_ptr, size, type_index);
520 } else if (type == CTF_TYPE_KIND_TYPDEF) {
521 vlen = create_new_typedef(ctf, type_ptr, size, type_index);
522 } else if (type == CTF_TYPE_KIND_VOLATILE ||
523 type == CTF_TYPE_KIND_PTR ||
524 type == CTF_TYPE_KIND_CONST ||
525 type == CTF_TYPE_KIND_RESTRICT) {
526 vlen = create_new_tag(ctf, type, type_ptr, type_index);
527 } else if (type == CTF_TYPE_KIND_UNKN) {
528 cu__table_nullify_type_entry(ctf->priv, type_index);
529 fprintf(stderr,
530 "CTF: idx: %d, off: %zd, root: %s Unknown\n",
531 type_index, ((void *)type_ptr) - type_section,
532 CTF_ISROOT(val) ? "yes" : "no");
533 vlen = 0;
534 } else
535 return -EINVAL;
537 if (vlen < 0)
538 return vlen;
540 type_ptr = ptr + vlen;
541 type_index++;
543 return 0;
546 static struct variable *variable__new(uint16_t type, GElf_Sym *sym,
547 struct ctf *ctf)
549 struct variable *var = tag__alloc(sizeof(*var));
551 if (var != NULL) {
552 var->scope = VSCOPE_GLOBAL;
553 var->ip.addr = elf_sym__value(sym);
554 var->name = ctf->symtab->symstrs->d_buf + sym->st_name;
555 var->external = elf_sym__bind(sym) == STB_GLOBAL;
556 var->ip.tag.tag = DW_TAG_variable;
557 var->ip.tag.type = type;
558 uint32_t id; /* FIXME: not needed for variables... */
559 cu__add_tag(ctf->priv, &var->ip.tag, &id);
562 return var;
565 static int ctf__load_objects(struct ctf *ctf)
567 struct ctf_header *hp = ctf__get_buffer(ctf);
568 uint16_t *objp = (ctf__get_buffer(ctf) + sizeof(*hp) +
569 ctf__get32(ctf, &hp->ctf_object_off));
571 GElf_Sym sym;
572 uint32_t idx;
573 ctf__for_each_symtab_object(ctf, idx, sym) {
574 const uint16_t type = *objp;
576 * Discard void objects, probably was an object
577 * we didn't found DWARF info for when encoding.
579 if (type && variable__new(type, &sym, ctf) == NULL)
580 return -ENOMEM;
581 ++objp;
584 return 0;
587 static int ctf__load_sections(struct ctf *ctf)
589 int err = ctf__load_symtab(ctf);
591 if (err != 0)
592 goto out;
593 err = ctf__load_funcs(ctf);
594 if (err == 0)
595 err = ctf__load_types(ctf);
596 if (err == 0)
597 err = ctf__load_objects(ctf);
598 out:
599 return err;
602 static int class__fixup_ctf_bitfields(struct tag *tag, struct cu *cu)
604 struct class_member *pos;
605 struct type *tag_type = tag__type(tag);
607 type__for_each_data_member(tag_type, pos) {
608 struct tag *type = tag__strip_typedefs_and_modifiers(&pos->tag, cu);
610 if (type == NULL) /* FIXME: C++ CTF... */
611 continue;
613 pos->bitfield_offset = 0;
614 pos->bitfield_size = 0;
615 pos->byte_offset = pos->bit_offset / 8;
617 uint16_t type_bit_size;
618 size_t integral_bit_size;
620 switch (type->tag) {
621 case DW_TAG_enumeration_type:
622 type_bit_size = tag__type(type)->size;
623 /* Best we can do to check if this is a packed enum */
624 if (is_power_of_2(type_bit_size))
625 integral_bit_size = roundup(type_bit_size, 8);
626 else
627 integral_bit_size = sizeof(int) * 8;
628 break;
629 case DW_TAG_base_type: {
630 struct base_type *bt = tag__base_type(type);
631 char name[256];
632 type_bit_size = bt->bit_size;
633 integral_bit_size = base_type__name_to_size(bt, cu);
634 if (integral_bit_size == 0)
635 fprintf(stderr, "%s: unknown base type name \"%s\"!\n",
636 __func__, base_type__name(bt, name, sizeof(name)));
638 break;
639 default:
640 pos->byte_size = tag__size(type, cu);
641 pos->bit_size = pos->byte_size * 8;
642 continue;
646 * XXX: integral_bit_size can be zero if base_type__name_to_size doesn't
647 * know about the base_type name, so one has to add there when
648 * such base_type isn't found. pahole will put zero on the
649 * struct output so it should be easy to spot the name when
650 * such unlikely thing happens.
652 pos->byte_size = integral_bit_size / 8;
654 if (integral_bit_size == 0 || type_bit_size == integral_bit_size) {
655 pos->bit_size = integral_bit_size;
656 continue;
659 pos->bitfield_offset = pos->bit_offset % integral_bit_size;
660 pos->bitfield_size = type_bit_size;
661 pos->bit_size = type_bit_size;
662 pos->byte_offset = (((pos->bit_offset / integral_bit_size) *
663 integral_bit_size) / 8);
666 return 0;
669 static int cu__fixup_ctf_bitfields(struct cu *cu)
671 int err = 0;
672 struct tag *pos;
674 list_for_each_entry(pos, &cu->tags, node)
675 if (tag__is_struct(pos) || tag__is_union(pos)) {
676 err = class__fixup_ctf_bitfields(pos, cu);
677 if (err)
678 break;
681 return err;
684 static void ctf__cu_delete(struct cu *cu)
686 ctf__delete(cu->priv);
687 cu->priv = NULL;
690 struct debug_fmt_ops ctf__ops;
692 int ctf__load_file(struct cus *cus, struct conf_load *conf,
693 const char *filename)
695 int err;
696 struct ctf *state = ctf__new(filename, NULL);
698 if (state == NULL)
699 return -1;
701 struct cu *cu = cu__new(filename, state->wordsize, NULL, 0, filename, false);
702 if (cu == NULL)
703 return -1;
705 cu->language = LANG_C;
706 cu->uses_global_strings = false;
707 cu->little_endian = state->ehdr.e_ident[EI_DATA] == ELFDATA2LSB;
708 cu->dfops = &ctf__ops;
709 cu->priv = state;
710 state->priv = cu;
711 if (ctf__load(state) != 0)
712 return -1;
714 err = ctf__load_sections(state);
716 if (err != 0) {
717 cu__delete(cu);
718 return err;
721 err = cu__fixup_ctf_bitfields(cu);
723 * The app stole this cu, possibly deleting it,
724 * so forget about it
726 if (conf && conf->steal && conf->steal(cu, conf, NULL))
727 return 0;
729 cus__add(cus, cu);
730 return err;
733 struct debug_fmt_ops ctf__ops = {
734 .name = "ctf",
735 .load_file = ctf__load_file,
736 .cu__delete = ctf__cu_delete,