~ubuntu-branches/ubuntu/precise/dwarves-dfsg/precise

« back to all changes in this revision

Viewing changes to ctf_loader.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Girard
  • Date: 2011-05-02 19:34:31 UTC
  • mfrom: (1.1.1 upstream) (2.1.3 maverick)
  • Revision ID: james.westby@ubuntu.com-20110502193431-xd7eeb4sarnmyd7e
Tags: 1.9-1
* Acknowledge 1.3-1.1 NMU (thanks to Michael Banck) and resynch with
  Ubuntu release (thanks Bhavani Shankar).
* New upstream release:
  - patch from 1.3-1.1ubuntu1 no longer needed.
  - new manpage for pahole.
  - new program scncopy to copy ELF sections.
  - fixes crash when encountering a pointer in a struct. Closes: #513573.
  - recognizes C++ classes. Closes: #621530.
  - no longer FTBFS with gcc 4.6. Closes: #625158.
* Remove libebl detection and use. Closes: #534529.
* debian/control:
  - bump debhelper level to 7.
  - add Vcs-Git: and Vcs-Browser:
  - bump Standards-Version: to 3.9.2.
  - add zlib1g-dev build dependency.
* debian/copyright: add missing copyright holders.
* debian/rules:
  - allow to be compiled twice in a row.
  - ensure package building aborts if a program is not installed.
  - use dh_prep instead of dh_clean -k.
* debian/dwarves.install:
  - include syscse. Closes: #517180.
  - add ctracer. See README.ctracer for information on how to use it.
* Switch to dpkg-source 3.0 (quilt) format.
* Fix many lintian warnings.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ctfdump.c: CTF dumper.
 
2
 *
 
3
 * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
 
4
 */
 
5
 
 
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>
 
19
 
 
20
#include <gelf.h>
 
21
 
 
22
#include "libctf.h"
 
23
#include "ctf.h"
 
24
#include "dutil.h"
 
25
#include "dwarves.h"
 
26
 
 
27
/*
 
28
 * FIXME: We should just get the table from the CTF ELF section
 
29
 * and use it directly
 
30
 */
 
31
extern struct strings *strings;
 
32
 
 
33
static void *tag__alloc(const size_t size)
 
34
{
 
35
        struct tag *self = zalloc(size);
 
36
 
 
37
        if (self != NULL)
 
38
                self->top_level = 1;
 
39
 
 
40
        return self;
 
41
}
 
42
 
 
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)
 
45
{
 
46
        proto->tag.tag  = tag;
 
47
        proto->tag.type = type;
 
48
        INIT_LIST_HEAD(&proto->parms);
 
49
 
 
50
        int i;
 
51
        for (i = 0; i < vlen; i++) {
 
52
                uint16_t type = ctf__get16(self, &args[i]);
 
53
 
 
54
                if (type == 0)
 
55
                        proto->unspec_parms = 1;
 
56
                else {
 
57
                        struct parameter *p = tag__alloc(sizeof(*p));
 
58
 
 
59
                        if (p == NULL)
 
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);
 
64
                }
 
65
        }
 
66
 
 
67
        vlen *= sizeof(*args);
 
68
 
 
69
        /* Round up to next multiple of 4 to maintain
 
70
         * 32-bit alignment.
 
71
         */
 
72
        if (vlen & 0x2)
 
73
                vlen += 0x2;
 
74
 
 
75
        cu__add_tag(self->priv, &proto->tag, &id);
 
76
 
 
77
        return vlen;
 
78
out_free_parameters:
 
79
        ftype__delete(proto, self->priv);
 
80
        return -ENOMEM;
 
81
}
 
82
 
 
83
static struct function *function__new(uint16_t **ptr, GElf_Sym *sym,
 
84
                                      struct ctf *ctf)
 
