lib: remove `BT_GRAPH_RUN_STATUS_END`
[babeltrace.git] / src / plugins / lttng-utils / debug-info / dwarf.c
CommitLineData
c40a57e5
AB
1/*
2 * dwarf.c
3 *
4 * Babeltrace - DWARF Information Reader
5 *
6 * Copyright 2015 Antoine Busque <abusque@efficios.com>
7 *
8 * Author: Antoine Busque <abusque@efficios.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
29#include <glib.h>
4f45f9bb 30#include "dwarf.h"
c40a57e5
AB
31
32BT_HIDDEN
33struct bt_dwarf_cu *bt_dwarf_cu_create(Dwarf *dwarf_info)
34{
35 struct bt_dwarf_cu *cu;
36
37 if (!dwarf_info) {
38 goto error;
39 }
40
41 cu = g_new0(struct bt_dwarf_cu, 1);
42 if (!cu) {
43 goto error;
44 }
45 cu->dwarf_info = dwarf_info;
46 return cu;
47
48error:
49 return NULL;
50}
51
52BT_HIDDEN
53void bt_dwarf_cu_destroy(struct bt_dwarf_cu *cu)
54{
55 g_free(cu);
56}
57
58BT_HIDDEN
59int bt_dwarf_cu_next(struct bt_dwarf_cu *cu)
60{
61 int ret;
62 Dwarf_Off next_offset;
63 size_t cu_header_size;
64
65 if (!cu) {
66 ret = -1;
67 goto end;
68 }
69
70 ret = dwarf_nextcu(cu->dwarf_info, cu->next_offset, &next_offset,
71 &cu_header_size, NULL, NULL, NULL);
72 if (ret) {
73 /* ret is -1 on error, 1 if no next CU. */
74 goto end;
75 }
76
77 cu->offset = cu->next_offset;
78 cu->next_offset = next_offset;
79 cu->header_size = cu_header_size;
80
81end:
82 return ret;
83}
84
85BT_HIDDEN
86struct bt_dwarf_die *bt_dwarf_die_create(struct bt_dwarf_cu *cu)
87{
88 Dwarf_Die *dwarf_die = NULL;
89 struct bt_dwarf_die *die = NULL;
90
91 if (!cu) {
92 goto error;
93 }
94
95 dwarf_die = g_new0(Dwarf_Die, 1);
96 if (!dwarf_die) {
97 goto error;
98 }
99
100 dwarf_die = dwarf_offdie(cu->dwarf_info, cu->offset + cu->header_size,
101 dwarf_die);
102 if (!dwarf_die) {
103 goto error;
104 }
105
106 die = g_new0(struct bt_dwarf_die, 1);
107 if (!die) {
108 goto error;
109 }
110
111 die->cu = cu;
112 die->dwarf_die = dwarf_die;
113 die->depth = 0;
114
115 return die;
116
117error:
118 g_free(dwarf_die);
119 g_free(die);
120 return NULL;
121}
122
123BT_HIDDEN
124void bt_dwarf_die_destroy(struct bt_dwarf_die *die)
125{
126 if (!die) {
127 return;
128 }
129
130 g_free(die->dwarf_die);
131 g_free(die);
132}
133
e6365242
FD
134BT_HIDDEN
135int bt_dwarf_die_has_children(struct bt_dwarf_die *die)
136{
137 return dwarf_haschildren(die->dwarf_die);
138}
139
c40a57e5
AB
140BT_HIDDEN
141int bt_dwarf_die_child(struct bt_dwarf_die *die)
142{
143 int ret;
144 Dwarf_Die *child_die = NULL;
145
146 if (!die) {
147 ret = -1;
148 goto error;
149 }
150
151 child_die = g_new0(Dwarf_Die, 1);
152 if (!child_die) {
153 ret = -1;
154 goto error;
155 }
156
157 ret = dwarf_child(die->dwarf_die, child_die);
158 if (ret) {
159 /* ret is -1 on error, 1 if no child DIE. */
160 goto error;
161 }
162
163 g_free(die->dwarf_die);
164 die->dwarf_die = child_die;
165 die->depth++;
166 return 0;
167
168error:
169 g_free(child_die);
170 return ret;
171}
172
173BT_HIDDEN
174int bt_dwarf_die_next(struct bt_dwarf_die *die)
175{
176 int ret;
177 Dwarf_Die *next_die = NULL;
178
179 if (!die) {
180 ret = -1;
181 goto error;
182 }
183
184 next_die = g_new0(Dwarf_Die, 1);
185 if (!next_die) {
186 ret = -1;
187 goto error;
188 }
189
190 if (die->depth == 0) {
191 ret = dwarf_child(die->dwarf_die, next_die);
192 if (ret) {
193 /* ret is -1 on error, 1 if no child DIE. */
194 goto error;
195 }
196
197 die->depth = 1;
198 } else {
199 ret = dwarf_siblingof(die->dwarf_die, next_die);
200 if (ret) {
201 /* ret is -1 on error, 1 if we reached end of
202 * DIEs at this depth. */
203 goto error;
204 }
205 }
206
207 g_free(die->dwarf_die);
208 die->dwarf_die = next_die;
209 return 0;
210
211error:
212 g_free(next_die);
213 return ret;
214}
215
216BT_HIDDEN
217int bt_dwarf_die_get_tag(struct bt_dwarf_die *die, int *tag)
218{
219 int _tag;
220
221 if (!die || !tag) {
222 goto error;
223 }
224
225 _tag = dwarf_tag(die->dwarf_die);
226 if (_tag == DW_TAG_invalid) {
227 goto error;
228 }
229
230 *tag = _tag;
231 return 0;
232
233error:
234 return -1;
235}
236
237BT_HIDDEN
238int bt_dwarf_die_get_name(struct bt_dwarf_die *die, char **name)
239{
240 const char *_name;
241
242 if (!die || !name) {
243 goto error;
244 }
245
246 _name = dwarf_diename(die->dwarf_die);
247 if (!_name) {
248 goto error;
249 }
250
06d1cf5d 251 *name = g_strdup(_name);
c40a57e5
AB
252 if (!*name) {
253 goto error;
254 }
255
256 return 0;
257
258error:
259 return -1;
260}
261
262BT_HIDDEN
263int bt_dwarf_die_get_call_file(struct bt_dwarf_die *die, char **filename)
264{
265 int ret;
266 Dwarf_Sword file_no;
267 const char *_filename = NULL;
268 Dwarf_Files *src_files = NULL;
269 Dwarf_Attribute *file_attr = NULL;
270 struct bt_dwarf_die *cu_die = NULL;
271
272 if (!die || !filename) {
273 goto error;
274 }
275
276 file_attr = g_new0(Dwarf_Attribute, 1);
277 if (!file_attr) {
278 goto error;
279 }
280
281 file_attr = dwarf_attr(die->dwarf_die, DW_AT_call_file, file_attr);
282 if (!file_attr) {
283 goto error;
284 }
285
286 ret = dwarf_formsdata(file_attr, &file_no);
287 if (ret) {
288 goto error;
289 }
290
291 cu_die = bt_dwarf_die_create(die->cu);
292 if (!cu_die) {
293 goto error;
294 }
295
296 ret = dwarf_getsrcfiles(cu_die->dwarf_die, &src_files, NULL);
297 if (ret) {
298 goto error;
299 }
300
301 _filename = dwarf_filesrc(src_files, file_no, NULL, NULL);
302 if (!_filename) {
303 goto error;
304 }
305
06d1cf5d 306 *filename = g_strdup(_filename);
c40a57e5
AB
307
308 bt_dwarf_die_destroy(cu_die);
309 g_free(file_attr);
310
311 return 0;
312
313error:
314 bt_dwarf_die_destroy(cu_die);
315 g_free(file_attr);
316
317 return -1;
318}
319
320BT_HIDDEN
321int bt_dwarf_die_get_call_line(struct bt_dwarf_die *die,
322 uint64_t *line_no)
323{
324 int ret = 0;
325 Dwarf_Attribute *line_attr = NULL;
326 uint64_t _line_no;
327
328 if (!die || !line_no) {
329 goto error;
330 }
331
332 line_attr = g_new0(Dwarf_Attribute, 1);
333 if (!line_attr) {
334 goto error;
335 }
336
337 line_attr = dwarf_attr(die->dwarf_die, DW_AT_call_line, line_attr);
338 if (!line_attr) {
339 goto error;
340 }
341
342 ret = dwarf_formudata(line_attr, &_line_no);
343 if (ret) {
344 goto error;
345 }
346
347 *line_no = _line_no;
348 g_free(line_attr);
349
350 return 0;
351
352error:
353 g_free(line_attr);
354
355 return -1;
356}
357
358BT_HIDDEN
359int bt_dwarf_die_contains_addr(struct bt_dwarf_die *die, uint64_t addr,
a54aa699 360 bool *contains)
c40a57e5
AB
361{
362 int ret;
363
364 ret = dwarf_haspc(die->dwarf_die, addr);
365 if (ret == -1) {
366 goto error;
367 }
368
a54aa699 369 *contains = (ret == 1);
c40a57e5
AB
370
371 return 0;
372
373error:
374 return -1;
375}
This page took 0.07011 seconds and 4 git commands to generate.