2 SPDX-License-Identifier: GPL-2.0-only
4 Copyright (C) 2009 Red Hat Inc.
5 Copyright (C) 2009 Arnaldo Carvalho de Melo <acme@redhat.com>
12 #include "elf_symtab.h"
15 static int tag__check_id_drift(const struct tag
*tag
,
16 uint32_t core_id
, uint32_t ctf_id
)
18 if (ctf_id
!= core_id
) {
19 fprintf(stderr
, "%s: %s id drift, core: %u, libctf: %d\n",
20 __func__
, dwarf_tag_name(tag
->tag
), core_id
, ctf_id
);
26 static int dwarf_to_ctf_type(uint16_t tag
)
29 case DW_TAG_const_type
: return CTF_TYPE_KIND_CONST
;
30 case DW_TAG_pointer_type
: return CTF_TYPE_KIND_PTR
;
31 case DW_TAG_restrict_type
: return CTF_TYPE_KIND_RESTRICT
;
32 case DW_TAG_volatile_type
: return CTF_TYPE_KIND_VOLATILE
;
33 case DW_TAG_class_type
:
34 case DW_TAG_structure_type
: return CTF_TYPE_KIND_STR
;
35 case DW_TAG_union_type
: return CTF_TYPE_KIND_UNION
;
40 static int base_type__encode(struct tag
*tag
, uint32_t core_id
, struct ctf
*ctf
)
42 struct base_type
*bt
= tag__base_type(tag
);
43 uint32_t ctf_id
= ctf__add_base_type(ctf
, bt
->name
, bt
->bit_size
);
45 if (tag__check_id_drift(tag
, core_id
, ctf_id
))
51 static int pointer_type__encode(struct tag
*tag
, uint32_t core_id
, struct ctf
*ctf
)
53 uint32_t ctf_id
= ctf__add_short_type(ctf
, dwarf_to_ctf_type(tag
->tag
), tag
->type
, 0);
55 if (tag__check_id_drift(tag
, core_id
, ctf_id
))
61 static int typedef__encode(struct tag
*tag
, uint32_t core_id
, struct ctf
*ctf
)
63 uint32_t ctf_id
= ctf__add_short_type(ctf
, CTF_TYPE_KIND_TYPDEF
, tag
->type
, tag__namespace(tag
)->name
);
65 if (tag__check_id_drift(tag
, core_id
, ctf_id
))
71 static int fwd_decl__encode(struct tag
*tag
, uint32_t core_id
, struct ctf
*ctf
)
73 uint32_t ctf_id
= ctf__add_fwd_decl(ctf
, tag__namespace(tag
)->name
);
75 if (tag__check_id_drift(tag
, core_id
, ctf_id
))
81 static int structure_type__encode(struct tag
*tag
, uint32_t core_id
, struct ctf
*ctf
)
83 struct type
*type
= tag__type(tag
);
85 uint32_t ctf_id
= ctf__add_struct(ctf
, dwarf_to_ctf_type(tag
->tag
),
86 type
->namespace.name
, type
->size
,
87 type
->nr_members
, &position
);
89 if (tag__check_id_drift(tag
, core_id
, ctf_id
))
92 const bool is_short
= type
->size
< CTF_SHORT_MEMBER_LIMIT
;
93 struct class_member
*pos
;
94 type__for_each_data_member(type
, pos
) {
96 ctf__add_short_member(ctf
, pos
->name
, pos
->tag
.type
,
97 pos
->bit_offset
, &position
);
99 ctf__add_full_member(ctf
, pos
->name
, pos
->tag
.type
,
100 pos
->bit_offset
, &position
);
106 static uint32_t array_type__nelems(struct tag
*tag
)
110 struct array_type
*array
= tag__array_type(tag
);
112 for (i
= array
->dimensions
- 1; i
>= 0; --i
)
113 nelem
*= array
->nr_entries
[i
];
118 static int array_type__encode(struct tag
*tag
, uint32_t core_id
, struct ctf
*ctf
)
120 const uint32_t nelems
= array_type__nelems(tag
);
121 uint32_t ctf_id
= ctf__add_array(ctf
, tag
->type
, 0, nelems
);
123 if (tag__check_id_drift(tag
, core_id
, ctf_id
))
129 static int subroutine_type__encode(struct tag
*tag
, uint32_t core_id
, struct ctf
*ctf
)
131 struct parameter
*pos
;
133 struct ftype
*ftype
= tag__ftype(tag
);
134 uint32_t ctf_id
= ctf__add_function_type(ctf
, tag
->type
, ftype
->nr_parms
, ftype
->unspec_parms
, &position
);
136 if (tag__check_id_drift(tag
, core_id
, ctf_id
))
139 ftype__for_each_parameter(ftype
, pos
)
140 ctf__add_parameter(ctf
, pos
->tag
.type
, &position
);
145 static int enumeration_type__encode(struct tag
*tag
, uint32_t core_id
, struct ctf
*ctf
)
147 struct type
*etype
= tag__type(tag
);
149 uint32_t ctf_id
= ctf__add_enumeration_type(ctf
, etype
->namespace.name
,
150 etype
->size
, etype
->nr_members
,
153 if (tag__check_id_drift(tag
, core_id
, ctf_id
))
156 struct enumerator
*pos
;
157 type__for_each_enumerator(etype
, pos
)
158 ctf__add_enumerator(ctf
, pos
->name
, pos
->value
, &position
);
163 static void tag__encode_ctf(struct tag
*tag
, uint32_t core_id
, struct ctf
*ctf
)
166 case DW_TAG_base_type
:
167 base_type__encode(tag
, core_id
, ctf
);
169 case DW_TAG_const_type
:
170 case DW_TAG_pointer_type
:
171 case DW_TAG_restrict_type
:
172 case DW_TAG_volatile_type
:
173 pointer_type__encode(tag
, core_id
, ctf
);
176 typedef__encode(tag
, core_id
, ctf
);
178 case DW_TAG_structure_type
:
179 case DW_TAG_union_type
:
180 case DW_TAG_class_type
:
181 if (tag__type(tag
)->declaration
)
182 fwd_decl__encode(tag
, core_id
, ctf
);
184 structure_type__encode(tag
, core_id
, ctf
);
186 case DW_TAG_array_type
:
187 array_type__encode(tag
, core_id
, ctf
);
189 case DW_TAG_subroutine_type
:
190 subroutine_type__encode(tag
, core_id
, ctf
);
192 case DW_TAG_enumeration_type
:
193 enumeration_type__encode(tag
, core_id
, ctf
);
198 #define HASHADDR__BITS 8
199 #define HASHADDR__SIZE (1UL << HASHADDR__BITS)
200 #define hashaddr__fn(key) hash_64(key, HASHADDR__BITS)
202 static struct function
*hashaddr__find_function(const struct hlist_head hashtable
[],
205 struct function
*function
;
206 struct hlist_node
*pos
;
207 uint16_t bucket
= hashaddr__fn(addr
);
208 const struct hlist_head
*head
= &hashtable
[bucket
];
210 hlist_for_each_entry(function
, pos
, head
, tool_hnode
) {
211 if (function
->lexblock
.ip
.addr
== addr
)
218 static struct variable
*hashaddr__find_variable(const struct hlist_head hashtable
[],
221 struct variable
*variable
;
222 struct hlist_node
*pos
;
223 uint16_t bucket
= hashaddr__fn(addr
);
224 const struct hlist_head
*head
= &hashtable
[bucket
];
226 hlist_for_each_entry(variable
, pos
, head
, tool_hnode
) {
227 if (variable
->ip
.addr
== addr
)
235 * FIXME: Its in the DWARF loader, we have to find a better handoff
238 extern struct strings
*strings
;
240 int cu__encode_ctf(struct cu
*cu
, int verbose
)
243 struct ctf
*ctf
= ctf__new(cu
->filename
, cu
->elf
);
248 if (cu__cache_symtab(cu
) < 0)
251 ctf__set_strings(ctf
, strings
);
255 cu__for_each_type(cu
, id
, pos
)
256 tag__encode_ctf(pos
, id
, ctf
);
258 struct hlist_head hash_addr
[HASHADDR__SIZE
];
260 for (id
= 0; id
< HASHADDR__SIZE
; ++id
)
261 INIT_HLIST_HEAD(&hash_addr
[id
]);
263 struct function
*function
;
264 cu__for_each_function(cu
, id
, function
) {
265 uint64_t addr
= function
->lexblock
.ip
.addr
;
266 struct hlist_head
*head
= &hash_addr
[hashaddr__fn(addr
)];
267 hlist_add_head(&function
->tool_hnode
, head
);
272 const char *sym_name
;
273 cu__for_each_cached_symtab_entry(cu
, id
, sym
, sym_name
) {
274 if (ctf__ignore_symtab_function(&sym
, sym_name
))
277 addr
= elf_sym__value(&sym
);
279 function
= hashaddr__find_function(hash_addr
, addr
);
280 if (function
== NULL
) {
283 "function %4d: %-20s %#" PRIx64
" %5u NOT FOUND!\n",
285 elf_sym__size(&sym
));
286 err
= ctf__add_function(ctf
, 0, 0, 0, &position
);
292 const struct ftype
*ftype
= &function
->proto
;
293 err
= ctf__add_function(ctf
, function
->proto
.tag
.type
,
295 ftype
->unspec_parms
, &position
);
300 struct parameter
*pos
;
301 ftype__for_each_parameter(ftype
, pos
)
302 ctf__add_function_parameter(ctf
, pos
->tag
.type
, &position
);
305 for (id
= 0; id
< HASHADDR__SIZE
; ++id
)
306 INIT_HLIST_HEAD(&hash_addr
[id
]);
308 struct variable
*var
;
309 cu__for_each_variable(cu
, id
, pos
) {
310 var
= tag__variable(pos
);
311 if (variable__scope(var
) != VSCOPE_GLOBAL
)
313 struct hlist_head
*head
= &hash_addr
[hashaddr__fn(var
->ip
.addr
)];
314 hlist_add_head(&var
->tool_hnode
, head
);
317 cu__for_each_cached_symtab_entry(cu
, id
, sym
, sym_name
) {
318 if (ctf__ignore_symtab_object(&sym
, sym_name
))
320 addr
= elf_sym__value(&sym
);
322 var
= hashaddr__find_variable(hash_addr
, addr
);
326 "variable %4d: %-20s %#" PRIx64
" %5u NOT FOUND!\n",
328 elf_sym__size(&sym
));
329 err
= ctf__add_object(ctf
, 0);
335 err
= ctf__add_object(ctf
, var
->ip
.tag
.type
);
340 ctf__encode(ctf
, CTF_FLAGS_COMPR
);
349 "%4d: %-20s %#llx %5u failed encoding, "
350 "ABORTING!\n", id
, sym_name
,
351 (unsigned long long)addr
, elf_sym__size(&sym
));