85
{
 
86
        struct function *self = tag__alloc(sizeof(*self));
 
87
 
 
88
        if (self != NULL) {
 
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);
 
97
 
 
98
                uint16_t val = ctf__get16(ctf, *ptr);
 
99
                uint16_t tag = CTF_GET_KIND(val);
 
100
                uint16_t vlen = CTF_GET_VLEN(val);
 
101
 
 
102
                ++*ptr;
 
103
 
 
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;
 
109
                }
 
110
                uint16_t type = ctf__get16(ctf, *ptr);
 
111
                long id = -1; /* FIXME: not needed for funcs... */
 
112
 
 
113
                ++*ptr;
 
114
 
 
115
                if (ctf__load_ftype(ctf, &self->proto, DW_TAG_subprogram,
 
116
                                    type, vlen, *ptr, id) < 0)
 
117
                        return NULL;
 
118
                /*
 
119
                 * Round up to next multiple of 4 to maintain 32-bit alignment.
 
120
                 */
 
121
                if (vlen & 0x1)
 
122
                        ++vlen;
 
123
                *ptr += vlen;
 
124
        }
 
125
 
 
126
        return self;
 
127
out_delete:
 
128
        free(self);
 
129
        return NULL;
 
130
}
 
131
 
 
132
static int ctf__load_funcs(struct ctf *self)
 
133
{
 
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));
 
137
 
 
138
        GElf_Sym sym;
 
139
        uint32_t idx;
 
140
        ctf__for_each_symtab_function(self, idx, sym)
 
141
                if (function__new(&func_ptr, &sym, self) == NULL)
 
142
                        return -ENOMEM;
 
143
 
 
144
        return 0;
 
145
}
 
146
 
 
147
static struct base_type *base_type__new(strings_t name, uint32_t attrs,
 
148
                                        uint8_t float_type, size_t size)
 
149
{
 
150
        struct base_type *self = tag__alloc(sizeof(*self));
 
151
 
 
152
        if (self != NULL) {
 
153
                self->name = name;
 
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;
 
160
        }
 
161
        return self;
 
162
}
 
163
 
 
164
static void type__init(struct type *self, uint16_t tag,
 
165
                       strings_t name, size_t size)
 
166
{
 
167
        INIT_LIST_HEAD(&self->node);
 
168
        INIT_LIST_HEAD(&self->namespace.tags);
 
169
        self->size = size;
 
170
        self->namespace.tag.tag = tag;
 
171
        self->namespace.name = name;
 
172
        self->namespace.sname = 0;
 
173
}
 
174
 
 
175
static struct type *type__new(uint16_t tag, strings_t name, size_t size)
 
176
{
 
177
        struct type *self = tag__alloc(sizeof(*self));
 
178
 
 
179
        if (self != NULL)
 
180
                type__init(self, tag, name, size);
 
181
 
 
182
        return self;
 
183
}
 
184
 
 
185
static struct class *class__new(strings_t name, size_t size)
 
186
{
 
187
        struct class *self = tag__alloc(sizeof(*self));
 
188
 
 
189
        if (self != NULL) {
 
190
                type__init(&self->type, DW_TAG_structure_type, name, size);
 
191
                INIT_LIST_HEAD(&self->vtable);
 
192
        }
 
193
 
 
194
        return self;
 
195
}
 
196
 
 
197
static int create_new_base_type(struct ctf *self, void *ptr,
 
198
                                struct ctf_full_type *tp, long id)
 
199
{
 
200
        uint32_t *enc = ptr;
 
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));
 
206
        if (base == NULL)
 
207
                return -ENOMEM;
 
208
 
 
209
        base->tag.tag = DW_TAG_base_type;
 
210
        cu__add_tag(self->priv, &base->tag, &id);
 
211
 
 
212
        return sizeof(*enc);
 
213
}
 
214
 
 
215
static int create_new_base_type_float(struct ctf *self, void *ptr,
 
216
                                      struct ctf_full_type *tp,
 
217
                                      long id)
 
