1 /*
2
3 Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved.
4 Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of version 2.1 of the GNU Lesser General Public License
8 as published by the Free Software Foundation.
9
10 This program is distributed in the hope that it would be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
14 Further, this software is distributed without any warranty that it is
15 free of the rightful claim of any third person regarding infringement
16 or the like. Any license provided herein, whether implied or
17 otherwise, applies only to this software file. Patent licenses, if
18 any, provided herein do not apply to combinations of this program with
19 other software, or any other product whatsoever.
20
21 You should have received a copy of the GNU Lesser General Public
22 License along with this program; if not, write the Free Software
23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24 USA.
25
26 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
27 Mountain View, CA 94043, or:
28
29 http://www.sgi.com
30
31 For further information regarding this notice, see:
32
33 http://oss.sgi.com/projects/GenInfo/NoticeExplan
34
35 */
36 /* The address of the Free Software Foundation is
37 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
38 Boston, MA 02110-1301, USA.
39 SGI has moved from the Crittenden Lane address.
40 */
41
42
43
44
45 #include "config.h"
46 #include "dwarf_incl.h"
47 #include <stdio.h>
48 #include "dwarf_die_deliv.h"
49
50 /* This is normally reliable.
51 But not always.
52 If different compilation
53 units have different address sizes
54 this may not give the correct value in all contexts.
55 If the Elf offset size != address_size
56 (for example if address_size = 4 but recorded in elf64 object)
57 this may not give the correct value in all contexts.
58 */
59 int
dwarf_get_address_size(Dwarf_Debug dbg,Dwarf_Half * ret_addr_size,Dwarf_Error * error)60 dwarf_get_address_size(Dwarf_Debug dbg,
61 Dwarf_Half * ret_addr_size, Dwarf_Error * error)
62 {
63 Dwarf_Half address_size = 0;
64
65 if (dbg == 0) {
66 _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
67 return (DW_DLV_ERROR);
68 }
69 address_size = dbg->de_pointer_size;
70 *ret_addr_size = address_size;
71 return DW_DLV_OK;
72 }
73
74 /* This will be correct in all contexts where the
75 CU context of a DIE is known.
76 */
77 int
dwarf_get_die_address_size(Dwarf_Die die,Dwarf_Half * ret_addr_size,Dwarf_Error * error)78 dwarf_get_die_address_size(Dwarf_Die die,
79 Dwarf_Half * ret_addr_size, Dwarf_Error * error)
80 {
81 Dwarf_Half address_size = 0;
82 CHECK_DIE(die, DW_DLV_ERROR);
83 address_size = die->di_cu_context->cc_address_size;
84 *ret_addr_size = address_size;
85 return DW_DLV_OK;
86 }
87
88 int
dwarf_dieoffset(Dwarf_Die die,Dwarf_Off * ret_offset,Dwarf_Error * error)89 dwarf_dieoffset(Dwarf_Die die,
90 Dwarf_Off * ret_offset, Dwarf_Error * error)
91 {
92 CHECK_DIE(die, DW_DLV_ERROR);
93
94 *ret_offset = (die->di_debug_info_ptr -
95 die->di_cu_context->cc_dbg->de_debug_info.dss_data);
96 return DW_DLV_OK;
97 }
98
99
100 /*
101 This function returns the offset of
102 the die relative to the start of its
103 compilation-unit rather than .debug_info.
104 Returns DW_DLV_ERROR on error.
105 */
106 int
dwarf_die_CU_offset(Dwarf_Die die,Dwarf_Off * cu_off,Dwarf_Error * error)107 dwarf_die_CU_offset(Dwarf_Die die,
108 Dwarf_Off * cu_off, Dwarf_Error * error)
109 {
110 Dwarf_CU_Context cu_context = 0;
111
112 CHECK_DIE(die, DW_DLV_ERROR);
113 cu_context = die->di_cu_context;
114
115 *cu_off =
116 (die->di_debug_info_ptr - cu_context->cc_dbg->de_debug_info.dss_data -
117 cu_context->cc_debug_info_offset);
118 return DW_DLV_OK;
119 }
120
121 /*
122 This function returns the global offset
123 (meaning the section offset) and length of
124 the CU that this die is a part of.
125 Used for correctness checking by dwarfdump.
126 */
127 int
dwarf_die_CU_offset_range(Dwarf_Die die,Dwarf_Off * cu_off,Dwarf_Off * cu_length,Dwarf_Error * error)128 dwarf_die_CU_offset_range(Dwarf_Die die,
129 Dwarf_Off * cu_off,
130 Dwarf_Off * cu_length,
131 Dwarf_Error * error)
132 {
133 Dwarf_CU_Context cu_context = 0;
134
135 CHECK_DIE(die, DW_DLV_ERROR);
136 cu_context = die->di_cu_context;
137
138 *cu_off = cu_context->cc_debug_info_offset;
139 *cu_length = cu_context->cc_length + cu_context->cc_length_size
140 + cu_context->cc_extension_size;
141 return DW_DLV_OK;
142 }
143
144
145
146 int
dwarf_tag(Dwarf_Die die,Dwarf_Half * tag,Dwarf_Error * error)147 dwarf_tag(Dwarf_Die die, Dwarf_Half * tag, Dwarf_Error * error)
148 {
149 CHECK_DIE(die, DW_DLV_ERROR);
150 *tag = (die->di_abbrev_list->ab_tag);
151 return DW_DLV_OK;
152 }
153
154
155 int
dwarf_attrlist(Dwarf_Die die,Dwarf_Attribute ** attrbuf,Dwarf_Signed * attrcnt,Dwarf_Error * error)156 dwarf_attrlist(Dwarf_Die die,
157 Dwarf_Attribute ** attrbuf,
158 Dwarf_Signed * attrcnt, Dwarf_Error * error)
159 {
160 Dwarf_Word attr_count = 0;
161 Dwarf_Word i = 0;
162 Dwarf_Half attr = 0;
163 Dwarf_Half attr_form = 0;
164 Dwarf_Byte_Ptr abbrev_ptr = 0;
165 Dwarf_Abbrev_List abbrev_list = 0;
166 Dwarf_Attribute new_attr = 0;
167 Dwarf_Attribute head_attr = NULL;
168 Dwarf_Attribute curr_attr = NULL;
169 Dwarf_Attribute *attr_ptr = 0;
170 Dwarf_Debug dbg = 0;
171 Dwarf_Byte_Ptr info_ptr = 0;
172
173 CHECK_DIE(die, DW_DLV_ERROR);
174 dbg = die->di_cu_context->cc_dbg;
175
176 abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context,
177 die->di_abbrev_list->
178 ab_code);
179 if (abbrev_list == NULL) {
180 _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_BAD);
181 return (DW_DLV_ERROR);
182 }
183 abbrev_ptr = abbrev_list->ab_abbrev_ptr;
184
185 info_ptr = die->di_debug_info_ptr;
186 SKIP_LEB128_WORD(info_ptr);
187
188 do {
189 Dwarf_Unsigned utmp2;
190
191 DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
192 attr = (Dwarf_Half) utmp2;
193 DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
194 attr_form = (Dwarf_Half) utmp2;
195
196 if (attr != 0) {
197 new_attr =
198 (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
199 if (new_attr == NULL) {
200 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
201 return (DW_DLV_ERROR);
202 }
203
204 new_attr->ar_attribute = attr;
205 new_attr->ar_attribute_form_direct = attr_form;
206 new_attr->ar_attribute_form = attr_form;
207 if (attr_form == DW_FORM_indirect) {
208 Dwarf_Unsigned utmp6;
209
210 /* DECODE_LEB128_UWORD does info_ptr update */
211 DECODE_LEB128_UWORD(info_ptr, utmp6);
212 attr_form = (Dwarf_Half) utmp6;
213 new_attr->ar_attribute_form = attr_form;
214 }
215 new_attr->ar_cu_context = die->di_cu_context;
216 new_attr->ar_debug_info_ptr = info_ptr;
217
218 {
219 Dwarf_Unsigned sov = _dwarf_get_size_of_val(dbg,
220 attr_form,
221 die->di_cu_context->cc_address_size,
222 info_ptr,
223 die->di_cu_context->cc_length_size);
224 info_ptr += sov;
225 }
226
227
228 if (head_attr == NULL)
229 head_attr = curr_attr = new_attr;
230 else {
231 curr_attr->ar_next = new_attr;
232 curr_attr = new_attr;
233 }
234 attr_count++;
235 }
236 } while (attr != 0 || attr_form != 0);
237
238 if (attr_count == 0) {
239 *attrbuf = NULL;
240 *attrcnt = 0;
241 return (DW_DLV_NO_ENTRY);
242 }
243
244 attr_ptr = (Dwarf_Attribute *)
245 _dwarf_get_alloc(dbg, DW_DLA_LIST, attr_count);
246 if (attr_ptr == NULL) {
247 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
248 return (DW_DLV_ERROR);
249 }
250
251 curr_attr = head_attr;
252 for (i = 0; i < attr_count; i++) {
253 *(attr_ptr + i) = curr_attr;
254 curr_attr = curr_attr->ar_next;
255 }
256
257 *attrbuf = attr_ptr;
258 *attrcnt = attr_count;
259 return (DW_DLV_OK);
260 }
261
262
263 /*
264 This function takes a die, and an attr, and returns
265 a pointer to the start of the value of that attr in
266 the given die in the .debug_info section. The form
267 is returned in *attr_form.
268
269 Returns NULL on error, or if attr is not found.
270 However, *attr_form is 0 on error, and positive
271 otherwise.
272 */
273 static Dwarf_Byte_Ptr
_dwarf_get_value_ptr(Dwarf_Die die,Dwarf_Half attr,Dwarf_Half * attr_form)274 _dwarf_get_value_ptr(Dwarf_Die die,
275 Dwarf_Half attr, Dwarf_Half * attr_form)
276 {
277 Dwarf_Byte_Ptr abbrev_ptr = 0;
278 Dwarf_Abbrev_List abbrev_list;
279 Dwarf_Half curr_attr = 0;
280 Dwarf_Half curr_attr_form = 0;
281 Dwarf_Byte_Ptr info_ptr = 0;
282
283 abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context,
284 die->di_abbrev_list->ab_code);
285 if (abbrev_list == NULL) {
286 *attr_form = 0;
287 return (NULL);
288 }
289 abbrev_ptr = abbrev_list->ab_abbrev_ptr;
290
291 info_ptr = die->di_debug_info_ptr;
292 SKIP_LEB128_WORD(info_ptr);
293
294 do {
295 Dwarf_Unsigned utmp3;
296
297 DECODE_LEB128_UWORD(abbrev_ptr, utmp3);
298 curr_attr = (Dwarf_Half) utmp3;
299 DECODE_LEB128_UWORD(abbrev_ptr, utmp3);
300 curr_attr_form = (Dwarf_Half) utmp3;
301 if (curr_attr_form == DW_FORM_indirect) {
302 Dwarf_Unsigned utmp6;
303
304 /* DECODE_LEB128_UWORD updates info_ptr */
305 DECODE_LEB128_UWORD(info_ptr, utmp6);
306 curr_attr_form = (Dwarf_Half) utmp6;
307 }
308
309 if (curr_attr == attr) {
310 *attr_form = curr_attr_form;
311 return (info_ptr);
312 }
313
314 info_ptr += _dwarf_get_size_of_val(die->di_cu_context->cc_dbg,
315 curr_attr_form,
316 die->di_cu_context->cc_address_size,
317 info_ptr,
318 die->di_cu_context->cc_length_size);
319 } while (curr_attr != 0 || curr_attr_form != 0);
320
321 *attr_form = 1;
322 return (NULL);
323 }
324
325
326 int
dwarf_diename(Dwarf_Die die,char ** ret_name,Dwarf_Error * error)327 dwarf_diename(Dwarf_Die die, char **ret_name, Dwarf_Error * error)
328 {
329 Dwarf_Half attr_form = 0;
330 Dwarf_Debug dbg = 0;
331 Dwarf_Byte_Ptr info_ptr = 0;
332 Dwarf_Unsigned string_offset = 0;
333 int res = DW_DLV_ERROR;
334
335 CHECK_DIE(die, DW_DLV_ERROR);
336
337 info_ptr = _dwarf_get_value_ptr(die, DW_AT_name, &attr_form);
338 if (info_ptr == NULL) {
339 if (attr_form == 0) {
340 _dwarf_error(die->di_cu_context->cc_dbg, error,
341 DW_DLE_DIE_BAD);
342 return (DW_DLV_ERROR);
343 }
344 return DW_DLV_NO_ENTRY;
345 }
346
347 if (attr_form == DW_FORM_string) {
348 *ret_name = (char *) (info_ptr);
349 return DW_DLV_OK;
350 }
351
352 dbg = die->di_cu_context->cc_dbg;
353 if (attr_form != DW_FORM_strp) {
354 _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
355 return (DW_DLV_ERROR);
356 }
357
358 READ_UNALIGNED(dbg, string_offset, Dwarf_Unsigned,
359 info_ptr, die->di_cu_context->cc_length_size);
360
361 if (string_offset >= dbg->de_debug_str.dss_size) {
362 _dwarf_error(dbg, error, DW_DLE_STRING_OFFSET_BAD);
363 return (DW_DLV_ERROR);
364 }
365
366 res = _dwarf_load_section(dbg, &dbg->de_debug_str,error);
367 if (res != DW_DLV_OK) {
368 return res;
369 }
370
371 *ret_name = (char *) (dbg->de_debug_str.dss_data + string_offset);
372 return DW_DLV_OK;
373 }
374
375
376 int
dwarf_hasattr(Dwarf_Die die,Dwarf_Half attr,Dwarf_Bool * return_bool,Dwarf_Error * error)377 dwarf_hasattr(Dwarf_Die die,
378 Dwarf_Half attr,
379 Dwarf_Bool * return_bool, Dwarf_Error * error)
380 {
381 Dwarf_Half attr_form = 0;
382
383 CHECK_DIE(die, DW_DLV_ERROR);
384
385 if (_dwarf_get_value_ptr(die, attr, &attr_form) == NULL) {
386 if (attr_form == 0) {
387 _dwarf_error(die->di_cu_context->cc_dbg, error,
388 DW_DLE_DIE_BAD);
389 return (DW_DLV_ERROR);
390 }
391 *return_bool = false;
392 return DW_DLV_OK;
393 }
394
395 *return_bool = (true);
396 return DW_DLV_OK;
397 }
398
399
400 int
dwarf_attr(Dwarf_Die die,Dwarf_Half attr,Dwarf_Attribute * ret_attr,Dwarf_Error * error)401 dwarf_attr(Dwarf_Die die,
402 Dwarf_Half attr,
403 Dwarf_Attribute * ret_attr, Dwarf_Error * error)
404 {
405 Dwarf_Half attr_form = 0;
406 Dwarf_Attribute attrib = 0;
407 Dwarf_Byte_Ptr info_ptr = 0;
408 Dwarf_Debug dbg = 0;
409
410 CHECK_DIE(die, DW_DLV_ERROR);
411 dbg = die->di_cu_context->cc_dbg;
412
413 info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form);
414 if (info_ptr == NULL) {
415 if (attr_form == 0) {
416 _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
417 return (DW_DLV_ERROR);
418 }
419 return DW_DLV_NO_ENTRY;
420 }
421
422 attrib = (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
423 if (attrib == NULL) {
424 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
425 return (DW_DLV_ERROR);
426 }
427
428 attrib->ar_attribute = attr;
429 attrib->ar_attribute_form = attr_form;
430 attrib->ar_attribute_form_direct = attr_form;
431 attrib->ar_cu_context = die->di_cu_context;
432 attrib->ar_debug_info_ptr = info_ptr;
433 *ret_attr = (attrib);
434 return DW_DLV_OK;
435 }
436
437
438 int
dwarf_lowpc(Dwarf_Die die,Dwarf_Addr * return_addr,Dwarf_Error * error)439 dwarf_lowpc(Dwarf_Die die,
440 Dwarf_Addr * return_addr, Dwarf_Error * error)
441 {
442 Dwarf_Addr ret_addr = 0;
443 Dwarf_Byte_Ptr info_ptr = 0;
444 Dwarf_Half attr_form = 0;
445 Dwarf_Debug dbg = 0;
446 Dwarf_Half address_size = 0;
447
448 CHECK_DIE(die, DW_DLV_ERROR);
449
450 dbg = die->di_cu_context->cc_dbg;
451 address_size = die->di_cu_context->cc_address_size;
452 info_ptr = _dwarf_get_value_ptr(die, DW_AT_low_pc, &attr_form);
453 if ((info_ptr == NULL && attr_form == 0) ||
454 (info_ptr != NULL && attr_form != DW_FORM_addr)) {
455 _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
456 return (DW_DLV_ERROR);
457 }
458 if (info_ptr == NULL) {
459 return (DW_DLV_NO_ENTRY);
460 }
461
462
463 READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
464 info_ptr, address_size);
465
466 *return_addr = ret_addr;
467 return (DW_DLV_OK);
468 }
469
470
471 int
dwarf_highpc(Dwarf_Die die,Dwarf_Addr * return_addr,Dwarf_Error * error)472 dwarf_highpc(Dwarf_Die die,
473 Dwarf_Addr * return_addr, Dwarf_Error * error)
474 {
475 Dwarf_Addr ret_addr = 0;
476 Dwarf_Byte_Ptr info_ptr = 0;
477 Dwarf_Half attr_form = 0;
478 Dwarf_Debug dbg = 0;
479 Dwarf_Half address_size = 0;
480
481 CHECK_DIE(die, DW_DLV_ERROR);
482 dbg = die->di_cu_context->cc_dbg;
483 address_size = die->di_cu_context->cc_address_size;
484 info_ptr = _dwarf_get_value_ptr(die, DW_AT_high_pc, &attr_form);
485 if ((info_ptr == NULL && attr_form == 0) ||
486 (info_ptr != NULL && attr_form != DW_FORM_addr)) {
487 _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
488 return (DW_DLV_ERROR);
489 }
490 if (info_ptr == NULL) {
491 return (DW_DLV_NO_ENTRY);
492 }
493
494 READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
495 info_ptr, address_size);
496
497 *return_addr = ret_addr;
498 return (DW_DLV_OK);
499 }
500
501
502 /*
503 Takes a die, an attribute attr, and checks if attr
504 occurs in die. Attr is required to be an attribute
505 whose form is in the "constant" class. If attr occurs
506 in die, the value is returned.
507 Returns DW_DLV_OK, DW_DLV_ERROR, or DW_DLV_NO_ENTRY as
508 appropriate. Sets the value thru the pointer return_val.
509 This function is meant to do all the
510 processing for dwarf_bytesize, dwarf_bitsize, dwarf_bitoffset,
511 and dwarf_srclang.
512 */
513 static int
_dwarf_die_attr_unsigned_constant(Dwarf_Die die,Dwarf_Half attr,Dwarf_Unsigned * return_val,Dwarf_Error * error)514 _dwarf_die_attr_unsigned_constant(Dwarf_Die die,
515 Dwarf_Half attr,
516 Dwarf_Unsigned * return_val,
517 Dwarf_Error * error)
518 {
519 Dwarf_Byte_Ptr info_ptr;
520 Dwarf_Half attr_form;
521 Dwarf_Unsigned ret_value;
522 Dwarf_Debug dbg;
523
524 CHECK_DIE(die, DW_DLV_ERROR);
525
526 dbg = die->di_cu_context->cc_dbg;
527 info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form);
528 if (info_ptr != NULL) {
529 switch (attr_form) {
530
531 case DW_FORM_data1:
532 *return_val = (*(Dwarf_Small *) info_ptr);
533 return (DW_DLV_OK);
534
535 case DW_FORM_data2:
536 READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
537 info_ptr, sizeof(Dwarf_Shalf));
538 *return_val = ret_value;
539 return (DW_DLV_OK);
540
541 case DW_FORM_data4:
542 READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
543 info_ptr, sizeof(Dwarf_sfixed));
544 *return_val = ret_value;
545 return (DW_DLV_OK);
546
547 case DW_FORM_data8:
548 READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
549 info_ptr, sizeof(Dwarf_Unsigned));
550 *return_val = ret_value;
551 return (DW_DLV_OK);
552
553 case DW_FORM_udata:
554 *return_val = (_dwarf_decode_u_leb128(info_ptr, NULL));
555 return (DW_DLV_OK);
556
557 default:
558 _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
559 return (DW_DLV_ERROR);
560 }
561 }
562 if (attr_form == 0) {
563 _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
564 return (DW_DLV_ERROR);
565 }
566 return DW_DLV_NO_ENTRY;
567 }
568
569
570 int
dwarf_bytesize(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)571 dwarf_bytesize(Dwarf_Die die,
572 Dwarf_Unsigned * ret_size, Dwarf_Error * error)
573 {
574 Dwarf_Unsigned luns = 0;
575 int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_byte_size,
576 &luns, error);
577 *ret_size = luns;
578 return res;
579 }
580
581
582 int
dwarf_bitsize(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)583 dwarf_bitsize(Dwarf_Die die,
584 Dwarf_Unsigned * ret_size, Dwarf_Error * error)
585 {
586 Dwarf_Unsigned luns = 0;
587 int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_size,
588 &luns, error);
589 *ret_size = luns;
590 return res;
591 }
592
593
594 int
dwarf_bitoffset(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)595 dwarf_bitoffset(Dwarf_Die die,
596 Dwarf_Unsigned * ret_size, Dwarf_Error * error)
597 {
598 Dwarf_Unsigned luns = 0;
599 int res = _dwarf_die_attr_unsigned_constant(die,
600 DW_AT_bit_offset, &luns, error);
601 *ret_size = luns;
602 return res;
603 }
604
605
606 /* Refer section 3.1, page 21 in Dwarf Definition. */
607 int
dwarf_srclang(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)608 dwarf_srclang(Dwarf_Die die,
609 Dwarf_Unsigned * ret_size, Dwarf_Error * error)
610 {
611 Dwarf_Unsigned luns = 0;
612 int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_language,
613 &luns, error);
614 *ret_size = luns;
615 return res;
616 }
617
618
619 /* Refer section 5.4, page 37 in Dwarf Definition. */
620 int
dwarf_arrayorder(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)621 dwarf_arrayorder(Dwarf_Die die,
622 Dwarf_Unsigned * ret_size, Dwarf_Error * error)
623 {
624 Dwarf_Unsigned luns = 0;
625 int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_ordering,
626 &luns, error);
627 *ret_size = luns;
628 return res;
629 }
630
631 /*
632 Return DW_DLV_OK if ok
633 DW_DLV_ERROR if failure.
634
635 If the die and the attr are not related the result is
636 meaningless.
637 */
638 int
dwarf_attr_offset(Dwarf_Die die,Dwarf_Attribute attr,Dwarf_Off * offset,Dwarf_Error * error)639 dwarf_attr_offset(Dwarf_Die die, Dwarf_Attribute attr,
640 Dwarf_Off * offset /* return offset thru this ptr */,
641 Dwarf_Error * error)
642 {
643 Dwarf_Off attroff = 0;
644
645 CHECK_DIE(die, DW_DLV_ERROR);
646
647 attroff = (attr->ar_debug_info_ptr -
648 die->di_cu_context->cc_dbg->de_debug_info.dss_data);
649 *offset = attroff;
650 return DW_DLV_OK;
651 }
652
653 int
dwarf_die_abbrev_code(Dwarf_Die die)654 dwarf_die_abbrev_code(Dwarf_Die die)
655 {
656 return die->di_abbrev_code;
657 }
658
659 /* Helper function for finding form class. */
660 static enum Dwarf_Form_Class
dw_get_special_offset(Dwarf_Half attrnum)661 dw_get_special_offset(Dwarf_Half attrnum)
662 {
663 switch(attrnum) {
664 case DW_AT_stmt_list:
665 return DW_FORM_CLASS_LINEPTR;
666 case DW_AT_macro_info:
667 return DW_FORM_CLASS_MACPTR;
668 case DW_AT_ranges:
669 return DW_FORM_CLASS_RANGELISTPTR;
670 case DW_AT_location:
671 case DW_AT_string_length:
672 case DW_AT_return_addr:
673 case DW_AT_data_member_location:
674 case DW_AT_frame_base:
675 case DW_AT_segment:
676 case DW_AT_static_link:
677 case DW_AT_use_location:
678 case DW_AT_vtable_elem_location:
679 return DW_FORM_CLASS_LOCLISTPTR;
680 case DW_AT_sibling:
681 case DW_AT_byte_size :
682 case DW_AT_bit_offset :
683 case DW_AT_bit_size :
684 case DW_AT_discr :
685 case DW_AT_import :
686 case DW_AT_common_reference:
687 case DW_AT_containing_type:
688 case DW_AT_default_value:
689 case DW_AT_lower_bound:
690 case DW_AT_bit_stride:
691 case DW_AT_upper_bound:
692 case DW_AT_abstract_origin:
693 case DW_AT_base_types:
694 case DW_AT_count:
695 case DW_AT_friend:
696 case DW_AT_namelist_item:
697 case DW_AT_priority:
698 case DW_AT_specification:
699 case DW_AT_type:
700 case DW_AT_allocated:
701 case DW_AT_associated:
702 case DW_AT_byte_stride:
703 case DW_AT_extension:
704 case DW_AT_trampoline:
705 case DW_AT_small:
706 case DW_AT_object_pointer:
707 case DW_AT_signature:
708 return DW_FORM_CLASS_REFERENCE;
709 case DW_AT_MIPS_fde: /* SGI/IRIX extension */
710 return DW_FORM_CLASS_FRAMEPTR;
711 }
712 return DW_FORM_CLASS_UNKNOWN;
713 }
714
715 /* It takes 4 pieces of data (including the FORM)
716 to accurately determine the form 'class' as documented
717 in the DWARF spec. This is per DWARF4, but will work
718 for DWARF2 or 3 as well. */
dwarf_get_form_class(Dwarf_Half dwversion,Dwarf_Half attrnum,Dwarf_Half offset_size,Dwarf_Half form)719 enum Dwarf_Form_Class dwarf_get_form_class(
720 Dwarf_Half dwversion,
721 Dwarf_Half attrnum,
722 Dwarf_Half offset_size,
723 Dwarf_Half form)
724 {
725 switch(form) {
726 case DW_FORM_addr: return DW_FORM_CLASS_ADDRESS;
727
728 case DW_FORM_data2: return DW_FORM_CLASS_CONSTANT;
729
730 case DW_FORM_data4:
731 if(dwversion <= 3 && offset_size == 4) {
732 enum Dwarf_Form_Class class = dw_get_special_offset(attrnum);
733 if(class != DW_FORM_CLASS_UNKNOWN) {
734 return class;
735 }
736 }
737 return DW_FORM_CLASS_CONSTANT;
738 case DW_FORM_data8:
739 if(dwversion <= 3 && offset_size == 8) {
740 enum Dwarf_Form_Class class = dw_get_special_offset(attrnum);
741 if(class != DW_FORM_CLASS_UNKNOWN) {
742 return class;
743 }
744 }
745 return DW_FORM_CLASS_CONSTANT;
746
747 case DW_FORM_sec_offset:
748 {
749 enum Dwarf_Form_Class class = dw_get_special_offset(attrnum);
750 if(class != DW_FORM_CLASS_UNKNOWN) {
751 return class;
752 }
753 }
754 /* We do not know what this is. */
755 break;
756
757 case DW_FORM_string: return DW_FORM_CLASS_STRING;
758 case DW_FORM_strp: return DW_FORM_CLASS_STRING;
759
760 case DW_FORM_block: return DW_FORM_CLASS_BLOCK;
761 case DW_FORM_block1: return DW_FORM_CLASS_BLOCK;
762 case DW_FORM_block2: return DW_FORM_CLASS_BLOCK;
763 case DW_FORM_block4: return DW_FORM_CLASS_BLOCK;
764
765 case DW_FORM_data1: return DW_FORM_CLASS_CONSTANT;
766 case DW_FORM_sdata: return DW_FORM_CLASS_CONSTANT;
767 case DW_FORM_udata: return DW_FORM_CLASS_CONSTANT;
768
769 case DW_FORM_ref_addr: return DW_FORM_CLASS_REFERENCE;
770 case DW_FORM_ref1: return DW_FORM_CLASS_REFERENCE;
771 case DW_FORM_ref2: return DW_FORM_CLASS_REFERENCE;
772 case DW_FORM_ref4: return DW_FORM_CLASS_REFERENCE;
773 case DW_FORM_ref8: return DW_FORM_CLASS_REFERENCE;
774 case DW_FORM_ref_udata: return DW_FORM_CLASS_REFERENCE;
775 case DW_FORM_ref_sig8: return DW_FORM_CLASS_REFERENCE;
776
777 case DW_FORM_exprloc: return DW_FORM_CLASS_EXPRLOC;
778
779 case DW_FORM_flag: return DW_FORM_CLASS_FLAG;
780 case DW_FORM_flag_present: return DW_FORM_CLASS_FLAG;
781
782
783 case DW_FORM_indirect:
784 default:
785 break;
786 };
787 return DW_FORM_CLASS_UNKNOWN;
788 }
789
790