xref: /titanic_41/usr/src/tools/ctf/dwarf/common/dwarf_query.c (revision 07dc1947c362e187fb955d283b692f8769dd5def)
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