218
{
 
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));
 
223
        if (base == NULL)
 
224
                return -ENOMEM;
 
225
 
 
226
        base->tag.tag = DW_TAG_base_type;
 
227
        cu__add_tag(self->priv, &base->tag, &id);
 
228
 
 
229
        return sizeof(*enc);
 
230
}
 
231
 
 
232
static int create_new_array(struct ctf *self, void *ptr, long id)
 
233
{
 
234
        struct ctf_array *ap = ptr;
 
235
        struct array_type *array = tag__alloc(sizeof(*array));
 
236
 
 
237
        if (array == NULL)
 
238
                return -ENOMEM;
 
239
 
 
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));
 
244
 
 
245
        if (array->nr_entries == NULL) {
 
246
                free(array);
 
247
                return -ENOMEM;
 
248
        }
 
249
 
 
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);
 
253
 
 
254
        cu__add_tag(self->priv, &array->tag, &id);
 
255
 
 
256
        return sizeof(*ap);
 
257
}
 
258
 
 
259
static int create_new_subroutine_type(struct ctf *self, void *ptr,
 
260
                                      int vlen, struct ctf_full_type *tp,
 
261
                                      long id)
 
262
{
 
263
        uint16_t *args = ptr;
 
264
        unsigned int type = ctf__get16(self, &tp->base.ctf_type);
 
265
        struct ftype *proto = tag__alloc(sizeof(*proto));
 
266
 
 
267
        if (proto == NULL)
 
268
                return -ENOMEM;
 
269
 
 
270
        vlen = ctf__load_ftype(self, proto, DW_TAG_subroutine_type,
 
271
                               type, vlen, args, id);
 
272
        return vlen < 0 ? -ENOMEM : vlen;
 
273
}
 
274
 
 
275
static int create_full_members(struct ctf *self, void *ptr,
 
276
                               int vlen, struct type *class)
 
277
{
 
278
        struct ctf_full_member *mp = ptr;
 
279
        int i;
 
280
 
 
281
        for (i = 0; i < vlen; i++) {
 
282
                struct class_member *member = zalloc(sizeof(*member));
 
283
 
 
284
                if (member == NULL)
 
285
                        return -ENOMEM;
 
286
 
 
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);
 
294
        }
 
295
 
 
296
        return sizeof(*mp);
 
297
}
 
298
 
 
299
static int create_short_members(struct ctf *self, void *ptr,
 
300
                                int vlen, struct type *class)
 
301
{
 
302
        struct ctf_short_member *mp = ptr;
 
303
        int i;
 
304
 
 
305
        for (i = 0; i < vlen; i++) {
 
306
                struct class_member *member = zalloc(sizeof(*member));
 
307
 
 
308
                if (member == NULL)
 
309
                        return -ENOMEM;
 
310
 
 
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 */
 
316
 
 
317
                type__add_member(class, member);
 
318
        }
 
319
 
 
320
        return sizeof(*mp);
 
321
}
 
322
 
 
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)
 
326
{
 
327
        int member_size;
 
328
        strings_t name = ctf__get32(self, &tp->base.ctf_name);
 
329
        struct class *class = class__new(name, size);
 
330
 
 
331
        if (size >= CTF_SHORT_MEMBER_LIMIT) {
 
332
                member_size = create_full_members(self, ptr, vlen, &class->type);
 
333
        } else {
 
334
                member_size = create_short_members(self, ptr, vlen, &class->type);
 
335
        }
 
336
 
 
337
        if (member_size < 0)
 
338
                goto out_free;
 
339
 
 
340
        cu__add_tag(self->priv, &class->type.namespace.tag, &id);
 
341
 
 
342
        return (vlen * member_size);
 
343
out_free:
 
344
        class__delete(class, self->priv);
 
345
        return -ENOMEM;
 
346
}
 
347
 
 
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)
 
