1
/* ctfdump.c: CTF dumper.
3
* Copyright (C) 2008 David S. Miller <davem@davemloft.net>
28
* FIXME: We should just get the table from the CTF ELF section
31
extern struct strings *strings;
33
static void *tag__alloc(const size_t size)
35
struct tag *self = zalloc(size);
43
static int ctf__load_ftype(struct ctf *self, struct ftype *proto, uint16_t tag,
44
uint16_t type, uint16_t vlen, uint16_t *args, long id)
47
proto->tag.type = type;
48
INIT_LIST_HEAD(&proto->parms);
51
for (i = 0; i < vlen; i++) {
52
uint16_t type = ctf__get16(self, &args[i]);
55
proto->unspec_parms = 1;
57
struct parameter *p = tag__alloc(sizeof(*p));
60
goto out_free_parameters;
61
p->tag.tag = DW_TAG_formal_parameter;
62
p->tag.type = ctf__get16(self, &args[i]);
63
ftype__add_parameter(proto, p);
67
vlen *= sizeof(*args);
69
/* Round up to next multiple of 4 to maintain
75
cu__add_tag(self->priv, &proto->tag, &id);
79
ftype__delete(proto, self->priv);
83
static struct function *function__new(uint16_t **ptr, GElf_Sym *sym,
86
struct function *self = tag__alloc(sizeof(*self));
89
self->lexblock.ip.addr = elf_sym__value(sym);
90
self->lexblock.size = elf_sym__size(sym);
91
self->name = sym->st_name;
92
self->vtable_entry = -1;
93
self->external = elf_sym__bind(sym) == STB_GLOBAL;
94
INIT_LIST_HEAD(&self->vtable_node);
95
INIT_LIST_HEAD(&self->tool_node);
96
INIT_LIST_HEAD(&self->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, &self->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 *self)
134
struct ctf_header *hp = ctf__get_buffer(self);
135
uint16_t *func_ptr = (ctf__get_buffer(self) + sizeof(*hp) +
136
ctf__get32(self, &hp->ctf_func_off));
140
ctf__for_each_symtab_function(self, idx, sym)
141
if (function__new(&func_ptr, &sym, self) == NULL)
147
static struct base_type *base_type__new(strings_t name, uint32_t attrs,
148
uint8_t float_type, size_t size)
150
struct base_type *self = tag__alloc(sizeof(*self));
154
self->bit_size = size;
155
self->is_signed = attrs & CTF_TYPE_INT_SIGNED;
156
self->is_bool = attrs & CTF_TYPE_INT_BOOL;
157
self->is_varargs = attrs & CTF_TYPE_INT_VARARGS;
158
self->name_has_encoding = false;
159
self->float_type = float_type;
164
static void type__init(struct type *self, uint16_t tag,
165
strings_t name, size_t size)
167
INIT_LIST_HEAD(&self->node);
168
INIT_LIST_HEAD(&self->namespace.tags);
170
self->namespace.tag.tag = tag;
171
self->namespace.name = name;
172
self->namespace.sname = 0;
175
static struct type *type__new(uint16_t tag, strings_t name, size_t size)
177
struct type *self = tag__alloc(sizeof(*self));
180
type__init(self, tag, name, size);
185
static struct class *class__new(strings_t name, size_t size)
187
struct class *self = tag__alloc(sizeof(*self));
190
type__init(&self->type, DW_TAG_structure_type, name, size);
191
INIT_LIST_HEAD(&self->vtable);
197
static int create_new_base_type(struct ctf *self, void *ptr,
198
struct ctf_full_type *tp, long id)
201
uint32_t eval = ctf__get32(self, enc);
202
uint32_t attrs = CTF_TYPE_INT_ATTRS(eval);
203
strings_t name = ctf__get32(self, &tp->base.ctf_name);
204
struct base_type *base = base_type__new(name, attrs, 0,
205
CTF_TYPE_INT_BITS(eval));
209
base->tag.tag = DW_TAG_base_type;
210
cu__add_tag(self->priv, &base->tag, &id);
215
static int create_new_base_type_float(struct ctf *self, void *ptr,
216
struct ctf_full_type *tp,
219
strings_t name = ctf__get32(self, &tp->base.ctf_name);
220
uint32_t *enc = ptr, eval = ctf__get32(self, enc);
221
struct base_type *base = base_type__new(name, 0, eval,
222
CTF_TYPE_FP_BITS(eval));
226
base->tag.tag = DW_TAG_base_type;
227
cu__add_tag(self->priv, &base->tag, &id);
232
static int create_new_array(struct ctf *self, void *ptr, long id)
234
struct ctf_array *ap = ptr;
235
struct array_type *array = tag__alloc(sizeof(*array));
240
/* FIXME: where to get the number of dimensions?
241
* it it flattened? */
242
array->dimensions = 1;
243
array->nr_entries = malloc(sizeof(uint32_t));
245
if (array->nr_entries == NULL) {
250
array->nr_entries[0] = ctf__get32(self, &ap->ctf_array_nelems);
251
array->tag.tag = DW_TAG_array_type;
252
array->tag.type = ctf__get16(self, &ap->ctf_array_type);
254
cu__add_tag(self->priv, &array->tag, &id);
259
static int create_new_subroutine_type(struct ctf *self, void *ptr,
260
int vlen, struct ctf_full_type *tp,
263
uint16_t *args = ptr;
264
unsigned int type = ctf__get16(self, &tp->base.ctf_type);
265
struct ftype *proto = tag__alloc(sizeof(*proto));
270
vlen = ctf__load_ftype(self, proto, DW_TAG_subroutine_type,
271
type, vlen, args, id);
272
return vlen < 0 ? -ENOMEM : vlen;
275
static int create_full_members(struct ctf *self, void *ptr,
276
int vlen, struct type *class)
278
struct ctf_full_member *mp = ptr;
281
for (i = 0; i < vlen; i++) {
282
struct class_member *member = zalloc(sizeof(*member));
287
member->tag.tag = DW_TAG_member;
288
member->tag.type = ctf__get16(self, &mp[i].ctf_member_type);
289
member->name = ctf__get32(self, &mp[i].ctf_member_name);
290
member->bit_offset = (ctf__get32(self, &mp[i].ctf_member_offset_high) << 16) |
291
ctf__get32(self, &mp[i].ctf_member_offset_low);
292
/* sizes and offsets will be corrected at class__fixup_ctf_bitfields */
293
type__add_member(class, member);
299
static int create_short_members(struct ctf *self, void *ptr,
300
int vlen, struct type *class)
302
struct ctf_short_member *mp = ptr;
305
for (i = 0; i < vlen; i++) {
306
struct class_member *member = zalloc(sizeof(*member));
311
member->tag.tag = DW_TAG_member;
312
member->tag.type = ctf__get16(self, &mp[i].ctf_member_type);
313
member->name = ctf__get32(self, &mp[i].ctf_member_name);
314
member->bit_offset = ctf__get16(self, &mp[i].ctf_member_offset);
315
/* sizes and offsets will be corrected at class__fixup_ctf_bitfields */
317
type__add_member(class, member);
323
static int create_new_class(struct ctf *self, void *ptr,
324
int vlen, struct ctf_full_type *tp,
325
uint64_t size, long id)
328
strings_t name = ctf__get32(self, &tp->base.ctf_name);
329
struct class *class = class__new(name, size);
331
if (size >= CTF_SHORT_MEMBER_LIMIT) {
332
member_size = create_full_members(self, ptr, vlen, &class->type);
334
member_size = create_short_members(self, ptr, vlen, &class->type);
340
cu__add_tag(self->priv, &class->type.namespace.tag, &id);
342
return (vlen * member_size);
344
class__delete(class, self->priv);
348
static int create_new_union(struct ctf *self, void *ptr,
349
int vlen, struct ctf_full_type *tp,
350
uint64_t size, long id)
353
strings_t name = ctf__get32(self, &tp->base.ctf_name);
354
struct type *un = type__new(DW_TAG_union_type, name, size);
356
if (size >= CTF_SHORT_MEMBER_LIMIT) {
357
member_size = create_full_members(self, ptr, vlen, un);
359
member_size = create_short_members(self, ptr, vlen, un);
365
cu__add_tag(self->priv, &un->namespace.tag, &id);
367
return (vlen * member_size);
369
type__delete(un, self->priv);
373
static struct enumerator *enumerator__new(strings_t name, uint32_t value)
375
struct enumerator *self = tag__alloc(sizeof(*self));
380
self->tag.tag = DW_TAG_enumerator;
386
static int create_new_enumeration(struct ctf *self, void *ptr,
387
int vlen, struct ctf_full_type *tp,
388
uint16_t size, long id)
390
struct ctf_enum *ep = ptr;
392
struct type *enumeration = type__new(DW_TAG_enumeration_type,
395
size ?: (sizeof(int) * 8));
397
if (enumeration == NULL)
400
for (i = 0; i < vlen; i++) {
401
strings_t name = ctf__get32(self, &ep[i].ctf_enum_name);
402
uint32_t value = ctf__get32(self, &ep[i].ctf_enum_val);
403
struct enumerator *enumerator = enumerator__new(name, value);
405
if (enumerator == NULL)
408
enumeration__add(enumeration, enumerator);
411
cu__add_tag(self->priv, &enumeration->namespace.tag, &id);
413
return (vlen * sizeof(*ep));
415
enumeration__delete(enumeration, self->priv);
419
static int create_new_forward_decl(struct ctf *self, struct ctf_full_type *tp,
420
uint64_t size, long id)
422
strings_t name = ctf__get32(self, &tp->base.ctf_name);
423
struct class *fwd = class__new(name, size);
427
fwd->type.declaration = 1;
428
cu__add_tag(self->priv, &fwd->type.namespace.tag, &id);
432
static int create_new_typedef(struct ctf *self, struct ctf_full_type *tp,
433
uint64_t size, long id)
435
strings_t name = ctf__get32(self, &tp->base.ctf_name);
436
unsigned int type_id = ctf__get16(self, &tp->base.ctf_type);
437
struct type *type = type__new(DW_TAG_typedef, name, size);
442
type->namespace.tag.type = type_id;
443
cu__add_tag(self->priv, &type->namespace.tag, &id);
448
static int create_new_tag(struct ctf *self, int type,
449
struct ctf_full_type *tp, long id)
451
unsigned int type_id = ctf__get16(self, &tp->base.ctf_type);
452
struct tag *tag = zalloc(sizeof(*tag));
458
case CTF_TYPE_KIND_CONST: tag->tag = DW_TAG_const_type; break;
459
case CTF_TYPE_KIND_PTR: tag->tag = DW_TAG_pointer_type; break;
460
case CTF_TYPE_KIND_RESTRICT: tag->tag = DW_TAG_restrict_type; break;
461
case CTF_TYPE_KIND_VOLATILE: tag->tag = DW_TAG_volatile_type; break;
463
printf("%s: FOO %d\n\n", __func__, type);
468
cu__add_tag(self->priv, tag, &id);
473
static int ctf__load_types(struct ctf *self)
475
void *ctf_buffer = ctf__get_buffer(self);
476
struct ctf_header *hp = ctf_buffer;
477
void *ctf_contents = ctf_buffer + sizeof(*hp),
478
*type_section = (ctf_contents +
479
ctf__get32(self, &hp->ctf_type_off)),
480
*strings_section = (ctf_contents +
481
ctf__get32(self, &hp->ctf_str_off));
482
struct ctf_full_type *type_ptr = type_section,
483
*end = strings_section;
484
unsigned int type_index = 0x0001;
486
if (hp->ctf_parent_name || hp->ctf_parent_label)
487
type_index += 0x8000;
489
while (type_ptr < end) {
490
uint16_t val = ctf__get16(self, &type_ptr->base.ctf_info);
491
uint16_t type = CTF_GET_KIND(val);
492
int vlen = CTF_GET_VLEN(val);
493
void *ptr = type_ptr;
494
uint16_t base_size = ctf__get16(self, &type_ptr->base.ctf_size);
495
uint64_t size = base_size;
497
if (base_size == 0xffff) {
498
size = ctf__get32(self, &type_ptr->ctf_size_high);
500
size |= ctf__get32(self, &type_ptr->ctf_size_low);
501
ptr += sizeof(struct ctf_full_type);
503
ptr += sizeof(struct ctf_short_type);
505
if (type == CTF_TYPE_KIND_INT) {
506
vlen = create_new_base_type(self, ptr, type_ptr, type_index);
507
} else if (type == CTF_TYPE_KIND_FLT) {
508
vlen = create_new_base_type_float(self, ptr, type_ptr, type_index);
509
} else if (type == CTF_TYPE_KIND_ARR) {
510
vlen = create_new_array(self, ptr, type_index);
511
} else if (type == CTF_TYPE_KIND_FUNC) {
512
vlen = create_new_subroutine_type(self, ptr, vlen, type_ptr, type_index);
513
} else if (type == CTF_TYPE_KIND_STR) {
514
vlen = create_new_class(self, ptr,
515
vlen, type_ptr, size, type_index);
516
} else if (type == CTF_TYPE_KIND_UNION) {
517
vlen = create_new_union(self, ptr,
518
vlen, type_ptr, size, type_index);
519
} else if (type == CTF_TYPE_KIND_ENUM) {
520
vlen = create_new_enumeration(self, ptr, vlen, type_ptr,
522
} else if (type == CTF_TYPE_KIND_FWD) {
523
vlen = create_new_forward_decl(self, type_ptr, size, type_index);
524
} else if (type == CTF_TYPE_KIND_TYPDEF) {
525
vlen = create_new_typedef(self, type_ptr, size, type_index);
526
} else if (type == CTF_TYPE_KIND_VOLATILE ||
527
type == CTF_TYPE_KIND_PTR ||
528
type == CTF_TYPE_KIND_CONST ||
529
type == CTF_TYPE_KIND_RESTRICT) {
530
vlen = create_new_tag(self, type, type_ptr, type_index);
531
} else if (type == CTF_TYPE_KIND_UNKN) {
532
cu__table_nullify_type_entry(self->priv, type_index);
534
"CTF: idx: %d, off: %zd, root: %s Unknown\n",
535
type_index, ((void *)type_ptr) - type_section,
536
CTF_ISROOT(val) ? "yes" : "no");
544
type_ptr = ptr + vlen;
550
static struct variable *variable__new(uint16_t type, GElf_Sym *sym,
553
struct variable *self = tag__alloc(sizeof(*self));
556
self->location = LOCATION_GLOBAL;
557
self->ip.addr = elf_sym__value(sym);
558
self->name = sym->st_name;
559
self->external = elf_sym__bind(sym) == STB_GLOBAL;
560
self->ip.tag.tag = DW_TAG_variable;
561
self->ip.tag.type = type;
562
long id = -1; /* FIXME: not needed for variables... */
563
cu__add_tag(ctf->priv, &self->ip.tag, &id);
569
static int ctf__load_objects(struct ctf *self)
571
struct ctf_header *hp = ctf__get_buffer(self);
572
uint16_t *objp = (ctf__get_buffer(self) + sizeof(*hp) +
573
ctf__get32(self, &hp->ctf_object_off));
577
ctf__for_each_symtab_object(self, idx, sym) {
578
const uint16_t type = *objp;
580
* Discard void objects, probably was an object
581
* we didn't found DWARF info for when encoding.
583
if (type && variable__new(type, &sym, self) == NULL)
591
static int ctf__load_sections(struct ctf *self)
593
int err = ctf__load_symtab(self);
597
err = ctf__load_funcs(self);
599
err = ctf__load_types(self);
601
err = ctf__load_objects(self);
606
static int class__fixup_ctf_bitfields(struct tag *self, struct cu *cu)
608
struct class_member *pos;
609
struct type *type_self = tag__type(self);
611
type__for_each_data_member(type_self, pos) {
612
struct tag *type = tag__follow_typedef(&pos->tag, cu);
614
if (type == NULL) /* FIXME: C++ CTF... */
617
pos->bitfield_offset = 0;
618
pos->bitfield_size = 0;
619
pos->byte_offset = pos->bit_offset / 8;
621
uint16_t type_bit_size;
622
size_t integral_bit_size;
625
case DW_TAG_enumeration_type:
626
type_bit_size = tag__type(type)->size;
627
/* Best we can do to check if this is a packed enum */
628
if (is_power_of_2(type_bit_size))
629
integral_bit_size = roundup(type_bit_size, 8);
631
integral_bit_size = sizeof(int) * 8;
633
case DW_TAG_base_type: {
634
struct base_type *bt = tag__base_type(type);
636
type_bit_size = bt->bit_size;
637
integral_bit_size = base_type__name_to_size(bt, cu);
638
if (integral_bit_size == 0)
639
fprintf(stderr, "%s: unknown base type name \"%s\"!\n",
640
__func__, base_type__name(bt, cu, name,
645
pos->byte_size = tag__size(type, cu);
646
pos->bit_size = pos->byte_size * 8;
651
* XXX: integral_bit_size can be zero if base_type__name_to_size doesn't
652
* know about the base_type name, so one has to add there when
653
* such base_type isn't found. pahole will put zero on the
654
* struct output so it should be easy to spot the name when
655
* such unlikely thing happens.
657
pos->byte_size = integral_bit_size / 8;
659
if (integral_bit_size == 0 || type_bit_size == integral_bit_size) {
660
pos->bit_size = integral_bit_size;
664
pos->bitfield_offset = pos->bit_offset % integral_bit_size;
665
pos->bitfield_size = type_bit_size;
666
pos->bit_size = type_bit_size;
667
pos->byte_offset = (((pos->bit_offset / integral_bit_size) *
668
integral_bit_size) / 8);
674
static int cu__fixup_ctf_bitfields(struct cu *self)
679
list_for_each_entry(pos, &self->tags, node)
680
if (tag__is_struct(pos) || tag__is_union(pos)) {
681
err = class__fixup_ctf_bitfields(pos, self);
689
static const char *ctf__function_name(struct function *self,
692
struct ctf *ctf = cu->priv;
694
return ctf->symtab->symstrs->d_buf + self->name;
697
static const char *ctf__variable_name(const struct variable *self,
700
struct ctf *ctf = cu->priv;
702
return ctf->symtab->symstrs->d_buf + self->name;
705
static void ctf__cu_delete(struct cu *self)
707
ctf__delete(self->priv);
711
static const char *ctf__strings_ptr(const struct cu *self, strings_t s)
713
return ctf__string(self->priv, s);
716
struct debug_fmt_ops ctf__ops;
718
int ctf__load_file(struct cus *self, struct conf_load *conf,
719
const char *filename)
722
struct ctf *state = ctf__new(filename, NULL);
727
struct cu *cu = cu__new(filename, state->wordsize, NULL, 0, filename);
731
cu->language = LANG_C;
732
cu->uses_global_strings = false;
733
cu->dfops = &ctf__ops;
736
if (ctf__load(state) != 0)
739
err = ctf__load_sections(state);
746
err = cu__fixup_ctf_bitfields(cu);
748
* The app stole this cu, possibly deleting it,
751
if (conf && conf->steal && conf->steal(cu, conf))
758
struct debug_fmt_ops ctf__ops = {
760
.function__name = ctf__function_name,
761
.load_file = ctf__load_file,
762
.variable__name = ctf__variable_name,
763
.strings__ptr = ctf__strings_ptr,
764
.cu__delete = ctf__cu_delete,