Move to kernel style SPDX license identifiers
[babeltrace.git] / src / plugins / lttng-utils / debug-info / dwarf.c
... / ...
CommitLineData
1/*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright 2015 Antoine Busque <abusque@efficios.com>
5 *
6 * Babeltrace - DWARF Information Reader
7 */
8
9#include <stdbool.h>
10
11#include <glib.h>
12
13#include "dwarf.h"
14
15BT_HIDDEN
16struct bt_dwarf_cu *bt_dwarf_cu_create(Dwarf *dwarf_info)
17{
18 struct bt_dwarf_cu *cu;
19
20 if (!dwarf_info) {
21 goto error;
22 }
23
24 cu = g_new0(struct bt_dwarf_cu, 1);
25 if (!cu) {
26 goto error;
27 }
28 cu->dwarf_info = dwarf_info;
29 return cu;
30
31error:
32 return NULL;
33}
34
35BT_HIDDEN
36void bt_dwarf_cu_destroy(struct bt_dwarf_cu *cu)
37{
38 g_free(cu);
39}
40
41BT_HIDDEN
42int bt_dwarf_cu_next(struct bt_dwarf_cu *cu)
43{
44 int ret;
45 Dwarf_Off next_offset;
46 size_t cu_header_size;
47
48 if (!cu) {
49 ret = -1;
50 goto end;
51 }
52
53 ret = dwarf_nextcu(cu->dwarf_info, cu->next_offset, &next_offset,
54 &cu_header_size, NULL, NULL, NULL);
55 if (ret) {
56 /* ret is -1 on error, 1 if no next CU. */
57 goto end;
58 }
59
60 cu->offset = cu->next_offset;
61 cu->next_offset = next_offset;
62 cu->header_size = cu_header_size;
63
64end:
65 return ret;
66}
67
68BT_HIDDEN
69struct bt_dwarf_die *bt_dwarf_die_create(struct bt_dwarf_cu *cu)
70{
71 Dwarf_Die *dwarf_die = NULL;
72 struct bt_dwarf_die *die = NULL;
73
74 if (!cu) {
75 goto error;
76 }
77
78 dwarf_die = g_new0(Dwarf_Die, 1);
79 if (!dwarf_die) {
80 goto error;
81 }
82
83 dwarf_die = dwarf_offdie(cu->dwarf_info, cu->offset + cu->header_size,
84 dwarf_die);
85 if (!dwarf_die) {
86 goto error;
87 }
88
89 die = g_new0(struct bt_dwarf_die, 1);
90 if (!die) {
91 goto error;
92 }
93
94 die->cu = cu;
95 die->dwarf_die = dwarf_die;
96 die->depth = 0;
97
98 return die;
99
100error:
101 g_free(dwarf_die);
102 g_free(die);
103 return NULL;
104}
105
106BT_HIDDEN
107void bt_dwarf_die_destroy(struct bt_dwarf_die *die)
108{
109 if (!die) {
110 return;
111 }
112
113 g_free(die->dwarf_die);
114 g_free(die);
115}
116
117BT_HIDDEN
118int bt_dwarf_die_has_children(struct bt_dwarf_die *die)
119{
120 return dwarf_haschildren(die->dwarf_die);
121}
122
123BT_HIDDEN
124int bt_dwarf_die_child(struct bt_dwarf_die *die)
125{
126 int ret;
127 Dwarf_Die *child_die = NULL;
128
129 if (!die) {
130 ret = -1;
131 goto error;
132 }
133
134 child_die = g_new0(Dwarf_Die, 1);
135 if (!child_die) {
136 ret = -1;
137 goto error;
138 }
139
140 ret = dwarf_child(die->dwarf_die, child_die);
141 if (ret) {
142 /* ret is -1 on error, 1 if no child DIE. */
143 goto error;
144 }
145
146 g_free(die->dwarf_die);
147 die->dwarf_die = child_die;
148 die->depth++;
149 return 0;
150
151error:
152 g_free(child_die);
153 return ret;
154}
155
156BT_HIDDEN
157int bt_dwarf_die_next(struct bt_dwarf_die *die)
158{
159 int ret;
160 Dwarf_Die *next_die = NULL;
161
162 if (!die) {
163 ret = -1;
164 goto error;
165 }
166
167 next_die = g_new0(Dwarf_Die, 1);
168 if (!next_die) {
169 ret = -1;
170 goto error;
171 }
172
173 if (die->depth == 0) {
174 ret = dwarf_child(die->dwarf_die, next_die);
175 if (ret) {
176 /* ret is -1 on error, 1 if no child DIE. */
177 goto error;
178 }
179
180 die->depth = 1;
181 } else {
182 ret = dwarf_siblingof(die->dwarf_die, next_die);
183 if (ret) {
184 /* ret is -1 on error, 1 if we reached end of
185 * DIEs at this depth. */
186 goto error;
187 }
188 }
189
190 g_free(die->dwarf_die);
191 die->dwarf_die = next_die;
192 return 0;
193
194error:
195 g_free(next_die);
196 return ret;
197}
198
199BT_HIDDEN
200int bt_dwarf_die_get_tag(struct bt_dwarf_die *die, int *tag)
201{
202 int _tag;
203
204 if (!die || !tag) {
205 goto error;
206 }
207
208 _tag = dwarf_tag(die->dwarf_die);
209 if (_tag == DW_TAG_invalid) {
210 goto error;
211 }
212
213 *tag = _tag;
214 return 0;
215
216error:
217 return -1;
218}
219
220BT_HIDDEN
221int bt_dwarf_die_get_name(struct bt_dwarf_die *die, char **name)
222{
223 const char *_name;
224
225 if (!die || !name) {
226 goto error;
227 }
228
229 _name = dwarf_diename(die->dwarf_die);
230 if (!_name) {
231 goto error;
232 }
233
234 *name = g_strdup(_name);
235 if (!*name) {
236 goto error;
237 }
238
239 return 0;
240
241error:
242 return -1;
243}
244
245BT_HIDDEN
246int bt_dwarf_die_get_call_file(struct bt_dwarf_die *die, char **filename)
247{
248 int ret;
249 Dwarf_Sword file_no;
250 const char *_filename = NULL;
251 Dwarf_Files *src_files = NULL;
252 Dwarf_Attribute *file_attr = NULL;
253 struct bt_dwarf_die *cu_die = NULL;
254
255 if (!die || !filename) {
256 goto error;
257 }
258
259 file_attr = g_new0(Dwarf_Attribute, 1);
260 if (!file_attr) {
261 goto error;
262 }
263
264 file_attr = dwarf_attr(die->dwarf_die, DW_AT_call_file, file_attr);
265 if (!file_attr) {
266 goto error;
267 }
268
269 ret = dwarf_formsdata(file_attr, &file_no);
270 if (ret) {
271 goto error;
272 }
273
274 cu_die = bt_dwarf_die_create(die->cu);
275 if (!cu_die) {
276 goto error;
277 }
278
279 ret = dwarf_getsrcfiles(cu_die->dwarf_die, &src_files, NULL);
280 if (ret) {
281 goto error;
282 }
283
284 _filename = dwarf_filesrc(src_files, file_no, NULL, NULL);
285 if (!_filename) {
286 goto error;
287 }
288
289 *filename = g_strdup(_filename);
290
291 bt_dwarf_die_destroy(cu_die);
292 g_free(file_attr);
293
294 return 0;
295
296error:
297 bt_dwarf_die_destroy(cu_die);
298 g_free(file_attr);
299
300 return -1;
301}
302
303BT_HIDDEN
304int bt_dwarf_die_get_call_line(struct bt_dwarf_die *die,
305 uint64_t *line_no)
306{
307 int ret = 0;
308 Dwarf_Attribute *line_attr = NULL;
309 uint64_t _line_no;
310
311 if (!die || !line_no) {
312 goto error;
313 }
314
315 line_attr = g_new0(Dwarf_Attribute, 1);
316 if (!line_attr) {
317 goto error;
318 }
319
320 line_attr = dwarf_attr(die->dwarf_die, DW_AT_call_line, line_attr);
321 if (!line_attr) {
322 goto error;
323 }
324
325 ret = dwarf_formudata(line_attr, &_line_no);
326 if (ret) {
327 goto error;
328 }
329
330 *line_no = _line_no;
331 g_free(line_attr);
332
333 return 0;
334
335error:
336 g_free(line_attr);
337
338 return -1;
339}
340
341BT_HIDDEN
342int bt_dwarf_die_contains_addr(struct bt_dwarf_die *die, uint64_t addr,
343 bool *contains)
344{
345 int ret;
346
347 ret = dwarf_haspc(die->dwarf_die, addr);
348 if (ret == -1) {
349 goto error;
350 }
351
352 *contains = (ret == 1);
353
354 return 0;
355
356error:
357 return -1;
358}
This page took 0.023873 seconds and 4 git commands to generate.