351
{
 
352
        int member_size;
 
353
        strings_t name = ctf__get32(self, &tp->base.ctf_name);
 
354
        struct type *un = type__new(DW_TAG_union_type, name, size);
 
355
 
 
356
        if (size >= CTF_SHORT_MEMBER_LIMIT) {
 
357
                member_size = create_full_members(self, ptr, vlen, un);
 
358
        } else {
 
359
                member_size = create_short_members(self, ptr, vlen, un);
 
360
        }
 
361
 
 
362
        if (member_size < 0)
 
363
                goto out_free;
 
364
 
 
365
        cu__add_tag(self->priv, &un->namespace.tag, &id);
 
366
 
 
367
        return (vlen * member_size);
 
368
out_free:
 
369
        type__delete(un, self->priv);
 
370
        return -ENOMEM;
 
371
}
 
372
 
 
373
static struct enumerator *enumerator__new(strings_t name, uint32_t value)
 
374
{
 
375
        struct enumerator *self = tag__alloc(sizeof(*self));
 
376
 
 
377
        if (self != NULL) {
 
378
                self->name = name;
 
379
                self->value = value;
 
380
                self->tag.tag = DW_TAG_enumerator;
 
381
        }
 
382
 
 
383
        return self;
 
384
}
 
385
 
 
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)
 
389
{
 
390
        struct ctf_enum *ep = ptr;
 
391
        uint16_t i;
 
392
        struct type *enumeration = type__new(DW_TAG_enumeration_type,
 
393
                                             ctf__get32(self,
 
394
                                                        &tp->base.ctf_name),
 
395
                                             size ?: (sizeof(int) * 8));
 
396
 
 
397
        if (enumeration == NULL)
 
398
                return -ENOMEM;
 
399
 
 
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);
 
404
 
 
405
                if (enumerator == NULL)
 
406
                        goto out_free;
 
407
 
 
408
                enumeration__add(enumeration, enumerator);
 
409
        }
 
410
 
 
411
        cu__add_tag(self->priv, &enumeration->namespace.tag, &id);
 
412
 
 
413
        return (vlen * sizeof(*ep));
 
414
out_free:
 
415
        enumeration__delete(enumeration, self->priv);
 
416
        return -ENOMEM;
 
417
}
 
418
 
 
419
static int create_new_forward_decl(struct ctf *self, struct ctf_full_type *tp,
 
420
                                   uint64_t size, long id)
 
421
{
 
422
        strings_t name = ctf__get32(self, &tp->base.ctf_name);
 
423
        struct class *fwd = class__new(name, size);
 
424
 
 
425
        if (fwd == NULL)
 
426
                return -ENOMEM;
 
427
        fwd->type.declaration = 1;
 
428
        cu__add_tag(self->priv, &fwd->type.namespace.tag, &id);
 
429
        return 0;
 
430
}
 
431
 
 
432
static int create_new_typedef(struct ctf *self, struct ctf_full_type *tp,
 
433
                              uint64_t size, long id)
 
434
{
 
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);
 
438
 
 
439
        if (type == NULL)
 
440
                return -ENOMEM;
 
441
 
 
442
        type->namespace.tag.type = type_id;
 
443
        cu__add_tag(self->priv, &type->namespace.tag, &id);
 
444
 
 
445
        return 0;
 
446
}
 
447
 
 
448
static int create_new_tag(struct ctf *self, int type,
 
449
                          struct ctf_full_type *tp, long id)
 
450
{
 
451
        unsigned int type_id = ctf__get16(self, &tp->base.ctf_type);
 
452
        struct tag *tag = zalloc(sizeof(*tag));
 
453
 
 
454
        if (tag == NULL)
 
455
                return -ENOMEM;
 
456
 
 
457
        switch (type) {
 
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;
 
462
        default:
 
463
                printf("%s: FOO %d\n\n", __func__, type);
 
464
                return 0;
 
465
        }
 
466
 
 
467
        tag->type = type_id;
 
468
        cu__add_tag(self->priv, tag, &id);
 
469
 
 
470
        return 0;
 
471
}
 
