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