1 /* ctfdump.c: CTF dumper.
3 * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
27 static void *tag__alloc(const size_t size
)
29 struct tag
*tag
= zalloc(size
);
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
)
41 proto
->tag
.type
= type
;
42 INIT_LIST_HEAD(&proto
->parms
);
45 for (i
= 0; i
< vlen
; i
++) {
46 uint16_t type
= ctf__get16(ctf
, &args
[i
]);
49 proto
->unspec_parms
= 1;
51 struct parameter
*p
= tag__alloc(sizeof(*p
));
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
72 cu__add_tag(ctf
->priv
, &proto
->tag
, &type_id
);
74 cu__add_tag_with_id(ctf
->priv
, &proto
->tag
, id
);
83 static struct function
*function__new(uint16_t **ptr
, GElf_Sym
*sym
,
86 struct function
*func
= tag__alloc(sizeof(*func
));
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
);
104 if (tag
!= CTF_TYPE_KIND_FUNC
) {
106 "%s: Expected function type, got %u\n",
110 uint16_t type
= ctf__get16(ctf
, *ptr
);
111 long id
= -1; /* FIXME: not needed for funcs... */
115 if (ctf__load_ftype(ctf
, &func
->proto
, DW_TAG_subprogram
,
116 type
, vlen
, *ptr
, id
) < 0)
119 * Round up to next multiple of 4 to maintain 32-bit alignment.
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
));
140 ctf__for_each_symtab_function(ctf
, idx
, sym
)
141 if (function__new(&func_ptr
, &sym
, ctf
) == NULL
)
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
));
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
);
165 static void type__init(struct type
*type
, uint16_t tag
, const char *name
, size_t size
)
168 INIT_LIST_HEAD(&type
->namespace.tags
);
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
));
179 type__init(type
, tag
, name
, size
);
184 static struct class *class__new(const char *name
, size_t size
)
186 struct class *class = tag__alloc(sizeof(*class));
189 type__init(&class->type
, DW_TAG_structure_type
, name
, size
);
190 INIT_LIST_HEAD(&class->vtable
);
196 static int create_new_base_type(struct ctf
*ctf
, void *ptr
,
197 struct ctf_full_type
*tp
, uint32_t id
)
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
));
208 base
->tag
.tag
= DW_TAG_base_type
;
209 cu__add_tag_with_id(ctf
->priv
, &base
->tag
, id
);
214 static int create_new_base_type_float(struct ctf
*ctf
, void *ptr
,
215 struct ctf_full_type
*tp
,
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
));
225 base
->tag
.tag
= DW_TAG_base_type
;
226 cu__add_tag_with_id(ctf
->priv
, &base
->tag
, id
);
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
));
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
) {
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
);
258 static int create_new_subroutine_type(struct ctf
*ctf
, void *ptr
,
259 int vlen
, struct ctf_full_type
*tp
,
262 uint16_t *args
= ptr
;
263 unsigned int type
= ctf__get16(ctf
, &tp
->base
.ctf_type
);
264 struct ftype
*proto
= tag__alloc(sizeof(*proto
));
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
;
280 for (i
= 0; i
< vlen
; i
++) {
281 struct class_member
*member
= zalloc(sizeof(*member
));
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
);
298 static int create_short_members(struct ctf
*ctf
, void *ptr
,
299 int vlen
, struct type
*class)
301 struct ctf_short_member
*mp
= ptr
;
304 for (i
= 0; i
< vlen
; i
++) {
305 struct class_member
*member
= zalloc(sizeof(*member
));
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
);
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
)
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
);
333 member_size
= create_short_members(ctf
, ptr
, vlen
, &class->type
);
339 cu__add_tag_with_id(ctf
->priv
, &class->type
.namespace.tag
, id
);
341 return (vlen
* member_size
);
343 class__delete(class);
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
)
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
);
358 member_size
= create_short_members(ctf
, ptr
, vlen
, un
);
364 cu__add_tag_with_id(ctf
->priv
, &un
->namespace.tag
, id
);
366 return (vlen
* member_size
);
372 static struct enumerator
*enumerator__new(const char *name
, uint32_t value
)
374 struct enumerator
*en
= tag__alloc(sizeof(*en
));
379 en
->tag
.tag
= DW_TAG_enumerator
;
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
;
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
)
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
)
405 enumeration__add(enumeration
, enumerator
);
408 cu__add_tag_with_id(ctf
->priv
, &enumeration
->namespace.tag
, id
);
410 return (vlen
* sizeof(*ep
));
412 enumeration__delete(enumeration
);
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
);
424 fwd
->type
.declaration
= 1;
425 cu__add_tag_with_id(ctf
->priv
, &fwd
->type
.namespace.tag
, id
);
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
);
439 type
->namespace.tag
.type
= type_id
;
440 cu__add_tag_with_id(ctf
->priv
, &type
->namespace.tag
, id
);
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
));
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;
461 printf("%s: unknown type %d\n\n", __func__
, type
);
466 cu__add_tag_with_id(ctf
->priv
, tag
, id
);
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
);
496 size
|= ctf__get32(ctf
, &type_ptr
->ctf_size_low
);
497 ptr
+= sizeof(struct ctf_full_type
);
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
,
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
);
530 "CTF: idx: %d, off: %zd, root: %s Unknown\n",
531 type_index
, ((void *)type_ptr
) - type_section
,
532 CTF_ISROOT(val
) ? "yes" : "no");
540 type_ptr
= ptr
+ vlen
;
546 static struct variable
*variable__new(uint16_t type
, GElf_Sym
*sym
,
549 struct variable
*var
= tag__alloc(sizeof(*var
));
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
);
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
));
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
)
587 static int ctf__load_sections(struct ctf
*ctf
)
589 int err
= ctf__load_symtab(ctf
);
593 err
= ctf__load_funcs(ctf
);
595 err
= ctf__load_types(ctf
);
597 err
= ctf__load_objects(ctf
);
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... */
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
;
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);
627 integral_bit_size
= sizeof(int) * 8;
629 case DW_TAG_base_type
: {
630 struct base_type
*bt
= tag__base_type(type
);
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
)));
640 pos
->byte_size
= tag__size(type
, cu
);
641 pos
->bit_size
= pos
->byte_size
* 8;
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
;
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);
669 static int cu__fixup_ctf_bitfields(struct cu
*cu
)
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
);
684 static void ctf__cu_delete(struct cu
*cu
)
686 ctf__delete(cu
->priv
);
690 struct debug_fmt_ops ctf__ops
;
692 int ctf__load_file(struct cus
*cus
, struct conf_load
*conf
,
693 const char *filename
)
696 struct ctf
*state
= ctf__new(filename
, NULL
);
701 struct cu
*cu
= cu__new(filename
, state
->wordsize
, NULL
, 0, filename
, false);
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
;
711 if (ctf__load(state
) != 0)
714 err
= ctf__load_sections(state
);
721 err
= cu__fixup_ctf_bitfields(cu
);
723 * The app stole this cu, possibly deleting it,
726 if (conf
&& conf
->steal
&& conf
->steal(cu
, conf
, NULL
))
733 struct debug_fmt_ops ctf__ops
= {
735 .load_file
= ctf__load_file
,
736 .cu__delete
= ctf__cu_delete
,