472
 
 
473
static int ctf__load_types(struct ctf *self)
 
474
{
 
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;
 
485
 
 
486
        if (hp->ctf_parent_name || hp->ctf_parent_label)
 
487
                type_index += 0x8000;
 
488
 
 
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;
 
496
 
 
497
                if (base_size == 0xffff) {
 
498
                        size = ctf__get32(self, &type_ptr->ctf_size_high);
 
499
                        size <<= 32;
 
500
                        size |= ctf__get32(self, &type_ptr->ctf_size_low);
 
501
                        ptr += sizeof(struct ctf_full_type);
 
502
                } else
 
503
                        ptr += sizeof(struct ctf_short_type);
 
504
 
 
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,
 
521
                                                      size, type_index);
 
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);
 
533
                        fprintf(stderr,
 
534
                                "CTF: idx: %d, off: %zd, root: %s Unknown\n",
 
535
                                type_index, ((void *)type_ptr) - type_section,
 
536
                                CTF_ISROOT(val) ? "yes" : "no");
 
537
                        vlen = 0;
 
538
                } else
 
539
                        return -EINVAL;
 
540
 
 
541
                if (vlen < 0)
 
542
                        return vlen;
 
543
 
 
544
                type_ptr = ptr + vlen;
 
545
                type_index++;
 
546
        }
 
547
        return 0;
 
548
}
 
549
 
 
550
static struct variable *variable__new(uint16_t type, GElf_Sym *sym,
 
551
                                      struct ctf *ctf)
 
552
{
 
553
        struct variable *self = tag__alloc(sizeof(*self));
 
554
 
 
555
        if (self != NULL) {
 
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);
 
564
        }
 
565
 
 
566
        return self;
 
567
}
 
568
 
 
569
static int ctf__load_objects(struct ctf *self)
 
570
{
 
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));
 
574
 
 
575
        GElf_Sym sym;
 
576
        uint32_t idx;
 
577
        ctf__for_each_symtab_object(self, idx, sym) {
 
578
                const uint16_t type = *objp;
 
579
                /*
 
580
                 * Discard void objects, probably was an object
 
581
                 * we didn't found DWARF info for when encoding.
 
582
                 */
 
583
                if (type && variable__new(type, &sym, self) == NULL)
 
584
                        return -ENOMEM;
 
585
                ++objp;
 
586
        }
 
587
 
 
588
        return 0;
 
589
}
 
590
 
 
591
static int ctf__load_sections(struct ctf *self)
 
592
{
 
593
        int err = ctf__load_symtab(self);
 
594
 
 
595
        if (err != 0)
 
596
                goto out;
 
597
        err = ctf__load_funcs(self);
 
598
        if (err == 0)
 
599
                err = ctf__load_types(self);
 
600
        if (err == 0)
 
601
                err = ctf__load_objects(self);
 
602
out:
 
603
        return err;
 
604
}
 
605
 
 
606
static int class__fixup_ctf_bitfields(struct tag *self, struct cu *cu)
 
607
{
 
608
        struct class_member *pos;
 
609
        struct type *type_self = tag__type(self);
 
610
 
 
611
        type__for_each_data_member(type_self, pos) {
 
612
                struct tag *type = tag__follow_typedef(&pos->tag, cu);
 
613
 
 
614
                if (type == NULL) /* FIXME: C++ CTF... */
 
615
                        continue;
 
616
 
 
617
                pos->bitfield_offset = 0;
 
618
                pos->bitfield_size = 0;
 
619
                pos->byte_offset = pos->bit_offset / 8;
 
620
 
 
621
                uint16_t type_bit_size;
 
622
                size_t integral_bit_size;
 
623
 
 
624
                switch (type->tag) {
 
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);
 
630
                        else
 
631
                                integral_bit_size = sizeof(int) * 8;
 
632
                        break;
 
633
                case DW_TAG_base_type: {
 
634
                        struct base_type *bt = tag__base_type(type);
 
635
                        char name[256];
 
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,
 
641
                                                                  sizeof(name)));
 
642
                }
 
643
                        break;
 
644
                default:
 
645
                        pos->byte_size = tag__size(type, cu);
 
646
                        pos->bit_size = pos->byte_size * 8;
 
647
                        continue;
 
648
                }
 
649
 
 
650
                /*
 
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.
 
656
                 */
 
657
                pos->byte_size = integral_bit_size / 8;
 
658
 
 
659
                if (integral_bit_size == 0 || type_bit_size == integral_bit_size) {
 
660
                        pos->bit_size = integral_bit_size;
 
661
                        continue;
 
662
                }
 
663
 
 
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);
 
669
        }
 
670
 
 
671
        return 0;
 
672
}
 
673
 
 
674
static int cu__fixup_ctf_bitfields(struct cu *self)
 
675
{
 
676
        int err = 0;
 
677
        struct tag *pos;
 
678
 
 
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);
 
682
                        if (err)
 
683
                                break;
 
684
                }
 
685
 
 
686
        return err;
 
687
}
 
688
 
 
689
static const char *ctf__function_name(struct function *self,
 
690
                                      const struct cu *cu)
 
691
{
 
692
        struct ctf *ctf = cu->priv;
 
693
 
 
694
        return ctf->symtab->symstrs->d_buf + self->name;
 
695
}
 
696
 
 
697
static const char *ctf__variable_name(const struct variable *self,
 
698
                                      const struct cu *cu)
 
699
{
 
700
        struct ctf *ctf = cu->priv;
 
701
 
 
702
        return ctf->symtab->symstrs->d_buf + self->name;
 
703
}
 
704
 
 
705
static void ctf__cu_delete(struct cu *self)
 
706
{
 
707
        ctf__delete(self->priv);
 
708
        self->priv = NULL;
 
709
}
 
710
 
 
711
static const char *ctf__strings_ptr(const struct cu *self, strings_t s)
 
712
{
 
713
        return ctf__string(self->priv, s);
 
714
}
 
715
 
 
716
struct debug_fmt_ops ctf__ops;
 
717
 
 
718
int ctf__load_file(struct cus *self, struct conf_load *conf,
 
719
                   const char *filename)
 
720
{
 
721
        int err;
 
722
        struct ctf *state = ctf__new(filename, NULL);
 
723
 
 
724
        if (state == NULL)
 
725
                return -1;
 
726
 
 
727
        struct cu *cu = cu__new(filename, state->wordsize, NULL, 0, filename);
 
728
        if (cu == NULL)
 
729
                return -1;
 
730
 
 
731
        cu->language = LANG_C;
 
732
        cu->uses_global_strings = false;
 
733
        cu->dfops = &ctf__ops;
 
734
        cu->priv = state;
 
735
        state->priv = cu;
 
736
        if (ctf__load(state) != 0)
 
737
                return -1;
 
738
 
 
739
        err = ctf__load_sections(state);
 
740
 
 
741
        if (err != 0) {
 
742
                cu__delete(cu);
 
743
                return err;
 
744
        }
 
745
 
 
746
        err = cu__fixup_ctf_bitfields(cu);
 
747
        /*
 
748
         * The app stole this cu, possibly deleting it,
 
749
         * so forget about it
 
750
         */
 
751
        if (conf && conf->steal && conf->steal(cu, conf))
 
752
                return 0;
 
753
 
 
754
        cus__add(self, cu);
 
755
        return err;
 
756
}
 
757
 
 
758
struct debug_fmt_ops ctf__ops = {
 
759
        .name           = "ctf",
 
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,
 
765
};