xref: /illumos-gate/usr/src/lib/libdwarf/common/dwarf_query.c (revision 4d9fdb46b215739778ebc12079842c9905586999)
1 /*
2   Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
3   Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved.
4   Portions Copyright 2012 SN Systems Ltd. All rights reserved.
5 
6   This program is free software; you can redistribute it
7   and/or modify it under the terms of version 2.1 of the
8   GNU Lesser General Public License as published by the Free
9   Software Foundation.
10 
11   This program is distributed in the hope that it would be
12   useful, but WITHOUT ANY WARRANTY; without even the implied
13   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14   PURPOSE.
15 
16   Further, this software is distributed without any warranty
17   that it is free of the rightful claim of any third person
18   regarding infringement or the like.  Any license provided
19   herein, whether implied or otherwise, applies only to this
20   software file.  Patent licenses, if any, provided herein
21   do not apply to combinations of this program with other
22   software, or any other product whatsoever.
23 
24   You should have received a copy of the GNU Lesser General
25   Public License along with this program; if not, write the
26   Free Software Foundation, Inc., 51 Franklin Street - Fifth
27   Floor, Boston MA 02110-1301, USA.
28 
29 */
30 
31 #include "config.h"
32 #include <stdio.h>
33 #include "dwarf_incl.h"
34 #include "dwarf_alloc.h"
35 #include "dwarf_error.h"
36 #include "dwarf_util.h"
37 #include "dwarf_die_deliv.h"
38 #include "dwarfstring.h"
39 
40 #define TRUE 1
41 static int _dwarf_die_attr_unsigned_constant(Dwarf_Die die,
42     Dwarf_Half attr,
43     Dwarf_Unsigned * return_val,
44     Dwarf_Error * error);
45 
46 static int _dwarf_get_ranges_base_attr_value(Dwarf_Debug dbg,
47     Dwarf_CU_Context context,
48     Dwarf_Unsigned * rabase_out,
49     Dwarf_Error    * error);
50 
51 static int _dwarf_get_address_base_attr_value(Dwarf_Debug dbg,
52     Dwarf_CU_Context context,
53     Dwarf_Unsigned *abase_out,
54     Dwarf_Error *error);
55 
dwarf_get_offset_size(Dwarf_Debug dbg,Dwarf_Half * offset_size,Dwarf_Error * error)56 int dwarf_get_offset_size(Dwarf_Debug dbg,
57     Dwarf_Half  *    offset_size,
58     Dwarf_Error *    error)
59 {
60     if (dbg == 0) {
61         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
62         return (DW_DLV_ERROR);
63     }
64     *offset_size = dbg->de_length_size;
65     return DW_DLV_OK;
66 }
67 
68 #if 0
69 static void
70 dump_bytes(char * msg,Dwarf_Small * start, long len)
71 {
72     Dwarf_Small *end = start + len;
73     Dwarf_Small *cur = start;
74 
75     printf("%s ",msg);
76     for (; cur < end; cur++) {
77         printf("%02x ", *cur);
78     }
79     printf("\n");
80 }
81 #endif
82 
83 /* This is normally reliable.
84 But not always.
85 If different compilation
86 units have different address sizes
87 this may not give the correct value in all contexts.
88 If the Elf offset size != address_size
89 (for example if address_size = 4 but recorded in elf64 object)
90 this may not give the correct value in all contexts.
91 */
92 int
dwarf_get_address_size(Dwarf_Debug dbg,Dwarf_Half * ret_addr_size,Dwarf_Error * error)93 dwarf_get_address_size(Dwarf_Debug dbg,
94     Dwarf_Half * ret_addr_size, Dwarf_Error * error)
95 {
96     Dwarf_Half address_size = 0;
97 
98     if (dbg == 0) {
99         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
100         return (DW_DLV_ERROR);
101     }
102     address_size = dbg->de_pointer_size;
103     *ret_addr_size = address_size;
104     return DW_DLV_OK;
105 }
106 
107 /* This will be correct in all contexts where the
108    CU context of a DIE is known.
109 */
110 int
dwarf_get_die_address_size(Dwarf_Die die,Dwarf_Half * ret_addr_size,Dwarf_Error * error)111 dwarf_get_die_address_size(Dwarf_Die die,
112     Dwarf_Half * ret_addr_size, Dwarf_Error * error)
113 {
114     Dwarf_Half address_size = 0;
115     CHECK_DIE(die, DW_DLV_ERROR);
116     address_size = die->di_cu_context->cc_address_size;
117     *ret_addr_size = address_size;
118     return DW_DLV_OK;
119 }
120 
121 int
dwarf_dieoffset(Dwarf_Die die,Dwarf_Off * ret_offset,Dwarf_Error * error)122 dwarf_dieoffset(Dwarf_Die die,
123     Dwarf_Off * ret_offset, Dwarf_Error * error)
124 {
125     Dwarf_Small *dataptr = 0;
126     Dwarf_Debug dbg = 0;
127 
128     CHECK_DIE(die, DW_DLV_ERROR);
129     dbg = die->di_cu_context->cc_dbg;
130     dataptr = die->di_is_info? dbg->de_debug_info.dss_data:
131         dbg->de_debug_types.dss_data;
132 
133     *ret_offset = (die->di_debug_ptr - dataptr);
134     return DW_DLV_OK;
135 }
136 
137 
138 /*  This function returns the offset of
139     the die relative to the start of its
140     compilation-unit rather than .debug_info.
141     Returns DW_DLV_ERROR on error.  */
142 int
dwarf_die_CU_offset(Dwarf_Die die,Dwarf_Off * cu_off,Dwarf_Error * error)143 dwarf_die_CU_offset(Dwarf_Die die,
144     Dwarf_Off * cu_off, Dwarf_Error * error)
145 {
146     Dwarf_CU_Context cu_context = 0;
147     Dwarf_Small *dataptr = 0;
148     Dwarf_Debug dbg = 0;
149 
150     CHECK_DIE(die, DW_DLV_ERROR);
151     cu_context = die->di_cu_context;
152     dbg = die->di_cu_context->cc_dbg;
153     dataptr = die->di_is_info? dbg->de_debug_info.dss_data:
154         dbg->de_debug_types.dss_data;
155 
156     *cu_off = (die->di_debug_ptr - dataptr - cu_context->cc_debug_offset);
157     return DW_DLV_OK;
158 }
159 
160 /*  A common function to get both offsets (local and global)
161     It's unusual in that it sets both return offsets
162     to zero on entry.  Normally we only set any
163     output-args (through their pointers) in case
164     of success.  */
165 int
dwarf_die_offsets(Dwarf_Die die,Dwarf_Off * off,Dwarf_Off * cu_off,Dwarf_Error * error)166 dwarf_die_offsets(Dwarf_Die die,
167     Dwarf_Off *off,
168     Dwarf_Off *cu_off,
169     Dwarf_Error *error)
170 {
171     int res = 0;
172     Dwarf_Off lcuoff = 0;
173     Dwarf_Off loff = 0;
174 
175     res = dwarf_dieoffset(die,&loff,error);
176     if (res == DW_DLV_OK) {
177         res = dwarf_die_CU_offset(die,&lcuoff,error);
178     }
179     if (res == DW_DLV_OK) {
180         /*  Waiting till both succeed before
181             returning any value at all to retain
182             normal libdwarf call semantics. */
183         *off = loff;
184         *cu_off = lcuoff;
185     } else {
186         *off = 0;
187         *cu_off = 0;
188     }
189     return res;
190 }
191 
192 /*  This function returns the global offset
193     (meaning the section offset) and length of
194     the CU that this die is a part of.
195     Used for correctness checking by dwarfdump.  */
196 int
dwarf_die_CU_offset_range(Dwarf_Die die,Dwarf_Off * cu_off,Dwarf_Off * cu_length,Dwarf_Error * error)197 dwarf_die_CU_offset_range(Dwarf_Die die,
198     Dwarf_Off * cu_off,
199     Dwarf_Off * cu_length,
200     Dwarf_Error * error)
201 {
202     Dwarf_CU_Context cu_context = 0;
203 
204     CHECK_DIE(die, DW_DLV_ERROR);
205     cu_context = die->di_cu_context;
206 
207     *cu_off = cu_context->cc_debug_offset;
208     *cu_length = cu_context->cc_length + cu_context->cc_length_size
209         + cu_context->cc_extension_size;
210     return DW_DLV_OK;
211 }
212 
213 
214 
215 int
dwarf_tag(Dwarf_Die die,Dwarf_Half * tag,Dwarf_Error * error)216 dwarf_tag(Dwarf_Die die, Dwarf_Half * tag, Dwarf_Error * error)
217 {
218     CHECK_DIE(die, DW_DLV_ERROR);
219     *tag = die->di_abbrev_list->abl_tag;
220     return DW_DLV_OK;
221 }
222 
223 /* Returns the children offsets for the given offset */
224 int
dwarf_offset_list(Dwarf_Debug dbg,Dwarf_Off offset,Dwarf_Bool is_info,Dwarf_Off ** offbuf,Dwarf_Unsigned * offcnt,Dwarf_Error * error)225 dwarf_offset_list(Dwarf_Debug dbg,
226     Dwarf_Off offset, Dwarf_Bool is_info,
227     Dwarf_Off **offbuf, Dwarf_Unsigned *offcnt,
228     Dwarf_Error * error)
229 {
230     Dwarf_Die die = 0;
231     Dwarf_Die child = 0;
232     Dwarf_Die sib_die = 0;
233     Dwarf_Die cur_die = 0;
234     Dwarf_Unsigned off_count = 0;
235     int res = 0;
236 
237     /* Temporary counter. */
238     Dwarf_Unsigned i = 0;
239 
240     /* Points to contiguous block of Dwarf_Off's to be returned. */
241     Dwarf_Off *ret_offsets = 0;
242 
243     Dwarf_Chain_2 curr_chain = 0;
244     Dwarf_Chain_2 prev_chain = 0;
245     Dwarf_Chain_2 head_chain = 0;
246 
247     *offbuf = NULL;
248     *offcnt = 0;
249 
250     /* Get DIE for offset */
251     res = dwarf_offdie_b(dbg,offset,is_info,&die,error);
252     if (DW_DLV_OK != res) {
253         return res;
254     }
255 
256     /* Get first child for die */
257     res = dwarf_child(die,&child,error);
258     if (DW_DLV_ERROR == res || DW_DLV_NO_ENTRY == res) {
259         return res;
260     }
261 
262     cur_die = child;
263     for (;;) {
264         if (DW_DLV_OK == res) {
265             int dres = 0;
266             Dwarf_Off cur_off = 0;
267 
268             /* Get Global offset for current die */
269             dres = dwarf_dieoffset(cur_die,&cur_off,error);
270             if (dres == DW_DLV_OK) {
271                 /* Normal. use cur_off. */
272             } else if (dres == DW_DLV_ERROR) {
273                 /* Should be impossible unless... */
274                 /* avoid leak. */
275                 /*  Just leave cur_off as zero. */
276                 /* dwarf_dealloc(dbg,*error,DW_DLA_ERROR); */
277                 /* *error = NULL; */
278                 return DW_DLV_ERROR;
279             } else { /* DW_DLV_NO_ENTRY */
280                 /* Impossible, dwarf_dieoffset never returns this */
281             }
282             /* Record offset in current entry chain */
283             curr_chain = (Dwarf_Chain_2)_dwarf_get_alloc(
284                 dbg,DW_DLA_CHAIN_2,1);
285             if (curr_chain == NULL) {
286                 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
287                 return (DW_DLV_ERROR);
288             }
289 
290             /* Put current offset on singly_linked list. */
291             curr_chain->ch_item = cur_off;
292             ++off_count;
293 
294             if (head_chain == NULL) {
295                 head_chain = prev_chain = curr_chain;
296             }
297             else {
298                 prev_chain->ch_next = curr_chain;
299                 prev_chain = curr_chain;
300             }
301         }
302 
303         /* Process any siblings entries if any */
304         sib_die = 0;
305         res = dwarf_siblingof_b(dbg,cur_die,is_info,&sib_die,error);
306         if (DW_DLV_ERROR == res) {
307             return res;
308         }
309         if (DW_DLV_NO_ENTRY == res) {
310             /* Done at this level. */
311             break;
312         }
313         /* res == DW_DLV_OK */
314         if (cur_die != die) {
315             dwarf_dealloc(dbg,cur_die,DW_DLA_DIE);
316         }
317         cur_die = sib_die;
318     }
319 
320     /* Points to contiguous block of Dwarf_Off's. */
321     ret_offsets = (Dwarf_Off *) _dwarf_get_alloc(dbg,
322         DW_DLA_ADDR, off_count);
323     if (ret_offsets == NULL) {
324         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
325         return (DW_DLV_ERROR);
326     }
327 
328     /*  Store offsets in contiguous block,
329         and deallocate the chain. */
330     curr_chain = head_chain;
331     for (i = 0; i < off_count; i++) {
332         *(ret_offsets + i) = curr_chain->ch_item;
333         prev_chain = curr_chain;
334         curr_chain = curr_chain->ch_next;
335         dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN_2);
336     }
337 
338     *offbuf = ret_offsets;
339     *offcnt = off_count;
340 
341     return DW_DLV_OK;
342 }
343 
344 static void
empty_local_attrlist(Dwarf_Debug dbg,Dwarf_Attribute attr)345 empty_local_attrlist(Dwarf_Debug dbg,
346     Dwarf_Attribute attr)
347 {
348     Dwarf_Attribute cur = 0;
349     Dwarf_Attribute next = 0;
350 
351     for (cur = attr; cur ; cur = next) {
352         next = cur->ar_next;
353         dwarf_dealloc(dbg,cur,DW_DLA_ATTR);
354     }
355 }
356 
357 /*  Now we use *_wrapper here,
358     We cannot leak memory.
359 */
360 int
dwarf_attrlist(Dwarf_Die die,Dwarf_Attribute ** attrbuf,Dwarf_Signed * attrcnt,Dwarf_Error * error)361 dwarf_attrlist(Dwarf_Die die,
362     Dwarf_Attribute ** attrbuf,
363     Dwarf_Signed * attrcnt, Dwarf_Error * error)
364 {
365     Dwarf_Unsigned attr_count = 0;
366     Dwarf_Unsigned attr = 0;
367     Dwarf_Unsigned attr_form = 0;
368     Dwarf_Unsigned i = 0;
369     Dwarf_Byte_Ptr abbrev_ptr = 0;
370     Dwarf_Byte_Ptr abbrev_end = 0;
371     Dwarf_Abbrev_List abbrev_list = 0;
372     Dwarf_Attribute head_attr = NULL;
373     Dwarf_Attribute curr_attr = NULL;
374     Dwarf_Attribute *attr_ptr = 0;
375     Dwarf_Debug dbg = 0;
376     Dwarf_Byte_Ptr info_ptr = 0;
377     Dwarf_Byte_Ptr die_info_end = 0;
378     int lres = 0;
379     Dwarf_CU_Context context = 0;
380 
381     CHECK_DIE(die, DW_DLV_ERROR);
382     context = die->di_cu_context;
383     dbg = context->cc_dbg;
384     die_info_end =
385         _dwarf_calculate_info_section_end_ptr(context);
386 
387     lres = _dwarf_get_abbrev_for_code(context,
388         die->di_abbrev_list->abl_code,
389         &abbrev_list,error);
390     if (lres == DW_DLV_ERROR) {
391         return lres;
392     }
393     if (lres == DW_DLV_NO_ENTRY) {
394         _dwarf_error(dbg, error, DW_DLE_ABBREV_MISSING);
395         return DW_DLV_ERROR;
396     }
397 
398     abbrev_ptr = abbrev_list->abl_abbrev_ptr;
399     abbrev_end = _dwarf_calculate_abbrev_section_end_ptr(context);
400 
401 
402     info_ptr = die->di_debug_ptr;
403     {
404         /* SKIP_LEB128_WORD_CK(info_ptr,dbg,error,die_info_end); */
405         Dwarf_Unsigned ignore_this = 0;
406         Dwarf_Unsigned len = 0;
407 
408         lres = _dwarf_decode_u_leb128_chk(info_ptr,
409             &len,&ignore_this,die_info_end);
410         if (lres == DW_DLV_ERROR) {
411             /* Stepped off the end SKIPping the leb  */
412             dwarfstring m;
413 
414             dwarfstring_constructor(&m);
415             dwarfstring_append_printf_u(&m,
416                 "DW_DLE_DIE_BAD: In building an attrlist "
417                 "we run off the end of the DIE while skipping "
418                 " the DIE tag, seeing the leb length as 0x%u ",
419                 len);
420             _dwarf_error_string(dbg, error, DW_DLE_DIE_BAD,
421                 dwarfstring_string(&m));
422             dwarfstring_destructor(&m);
423             return DW_DLV_ERROR;
424         }
425         info_ptr += len;
426     }
427 
428     do {
429         Dwarf_Signed implicit_const = 0;
430         Dwarf_Attribute new_attr = 0;
431         int res = 0;
432 
433         /*  The DECODE have to be wrapped in functions to
434             catch errors before return. */
435         /*DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2,
436             dbg,error,abbrev_end); */
437         res = _dwarf_leb128_uword_wrapper(dbg,
438             &abbrev_ptr,abbrev_end,&attr,error);
439         if (res == DW_DLV_ERROR) {
440             empty_local_attrlist(dbg,head_attr);
441             return res;
442         }
443         if (attr > DW_AT_hi_user) {
444             empty_local_attrlist(dbg,head_attr);
445             _dwarf_error(dbg, error,DW_DLE_ATTR_CORRUPT);
446             return DW_DLV_ERROR;
447         }
448         /*DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2,
449             dbg,error,abbrev_end); */
450         res = _dwarf_leb128_uword_wrapper(dbg,
451             &abbrev_ptr,abbrev_end,&attr_form,error);
452         if (res == DW_DLV_ERROR) {
453             empty_local_attrlist(dbg,head_attr);
454             return res;
455         }
456         if (!_dwarf_valid_form_we_know(attr_form,attr)) {
457             empty_local_attrlist(dbg,head_attr);
458             _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM);
459             return (DW_DLV_ERROR);
460         }
461         if (attr_form == DW_FORM_implicit_const) {
462             /* The value is here, not in a DIE. */
463             res = _dwarf_leb128_sword_wrapper(dbg,&abbrev_ptr,
464                 abbrev_end, &implicit_const, error);
465             if (res == DW_DLV_ERROR) {
466                 empty_local_attrlist(dbg,head_attr);
467                 return res;
468             }
469             /*DECODE_LEB128_SWORD_CK(abbrev_ptr, implicit_const,
470                 dbg,error,abbrev_end); */
471         }
472 
473         if (!_dwarf_valid_form_we_know(attr_form,attr)) {
474             empty_local_attrlist(dbg,head_attr);
475             _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM);
476             return DW_DLV_ERROR;
477         }
478         if (attr != 0) {
479             new_attr = (Dwarf_Attribute)
480                 _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
481             if (new_attr == NULL) {
482                 empty_local_attrlist(dbg,head_attr);
483                 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
484                 return DW_DLV_ERROR;
485             }
486             new_attr->ar_attribute = attr;
487             new_attr->ar_attribute_form_direct = attr_form;
488             new_attr->ar_attribute_form = attr_form;
489             if (attr_form == DW_FORM_indirect) {
490                 Dwarf_Unsigned utmp6 = 0;
491 
492                 if (_dwarf_reference_outside_section(die,
493                     (Dwarf_Small*) info_ptr,
494                     ((Dwarf_Small*) info_ptr )+1)) {
495                     dwarf_dealloc(dbg,new_attr,DW_DLA_ATTR);
496                     empty_local_attrlist(dbg,head_attr);
497                     _dwarf_error_string(dbg, error,
498                         DW_DLE_ATTR_OUTSIDE_SECTION,
499                         "DW_DLE_ATTR_OUTSIDE_SECTION: "
500                         " Reading Attriutes: "
501                         "For DW_FORM_indirect there is"
502                         " no room for the form. Corrupt Dwarf");
503                     return DW_DLV_ERROR;
504                 }
505 
506                 /*  DECODE_LEB128_UWORD does info_ptr update
507                     DECODE_LEB128_UWORD_CK(info_ptr, utmp6,
508                         dbg,error,die_info_end);
509                 */
510                 res = _dwarf_leb128_uword_wrapper(dbg,
511                     &info_ptr,die_info_end,&utmp6,error);
512                 attr_form = (Dwarf_Half) utmp6;
513                 new_attr->ar_attribute_form = attr_form;
514             }
515             /*  Here the final address must be *inside* the
516                 section, as we will read from there, and read
517                 at least one byte, we think.
518                 We do not want info_ptr to point past end so
519                 we add 1 to the end-pointer.  */
520             if ( attr_form != DW_FORM_implicit_const &&
521                 _dwarf_reference_outside_section(die,
522                 (Dwarf_Small*) info_ptr,
523                 ((Dwarf_Small*) info_ptr )+1)) {
524                 dwarf_dealloc(dbg,new_attr,DW_DLA_ATTR);
525                 empty_local_attrlist(dbg,head_attr);
526                 _dwarf_error_string(dbg, error,
527                     DW_DLE_ATTR_OUTSIDE_SECTION,
528                     "DW_DLE_ATTR_OUTSIDE_SECTION: "
529                     " Reading Attriutes: "
530                     "We have run off the end of the section. "
531                     "Corrupt Dwarf");
532                 return DW_DLV_ERROR;
533             }
534             new_attr->ar_cu_context = die->di_cu_context;
535             new_attr->ar_debug_ptr = info_ptr;
536             new_attr->ar_die = die;
537             new_attr->ar_dbg = dbg;
538             if (attr_form == DW_FORM_implicit_const) {
539                 /*  The value is here, not in a DIE.
540                     Do not increment info_ptr */
541                 new_attr->ar_implicit_const = implicit_const;
542             } else {
543                 Dwarf_Unsigned sov = 0;
544                 int vres = 0;
545 
546                 vres = _dwarf_get_size_of_val(dbg,
547                     attr_form,
548                     die->di_cu_context->cc_version_stamp,
549                     die->di_cu_context->cc_address_size,
550                     info_ptr,
551                     die->di_cu_context->cc_length_size,
552                     &sov,
553                     die_info_end,
554                     error);
555                 if(vres!= DW_DLV_OK) {
556                     dwarf_dealloc(dbg,new_attr,DW_DLA_ATTR);
557                     empty_local_attrlist(dbg,head_attr);
558                     return vres;
559                 }
560                 info_ptr += sov;
561             }
562             if (head_attr == NULL)
563                 head_attr = curr_attr = new_attr;
564             else {
565                 curr_attr->ar_next = new_attr;
566                 curr_attr = new_attr;
567             }
568             attr_count++;
569         }
570     } while (attr || attr_form);
571     if (!attr_count) {
572         *attrbuf = NULL;
573         *attrcnt = 0;
574         return (DW_DLV_NO_ENTRY);
575     }
576     attr_ptr = (Dwarf_Attribute *)
577         _dwarf_get_alloc(dbg, DW_DLA_LIST, attr_count);
578     if (attr_ptr == NULL) {
579         empty_local_attrlist(dbg,head_attr);
580         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
581         return (DW_DLV_ERROR);
582     }
583     curr_attr = head_attr;
584     for (i = 0; i < attr_count; i++) {
585         *(attr_ptr + i) = curr_attr;
586         curr_attr = curr_attr->ar_next;
587     }
588     *attrbuf = attr_ptr;
589     *attrcnt = attr_count;
590     return (DW_DLV_OK);
591 }
592 
593 
594 /*
595     This function takes a die, and an attr, and returns
596     a pointer to the start of the value of that attr in
597     the given die in the .debug_info section.  The form
598     is returned in *attr_form.
599 
600     If the attr_form is DW_FORM_implicit_const
601     (known signed, so most callers)
602     that is fine, but in that case we do not
603     need to actually set the *ptr_to_value.
604 
605     Returns NULL on error, or if attr is not found.
606     However, *attr_form is 0 on error, and positive
607     otherwise.
608 */
609 static int
_dwarf_get_value_ptr(Dwarf_Die die,Dwarf_Half attr,Dwarf_Half * attr_form,Dwarf_Byte_Ptr * ptr_to_value,Dwarf_Signed * implicit_const_out,Dwarf_Error * error)610 _dwarf_get_value_ptr(Dwarf_Die die,
611     Dwarf_Half attr,
612     Dwarf_Half * attr_form,
613     Dwarf_Byte_Ptr * ptr_to_value,
614     Dwarf_Signed *implicit_const_out,
615     Dwarf_Error *error)
616 {
617     Dwarf_Byte_Ptr abbrev_ptr = 0;
618     Dwarf_Byte_Ptr abbrev_end = 0;
619     Dwarf_Abbrev_List abbrev_list;
620     Dwarf_Half curr_attr = 0;
621     Dwarf_Half curr_attr_form = 0;
622     Dwarf_Byte_Ptr info_ptr = 0;
623     Dwarf_CU_Context context = die->di_cu_context;
624     Dwarf_Byte_Ptr die_info_end = 0;
625     Dwarf_Debug dbg = 0;
626     int lres = 0;
627 
628     if (!context) {
629         _dwarf_error(NULL,error,DW_DLE_DIE_NO_CU_CONTEXT);
630         return DW_DLV_ERROR;
631     }
632     dbg = context->cc_dbg;
633     die_info_end =
634         _dwarf_calculate_info_section_end_ptr(context);
635 
636     lres = _dwarf_get_abbrev_for_code(context,
637         die->di_abbrev_list->abl_code,
638         &abbrev_list,error);
639     if (lres == DW_DLV_ERROR) {
640         return lres;
641     }
642     if (lres == DW_DLV_NO_ENTRY) {
643         _dwarf_error(dbg,error,DW_DLE_CU_DIE_NO_ABBREV_LIST);
644         return DW_DLV_ERROR;
645     }
646 
647     abbrev_ptr = abbrev_list->abl_abbrev_ptr;
648     abbrev_end = _dwarf_calculate_abbrev_section_end_ptr(context);
649 
650     info_ptr = die->di_debug_ptr;
651     /* This ensures and checks die_info_end >= info_ptr */
652     {
653         /* SKIP_LEB128_WORD_CK(info_ptr,dbg,error,die_info_end); */
654         Dwarf_Unsigned ignore_this = 0;
655         Dwarf_Unsigned len = 0;
656 
657         lres = _dwarf_decode_u_leb128_chk(info_ptr,
658             &len,&ignore_this,die_info_end);
659         if (lres == DW_DLV_ERROR) {
660             /* Stepped off the end SKIPping the leb  */
661             dwarfstring m;
662             dwarfstring_constructor(&m);
663             dwarfstring_append_printf_u(&m,
664                 "DW_DLE_DIE_BAD: In building an attrlist "
665                 "we run off the end of the DIE while skipping "
666                 " the DIE tag, seeing the leb length as 0x%u ",
667                 len);
668             _dwarf_error_string(dbg, error, DW_DLE_DIE_BAD,
669                 dwarfstring_string(&m));
670             dwarfstring_destructor(&m);
671             return DW_DLV_ERROR;
672         }
673         info_ptr += len;
674     }
675     do {
676         Dwarf_Unsigned formtmp3 = 0;
677         Dwarf_Unsigned atmp3 = 0;
678         Dwarf_Unsigned value_size=0;
679         Dwarf_Signed implicit_const = 0;
680         int res = 0;
681 
682         DECODE_LEB128_UWORD_CK(abbrev_ptr, atmp3,dbg,error,abbrev_end);
683         if (atmp3 > DW_AT_hi_user) {
684             _dwarf_error(dbg, error,DW_DLE_ATTR_CORRUPT);
685             return DW_DLV_ERROR;
686         }
687         curr_attr = (Dwarf_Half) atmp3;
688 
689         DECODE_LEB128_UWORD_CK(abbrev_ptr,formtmp3,
690             dbg,error,abbrev_end);
691         if (!_dwarf_valid_form_we_know(formtmp3,curr_attr)) {
692             _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM);
693             return (DW_DLV_ERROR);
694         }
695 
696         curr_attr_form = (Dwarf_Half) formtmp3;
697         if (curr_attr_form == DW_FORM_indirect) {
698             Dwarf_Unsigned utmp6;
699 
700             /* DECODE_LEB128_UWORD updates info_ptr */
701             DECODE_LEB128_UWORD_CK(info_ptr, utmp6,dbg,error,die_info_end);
702             curr_attr_form = (Dwarf_Half) utmp6;
703         }
704         if (curr_attr_form == DW_FORM_implicit_const) {
705             /* The value is here, not in a DIE. */
706             DECODE_LEB128_SWORD_CK(abbrev_ptr, implicit_const,
707                 dbg,error,abbrev_end);
708         }
709         if (curr_attr == attr) {
710             *attr_form = curr_attr_form;
711             if(implicit_const_out) {
712                 *implicit_const_out = implicit_const;
713             }
714             *ptr_to_value = info_ptr;
715             return DW_DLV_OK;
716         }
717         res = _dwarf_get_size_of_val(dbg,
718             curr_attr_form,
719             die->di_cu_context->cc_version_stamp,
720             die->di_cu_context->cc_address_size,
721             info_ptr,
722             die->di_cu_context->cc_length_size,
723             &value_size,
724             die_info_end,
725             error);
726         if (res != DW_DLV_OK) {
727             return res;
728         }
729         {
730             /* ptrdiff_t is signed type, so use DW signed type */
731             Dwarf_Signed len = die_info_end - info_ptr;
732             if (len < 0 || (value_size > ((Dwarf_Unsigned)len))) {
733                 /*  Something badly wrong. We point past end
734                     of debug_info or debug_types or a
735                     section is unreasonably sized or we are
736                     pointing to two different sections? */
737                 _dwarf_error(dbg,error,DW_DLE_DIE_ABBREV_BAD);
738                 return DW_DLV_ERROR;
739             }
740         }
741         info_ptr+= value_size;
742     } while (curr_attr != 0 || curr_attr_form != 0);
743     return DW_DLV_NO_ENTRY;
744 }
745 
746 int
dwarf_die_text(Dwarf_Die die,Dwarf_Half attrnum,char ** ret_name,Dwarf_Error * error)747 dwarf_die_text(Dwarf_Die die,
748     Dwarf_Half attrnum,
749     char **ret_name,
750     Dwarf_Error * error)
751 {
752     Dwarf_Debug dbg = 0;
753     int res = DW_DLV_ERROR;
754     Dwarf_Attribute attr = 0;
755     Dwarf_Error lerr = 0;
756 
757     CHECK_DIE(die, DW_DLV_ERROR);
758 
759     res = dwarf_attr(die,attrnum,&attr,&lerr);
760     dbg = die->di_cu_context->cc_dbg;
761     if (res == DW_DLV_ERROR) {
762         return DW_DLV_NO_ENTRY;
763     }
764     if (res == DW_DLV_NO_ENTRY) {
765         return res;
766     }
767     res = dwarf_formstring(attr,ret_name,error);
768     dwarf_dealloc(dbg,attr, DW_DLA_ATTR);
769     attr = 0;
770     return res;
771 }
772 
773 int
dwarf_diename(Dwarf_Die die,char ** ret_name,Dwarf_Error * error)774 dwarf_diename(Dwarf_Die die,
775     char **ret_name,
776     Dwarf_Error * error)
777 {
778     return dwarf_die_text(die,DW_AT_name,ret_name,error);
779 }
780 
781 int
dwarf_hasattr(Dwarf_Die die,Dwarf_Half attr,Dwarf_Bool * return_bool,Dwarf_Error * error)782 dwarf_hasattr(Dwarf_Die die,
783     Dwarf_Half attr,
784     Dwarf_Bool * return_bool, Dwarf_Error * error)
785 {
786     Dwarf_Half attr_form = 0;
787     Dwarf_Byte_Ptr info_ptr = 0;
788     int res = 0;
789     Dwarf_Signed implicit_const;
790 
791     CHECK_DIE(die, DW_DLV_ERROR);
792 
793     res = _dwarf_get_value_ptr(die, attr, &attr_form,&info_ptr,
794         &implicit_const,error);
795     if(res == DW_DLV_ERROR) {
796         return res;
797     }
798     if(res == DW_DLV_NO_ENTRY) {
799         *return_bool = false;
800         return DW_DLV_OK;
801     }
802     *return_bool = (true);
803     return DW_DLV_OK;
804 }
805 
806 int
dwarf_attr(Dwarf_Die die,Dwarf_Half attr,Dwarf_Attribute * ret_attr,Dwarf_Error * error)807 dwarf_attr(Dwarf_Die die,
808     Dwarf_Half attr,
809     Dwarf_Attribute * ret_attr, Dwarf_Error * error)
810 {
811     Dwarf_Half attr_form = 0;
812     Dwarf_Attribute attrib = 0;
813     Dwarf_Byte_Ptr info_ptr = 0;
814     Dwarf_Debug dbg = 0;
815     int res = 0;
816     Dwarf_Signed implicit_const = 0;
817 
818     CHECK_DIE(die, DW_DLV_ERROR);
819     dbg = die->di_cu_context->cc_dbg;
820 
821     res = _dwarf_get_value_ptr(die, attr, &attr_form,&info_ptr,
822         &implicit_const,error);
823     if(res == DW_DLV_ERROR) {
824         return res;
825     }
826     if(res == DW_DLV_NO_ENTRY) {
827         return res;
828     }
829 
830     attrib = (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
831     if (!attrib) {
832         _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL,
833             "DW_DLE_ALLOC_FAIL allocating a single Dwarf_Attribute"
834             " in function dwarf_attr().");
835         return DW_DLV_ERROR;
836     }
837 
838     attrib->ar_attribute = attr;
839     attrib->ar_attribute_form = attr_form;
840     attrib->ar_attribute_form_direct = attr_form;
841     attrib->ar_cu_context = die->di_cu_context;
842 
843     /*  Only nonzero if DW_FORM_implicit_const */
844     attrib->ar_implicit_const = implicit_const;
845     /*  Only nonnull if not DW_FORM_implicit_const */
846     attrib->ar_debug_ptr = info_ptr;
847     attrib->ar_die = die;
848     attrib->ar_dbg = dbg;
849     *ret_attr = (attrib);
850     return DW_DLV_OK;
851 }
852 
853 /*  A DWP (.dwp) package object never contains .debug_addr,
854     only a normal .o or executable object.
855     Error returned here is on dbg, not tieddbg.
856     This looks for DW_AT_addr_base and if present
857     adds it in appropriately. */
858 int
_dwarf_extract_address_from_debug_addr(Dwarf_Debug dbg,Dwarf_CU_Context context,Dwarf_Unsigned index_to_addr,Dwarf_Addr * addr_out,Dwarf_Error * error)859 _dwarf_extract_address_from_debug_addr(Dwarf_Debug dbg,
860     Dwarf_CU_Context context,
861     Dwarf_Unsigned index_to_addr,
862     Dwarf_Addr *addr_out,
863     Dwarf_Error *error)
864 {
865     Dwarf_Unsigned address_base = 0;
866     Dwarf_Unsigned addrindex = index_to_addr;
867     Dwarf_Unsigned addr_offset = 0;
868     Dwarf_Unsigned ret_addr = 0;
869     int res = 0;
870     Dwarf_Byte_Ptr  sectionstart = 0;
871     Dwarf_Byte_Ptr  sectionend = 0;
872     Dwarf_Unsigned  sectionsize  = 0;
873 
874     res = _dwarf_get_address_base_attr_value(dbg,context,
875         &address_base, error);
876     if (res != DW_DLV_OK) {
877         return res;
878     }
879     res = _dwarf_load_section(dbg, &dbg->de_debug_addr,error);
880     if (res != DW_DLV_OK) {
881         /*  Ignore the inner error, report something meaningful */
882         if (res == DW_DLV_ERROR) {
883             dwarf_dealloc(dbg,*error, DW_DLA_ERROR);
884             *error = 0;
885         }
886         _dwarf_error(dbg,error,
887             DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION);
888         return DW_DLV_ERROR;
889     }
890     /*  DW_FORM_addrx has a base value from the CU die:
891         DW_AT_addr_base.  DW_OP_addrx and DW_OP_constx
892         rely on DW_AT_addr_base too. */
893     /*  DW_FORM_GNU_addr_index  relies on DW_AT_GNU_addr_base
894         which is in the CU die. */
895 
896     sectionstart = dbg->de_debug_addr.dss_data;
897     addr_offset = address_base + (addrindex * context->cc_address_size);
898     /*  The offsets table is a series of address-size entries
899         but with a base. */
900     sectionsize = dbg->de_debug_addr.dss_size;
901     sectionend = sectionstart + sectionsize;
902     if (addr_offset > (sectionsize - context->cc_address_size)) {
903         _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
904         return (DW_DLV_ERROR);
905     }
906     READ_UNALIGNED_CK(dbg,ret_addr,Dwarf_Addr,
907         sectionstart + addr_offset,
908         context->cc_address_size,
909         error,sectionend);
910     *addr_out = ret_addr;
911     return DW_DLV_OK;
912 }
913 
914 static int
_dwarf_look_in_local_and_tied_by_index(Dwarf_Debug dbg,Dwarf_CU_Context context,Dwarf_Unsigned index,Dwarf_Addr * return_addr,Dwarf_Error * error)915 _dwarf_look_in_local_and_tied_by_index(
916     Dwarf_Debug dbg,
917     Dwarf_CU_Context context,
918     Dwarf_Unsigned index,
919     Dwarf_Addr *return_addr,
920     Dwarf_Error *error)
921 {
922     int res2 = 0;
923 
924     res2 = _dwarf_extract_address_from_debug_addr(dbg,
925         context, index, return_addr, error);
926     if (res2 != DW_DLV_OK) {
927         if (res2 == DW_DLV_ERROR &&
928             error &&
929             dwarf_errno(*error) == DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION
930             && dbg->de_tied_data.td_tied_object) {
931             int res3 = 0;
932 
933             /*  We do not want to leak error structs... */
934             dwarf_dealloc(dbg,*error,DW_DLA_ERROR);
935 
936             *error = 0;
937             /* error is returned on dbg, not tieddbg. */
938             res3 = _dwarf_get_addr_from_tied(dbg,
939                 context,index,return_addr,error);
940             return res3;
941         }
942         return res2;
943     }
944     return DW_DLV_OK;
945 }
946 
947 /*  The DIE here can be any DIE in the relevant CU.
948     index is an index into .debug_addr */
949 int
dwarf_debug_addr_index_to_addr(Dwarf_Die die,Dwarf_Unsigned index,Dwarf_Addr * return_addr,Dwarf_Error * error)950 dwarf_debug_addr_index_to_addr(Dwarf_Die die,
951     Dwarf_Unsigned index,
952     Dwarf_Addr *return_addr,
953     Dwarf_Error *error)
954 {
955     Dwarf_Debug dbg = 0;
956     Dwarf_CU_Context context = 0;
957     int res = 0;
958 
959 
960     CHECK_DIE(die, DW_DLV_ERROR);
961     context = die->di_cu_context;
962     dbg = context->cc_dbg;
963 
964     /* error is returned on dbg, not tieddbg. */
965     res = _dwarf_look_in_local_and_tied_by_index(dbg,
966         context,
967         index,
968         return_addr,
969         error);
970     return res;
971 }
972 /* ASSERT:
973     attr_form == DW_FORM_GNU_addr_index ||
974         attr_form == DW_FORM_addrx
975 */
976 int
_dwarf_look_in_local_and_tied(Dwarf_Half attr_form,Dwarf_CU_Context context,Dwarf_Small * info_ptr,Dwarf_Addr * return_addr,Dwarf_Error * error)977 _dwarf_look_in_local_and_tied(Dwarf_Half attr_form,
978     Dwarf_CU_Context context,
979     Dwarf_Small *info_ptr,
980     Dwarf_Addr *return_addr,
981     Dwarf_Error *error)
982 {
983     int res2 = 0;
984     Dwarf_Unsigned index_to_addr = 0;
985     Dwarf_Debug dbg = 0;
986 
987     /*  We get the index. It might apply here
988         or in tied object. Checking that next. */
989     dbg = context->cc_dbg;
990     res2 = _dwarf_get_addr_index_itself(attr_form,
991         info_ptr,dbg,context, &index_to_addr,error);
992     if(res2 != DW_DLV_OK) {
993         return res2;
994     }
995     /* error is returned on dbg, not tieddbg. */
996     res2 = _dwarf_look_in_local_and_tied_by_index(
997         dbg,context,index_to_addr,return_addr,error);
998     return res2;
999 
1000 }
1001 
1002 int
dwarf_lowpc(Dwarf_Die die,Dwarf_Addr * return_addr,Dwarf_Error * error)1003 dwarf_lowpc(Dwarf_Die die,
1004     Dwarf_Addr * return_addr,
1005     Dwarf_Error * error)
1006 {
1007     Dwarf_Addr ret_addr = 0;
1008     Dwarf_Byte_Ptr info_ptr = 0;
1009     Dwarf_Half attr_form = 0;
1010     Dwarf_Debug dbg = 0;
1011     Dwarf_Half address_size = 0;
1012     Dwarf_Half offset_size = 0;
1013     int version = 0;
1014     enum Dwarf_Form_Class class = DW_FORM_CLASS_UNKNOWN;
1015     int res = 0;
1016     Dwarf_CU_Context context = die->di_cu_context;
1017     Dwarf_Small *die_info_end = 0;
1018 
1019     CHECK_DIE(die, DW_DLV_ERROR);
1020 
1021     dbg = context->cc_dbg;
1022     address_size = context->cc_address_size;
1023     offset_size = context->cc_length_size;
1024     res = _dwarf_get_value_ptr(die, DW_AT_low_pc,
1025         &attr_form,&info_ptr,0,error);
1026     if(res == DW_DLV_ERROR) {
1027         return res;
1028     }
1029     if(res == DW_DLV_NO_ENTRY) {
1030         return res;
1031     }
1032     version = context->cc_version_stamp;
1033     class = dwarf_get_form_class(version,DW_AT_low_pc,
1034         offset_size,attr_form);
1035     if (class != DW_FORM_CLASS_ADDRESS) {
1036         /* Not the correct form for DW_AT_low_pc */
1037         _dwarf_error(dbg, error, DW_DLE_LOWPC_WRONG_CLASS);
1038         return (DW_DLV_ERROR);
1039     }
1040 
1041     if(attr_form == DW_FORM_GNU_addr_index ||
1042         attr_form == DW_FORM_addrx) {
1043         /* error is returned on dbg, not tieddbg. */
1044         res = _dwarf_look_in_local_and_tied(
1045             attr_form,
1046             context,
1047             info_ptr,
1048             return_addr,
1049             error);
1050         return res;
1051     }
1052     die_info_end = _dwarf_calculate_info_section_end_ptr(context);
1053     READ_UNALIGNED_CK(dbg, ret_addr, Dwarf_Addr,
1054         info_ptr, address_size,
1055         error,die_info_end);
1056 
1057     *return_addr = ret_addr;
1058     return (DW_DLV_OK);
1059 }
1060 
1061 
1062 /*  This works for DWARF2 and DWARF3 but fails for DWARF4
1063     DW_AT_high_pc attributes of class constant.
1064     It is best to cease using this interface.
1065     */
1066 int
dwarf_highpc(Dwarf_Die die,Dwarf_Addr * return_addr,Dwarf_Error * error)1067 dwarf_highpc(Dwarf_Die die,
1068     Dwarf_Addr * return_addr, Dwarf_Error * error)
1069 {
1070     int res = 0;
1071     enum Dwarf_Form_Class class = DW_FORM_CLASS_UNKNOWN;
1072     Dwarf_Half form = 0;
1073 
1074     CHECK_DIE(die, DW_DLV_ERROR);
1075     res = dwarf_highpc_b(die,return_addr,&form,&class,error);
1076     if (res != DW_DLV_OK) {
1077         return res;
1078     }
1079     if (form != DW_FORM_addr) {
1080         /* Not the correct form for DWARF2/3 DW_AT_high_pc */
1081         Dwarf_Debug dbg = die->di_cu_context->cc_dbg;
1082         _dwarf_error(dbg, error, DW_DLE_HIGHPC_WRONG_FORM);
1083         return (DW_DLV_ERROR);
1084     }
1085     return (DW_DLV_OK);
1086 }
1087 
1088 /*  If the giving 'die' contains the DW_AT_type attribute, it returns
1089     the offset referenced by the attribute.
1090     In case of DW_DLV_NO_ENTRY or DW_DLV_ERROR it sets offset zero. */
1091 int
dwarf_dietype_offset(Dwarf_Die die,Dwarf_Off * return_off,Dwarf_Error * error)1092 dwarf_dietype_offset(Dwarf_Die die,
1093     Dwarf_Off *return_off, Dwarf_Error *error)
1094 {
1095     int res = 0;
1096     Dwarf_Off offset = 0;
1097     Dwarf_Attribute attr = 0;
1098 
1099     CHECK_DIE(die, DW_DLV_ERROR);
1100     res = dwarf_attr(die,DW_AT_type,&attr,error);
1101     if (res == DW_DLV_OK) {
1102         res = dwarf_global_formref(attr,&offset,error);
1103         dwarf_dealloc(die->di_cu_context->cc_dbg,attr,DW_DLA_ATTR);
1104     }
1105     *return_off = offset;
1106     return res;
1107 }
1108 
1109 
1110 
1111 int
_dwarf_get_string_base_attr_value(Dwarf_Debug dbg,Dwarf_CU_Context context,Dwarf_Unsigned * sbase_out,Dwarf_Error * error)1112 _dwarf_get_string_base_attr_value(Dwarf_Debug dbg,
1113     Dwarf_CU_Context context,
1114     Dwarf_Unsigned *sbase_out,
1115     Dwarf_Error *error)
1116 {
1117     int res = 0;
1118     Dwarf_Die cudie = 0;
1119     Dwarf_Unsigned cu_die_offset = 0;
1120     Dwarf_Attribute myattr = 0;
1121 
1122     if(context->cc_str_offsets_base_present) {
1123         *sbase_out = context->cc_str_offsets_base;
1124         return DW_DLV_OK;
1125     }
1126     cu_die_offset = context->cc_cu_die_global_sec_offset;
1127     context->cc_cu_die_offset_present  = TRUE;
1128     res = dwarf_offdie_b(dbg,cu_die_offset,
1129         context->cc_is_info,
1130         &cudie,
1131         error);
1132     if(res != DW_DLV_OK) {
1133         return res;
1134     }
1135     res = dwarf_attr(cudie,DW_AT_str_offsets_base,
1136         &myattr,error);
1137     if(res == DW_DLV_ERROR) {
1138         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1139         return res;
1140     }
1141     if (res == DW_DLV_OK) {
1142         Dwarf_Unsigned val = 0;
1143         /* Expect DW_FORM_sec_offset */
1144         if (myattr->ar_attribute_form != DW_FORM_sec_offset) {
1145             dwarf_dealloc(dbg,myattr,DW_DLA_ATTR);
1146             dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1147             _dwarf_error(dbg, error,DW_DLE_STR_OFFSETS_BASE_WRONG_FORM);
1148             return (DW_DLV_ERROR);
1149         }
1150         res = dwarf_global_formref(myattr,&val,error);
1151         dwarf_dealloc(dbg,myattr,DW_DLA_ATTR);
1152         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1153         if(res != DW_DLV_OK) {
1154             return res;
1155         }
1156         *sbase_out  = val;
1157         context->cc_str_offsets_base = val;
1158         context->cc_str_offsets_base_present = TRUE;
1159         return DW_DLV_OK;
1160     }
1161     /*  NO ENTRY, No other attr.Not even GNU, this one is standard
1162         DWARF5 only.  */
1163     dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1164     /*  We do not need a base for a .dwo. We might for .dwp
1165         and would or .o or executable.
1166         FIXME: assume we do not need this.
1167         Should we really return DW_DLV_NO_ENTRY?
1168     */
1169     *sbase_out = 0;
1170     return DW_DLV_OK;
1171 }
1172 /*  Goes to the CU die and finds the DW_AT_GNU_addr_base
1173     (or DW_AT_addr_base ) and gets the value from that CU die
1174     and returns it through abase_out. If we cannot find the value
1175     it is a serious error in the DWARF.
1176     */
1177 static int
_dwarf_get_address_base_attr_value(Dwarf_Debug dbg,Dwarf_CU_Context context,Dwarf_Unsigned * abase_out,Dwarf_Error * error)1178 _dwarf_get_address_base_attr_value(Dwarf_Debug dbg,
1179     Dwarf_CU_Context context,
1180     Dwarf_Unsigned *abase_out,
1181     Dwarf_Error *error)
1182 {
1183     int res = 0;
1184     Dwarf_Die cudie = 0;
1185     Dwarf_Bool cu_die_offset_present = 0;
1186     Dwarf_Unsigned cu_die_offset = 0;
1187     Dwarf_Attribute myattr = 0;
1188     if(context->cc_addr_base_present) {
1189         *abase_out = context->cc_addr_base;
1190         return DW_DLV_OK;
1191     }
1192 
1193     cu_die_offset = context->cc_cu_die_global_sec_offset;
1194     cu_die_offset_present = context->cc_cu_die_offset_present;
1195     if(!cu_die_offset_present) {
1196         _dwarf_error(dbg, error,
1197             DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM);
1198         return (DW_DLV_ERROR);
1199 
1200     }
1201     res = dwarf_offdie_b(dbg,cu_die_offset,
1202         context->cc_is_info,
1203         &cudie,
1204         error);
1205     if(res != DW_DLV_OK) {
1206         return res;
1207     }
1208     res = dwarf_attr(cudie,DW_AT_addr_base,
1209         &myattr,error);
1210     if(res == DW_DLV_ERROR) {
1211         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1212         return res;
1213     }
1214     if (res == DW_DLV_OK) {
1215         Dwarf_Unsigned val = 0;
1216         res = dwarf_formudata(myattr,&val,error);
1217         dwarf_dealloc(dbg,myattr,DW_DLA_ATTR);
1218         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1219         if(res != DW_DLV_OK) {
1220             return res;
1221         }
1222         *abase_out  = val;
1223         return DW_DLV_OK;
1224     }
1225     /* NO ENTRY, try the other attr. */
1226     res = dwarf_attr(cudie,DW_AT_GNU_addr_base, &myattr,error);
1227     if(res == DW_DLV_NO_ENTRY) {
1228         res = dwarf_attr(cudie,DW_AT_addr_base, &myattr,error);
1229         if (res == DW_DLV_NO_ENTRY) {
1230             /*  A .o or .dwp needs a base, but a .dwo does not.
1231                 FIXME: check this claim...
1232                 Assume zero is ok and works. */
1233             *abase_out = 0;
1234             dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1235             return DW_DLV_OK;
1236         }
1237         if (res == DW_DLV_ERROR) {
1238             dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1239             return res;
1240         }
1241     } else if (res == DW_DLV_ERROR) {
1242         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1243         return res;
1244     }
1245 
1246     {
1247         Dwarf_Unsigned val = 0;
1248         res = dwarf_formudata(myattr,&val,error);
1249         dwarf_dealloc(dbg,myattr,DW_DLA_ATTR);
1250         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1251         if(res != DW_DLV_OK) {
1252             return res;
1253         }
1254         *abase_out  = val;
1255     }
1256     return DW_DLV_OK;
1257 }
1258 
1259 
1260 /* The dbg here will be the tieddbg, and context will be
1261    a tied context.  */
1262 static int
_dwarf_get_ranges_base_attr_value(Dwarf_Debug dbg,Dwarf_CU_Context context,Dwarf_Unsigned * rangesbase_out,Dwarf_Error * error)1263 _dwarf_get_ranges_base_attr_value(Dwarf_Debug dbg,
1264     Dwarf_CU_Context context,
1265     Dwarf_Unsigned * rangesbase_out,
1266     Dwarf_Error    * error)
1267 {
1268     int res = 0;
1269     Dwarf_Die cudie = 0;
1270     Dwarf_Bool cu_die_offset_present = 0;
1271     Dwarf_Unsigned cu_die_offset = 0;
1272     Dwarf_Attribute myattr = 0;
1273 
1274     if (!context) {
1275         _dwarf_error(dbg, error,
1276             DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM);
1277         return (DW_DLV_ERROR);
1278     }
1279     if(context->cc_ranges_base_present) {
1280         *rangesbase_out = context->cc_ranges_base;
1281         return DW_DLV_OK;
1282     }
1283     cu_die_offset = context->cc_cu_die_global_sec_offset;
1284     cu_die_offset_present = context->cc_cu_die_offset_present;
1285     if(!cu_die_offset_present) {
1286         _dwarf_error(dbg, error,
1287             DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM);
1288         return (DW_DLV_ERROR);
1289 
1290     }
1291     res = dwarf_offdie_b(dbg,cu_die_offset,
1292         context->cc_is_info,
1293         &cudie,
1294         error);
1295     if(res != DW_DLV_OK) {
1296         return res;
1297     }
1298     res = dwarf_attr(cudie,DW_AT_rnglists_base,
1299         &myattr,error);
1300     if(res == DW_DLV_ERROR) {
1301         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1302         return res;
1303     }
1304     if (res == DW_DLV_OK) {
1305         Dwarf_Unsigned val = 0;
1306         res = dwarf_formudata(myattr,&val,error);
1307         dwarf_dealloc(dbg,myattr,DW_DLA_ATTR);
1308         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1309         if(res != DW_DLV_OK) {
1310             return res;
1311         }
1312         *rangesbase_out  = val;
1313         return DW_DLV_OK;
1314     }
1315     /* NO ENTRY, try the other attr. */
1316     res = dwarf_attr(cudie,DW_AT_GNU_ranges_base, &myattr,error);
1317     if(res == DW_DLV_NO_ENTRY) {
1318         res = dwarf_attr(cudie,DW_AT_rnglists_base, &myattr,error);
1319         if (res == DW_DLV_NO_ENTRY) {
1320             /*  A .o or execeutable skeleton  needs
1321                 a base , but a .dwo does not.
1322                 Assume zero is ok and works. */
1323             *rangesbase_out = 0;
1324             dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1325             return DW_DLV_OK;
1326         }
1327         if (res == DW_DLV_ERROR) {
1328             dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1329             return res;
1330         }
1331     } else if (res == DW_DLV_ERROR) {
1332         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1333         return res;
1334     }
1335 
1336     {
1337         Dwarf_Unsigned val = 0;
1338         res = dwarf_formudata(myattr,&val,error);
1339         dwarf_dealloc(dbg,myattr,DW_DLA_ATTR);
1340         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1341         if(res != DW_DLV_OK) {
1342             return res;
1343         }
1344         *rangesbase_out  = val;
1345     }
1346     return DW_DLV_OK;
1347 }
1348 /*  This works for  all versions of DWARF.
1349     This is the preferred interface, cease using dwarf_highpc.
1350     The consumer has to check the return_form or
1351     return_class to decide if the value returned
1352     through return_value is an address or an address-offset.
1353 
1354     See  DWARF4 section 2.17.2,
1355     "Contiguous Address Range".
1356     */
1357 int
dwarf_highpc_b(Dwarf_Die die,Dwarf_Addr * return_value,Dwarf_Half * return_form,enum Dwarf_Form_Class * return_class,Dwarf_Error * error)1358 dwarf_highpc_b(Dwarf_Die die,
1359     Dwarf_Addr * return_value,
1360     Dwarf_Half * return_form,
1361     enum Dwarf_Form_Class * return_class,
1362     Dwarf_Error * error)
1363 {
1364     Dwarf_Byte_Ptr info_ptr = 0;
1365     Dwarf_Half attr_form = 0;
1366     Dwarf_Debug dbg = 0;
1367     Dwarf_Half address_size = 0;
1368     Dwarf_Half offset_size = 0;
1369     enum Dwarf_Form_Class class = DW_FORM_CLASS_UNKNOWN;
1370     Dwarf_Half version = 0;
1371     Dwarf_Byte_Ptr die_info_end = 0;
1372     int res = 0;
1373 
1374     CHECK_DIE(die, DW_DLV_ERROR);
1375     dbg = die->di_cu_context->cc_dbg;
1376     address_size = die->di_cu_context->cc_address_size;
1377 
1378     res = _dwarf_get_value_ptr(die, DW_AT_high_pc,
1379         &attr_form,&info_ptr,0,error);
1380     if(res == DW_DLV_ERROR) {
1381         return res;
1382     }
1383     if(res == DW_DLV_NO_ENTRY) {
1384         return res;
1385     }
1386     die_info_end = _dwarf_calculate_info_section_end_ptr(
1387         die->di_cu_context);
1388 
1389     version = die->di_cu_context->cc_version_stamp;
1390     offset_size = die->di_cu_context->cc_length_size;
1391     class = dwarf_get_form_class(version,DW_AT_high_pc,
1392         offset_size,attr_form);
1393 
1394     if (class == DW_FORM_CLASS_ADDRESS) {
1395         Dwarf_Addr addr = 0;
1396         if (dwarf_addr_form_is_indexed(attr_form)) {
1397             Dwarf_Unsigned addr_out = 0;
1398             Dwarf_Unsigned index_to_addr = 0;
1399             int res2 = 0;
1400             Dwarf_CU_Context context = die->di_cu_context;
1401 
1402             /*  index_to_addr we get here might apply
1403                 to this dbg or to tieddbg. */
1404             /* error is returned on dbg, not tied */
1405             res2 = _dwarf_get_addr_index_itself(attr_form,
1406                 info_ptr,dbg,context,&index_to_addr,error);
1407             if(res2 != DW_DLV_OK) {
1408                 return res2;
1409             }
1410 
1411             res2 = _dwarf_extract_address_from_debug_addr(dbg,
1412                 context,
1413                 index_to_addr,
1414                 &addr_out,
1415                 error);
1416             if(res2 != DW_DLV_OK) {
1417                 if (res2 == DW_DLV_ERROR &&
1418                     error &&
1419                     dwarf_errno(*error) ==
1420                     DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION
1421                     && dbg->de_tied_data.td_tied_object) {
1422                     /*  .debug_addr is in tied dbg. */
1423                     int res3 = 0;
1424 
1425                     /*  Do not leak the above error pointer,
1426                         we have something else to try here. */
1427                     dwarf_dealloc(dbg,*error, DW_DLA_ERROR);
1428                     *error = 0;
1429 
1430                     /*  .debug_addr is in tied dbg.
1431                         Get the index of the addr */
1432                     res3 = _dwarf_get_addr_from_tied(dbg,
1433                         context,index_to_addr,&addr_out,error);
1434                     if ( res3 != DW_DLV_OK) {
1435                         return res3;
1436                     }
1437                 } else {
1438                     return res2;
1439                 }
1440             }
1441             *return_value = addr_out;
1442             /*  Allow null args starting 22 April 2019. */
1443             if (return_form) {
1444                 *return_form = attr_form;
1445             }
1446             if (return_class) {
1447                 *return_class = class;
1448             }
1449             return (DW_DLV_OK);
1450         }
1451 
1452         READ_UNALIGNED_CK(dbg, addr, Dwarf_Addr,
1453             info_ptr, address_size,
1454             error,die_info_end);
1455         *return_value = addr;
1456     } else {
1457         int res3 = 0;
1458         Dwarf_Unsigned v = 0;
1459         res3 = _dwarf_die_attr_unsigned_constant(die,DW_AT_high_pc,
1460             &v,error);
1461         if(res3 != DW_DLV_OK) {
1462             Dwarf_Byte_Ptr info_ptr2 = 0;
1463 
1464             res3 = _dwarf_get_value_ptr(die, DW_AT_high_pc,
1465                 &attr_form,&info_ptr2,0,error);
1466             if(res3 == DW_DLV_ERROR) {
1467                 return res3;
1468             }
1469             if(res3 == DW_DLV_NO_ENTRY) {
1470                 return res3;
1471             }
1472             if (attr_form == DW_FORM_sdata) {
1473                 Dwarf_Signed sval = 0;
1474 
1475                 /*  DWARF4 defines the value as an unsigned offset
1476                     in section 2.17.2. */
1477                 DECODE_LEB128_UWORD_CK(info_ptr2, sval,
1478                     dbg,error,die_info_end);
1479                 *return_value = (Dwarf_Unsigned)sval;
1480             } else {
1481                 _dwarf_error(dbg, error, DW_DLE_HIGHPC_WRONG_FORM);
1482                 return DW_DLV_ERROR;
1483             }
1484         } else {
1485             *return_value = v;
1486         }
1487     }
1488     /*  Allow null args starting 22 April 2019. */
1489     if (return_form) {
1490         *return_form = attr_form;
1491     }
1492     if (return_class) {
1493         *return_class = class;
1494     }
1495     return DW_DLV_OK;
1496 }
1497 
1498 /* The dbg and context here are a file with DW_FORM_addrx
1499     but missing .debug_addr. So go to the tied file
1500     and using the signature from the current context
1501     locate the target CU in the tied file Then
1502     get the address.
1503 
1504 */
1505 int
_dwarf_get_addr_from_tied(Dwarf_Debug dbg,Dwarf_CU_Context context,Dwarf_Unsigned index,Dwarf_Addr * addr_out,Dwarf_Error * error)1506 _dwarf_get_addr_from_tied(Dwarf_Debug dbg,
1507     Dwarf_CU_Context context,
1508     Dwarf_Unsigned index,
1509     Dwarf_Addr *addr_out,
1510     Dwarf_Error*error)
1511 {
1512     Dwarf_Debug tieddbg = 0;
1513     int res = 0;
1514     Dwarf_Addr local_addr = 0;
1515     Dwarf_CU_Context tiedcontext = 0;
1516 
1517     if (!context->cc_signature_present) {
1518         _dwarf_error(dbg, error, DW_DLE_NO_SIGNATURE_TO_LOOKUP);
1519         return  DW_DLV_ERROR;
1520     }
1521     tieddbg = dbg->de_tied_data.td_tied_object;
1522     if (!tieddbg) {
1523         _dwarf_error(dbg, error, DW_DLE_NO_TIED_ADDR_AVAILABLE);
1524         return  DW_DLV_ERROR;
1525     }
1526     if (!context->cc_signature_present) {
1527         _dwarf_error(dbg, error, DW_DLE_NO_TIED_SIG_AVAILABLE);
1528         return  DW_DLV_ERROR;
1529     }
1530     res = _dwarf_search_for_signature(tieddbg,
1531         context->cc_signature,
1532         &tiedcontext,
1533         error);
1534     if ( res == DW_DLV_ERROR) {
1535         /* Associate the error with dbg, not tieddbg */
1536         _dwarf_error_mv_s_to_t(tieddbg,error,dbg,error);
1537         return res;
1538     } else if ( res == DW_DLV_NO_ENTRY) {
1539         return res;
1540     }
1541 
1542     res = _dwarf_extract_address_from_debug_addr(tieddbg,
1543         tiedcontext,
1544         index,
1545         &local_addr,
1546         error);
1547     if ( res == DW_DLV_ERROR) {
1548         /* Associate the error with dbg, not tidedbg */
1549         _dwarf_error_mv_s_to_t(tieddbg,error,dbg,error);
1550         return res;
1551     } else if ( res == DW_DLV_NO_ENTRY) {
1552         return res;
1553     }
1554     *addr_out = local_addr;
1555     return DW_DLV_OK;
1556 }
1557 
1558 int
_dwarf_get_ranges_base_attr_from_tied(Dwarf_Debug dbg,Dwarf_CU_Context context,Dwarf_Unsigned * ranges_base_out,Dwarf_Unsigned * addr_base_out,Dwarf_Error * error)1559 _dwarf_get_ranges_base_attr_from_tied(Dwarf_Debug dbg,
1560     Dwarf_CU_Context context,
1561     Dwarf_Unsigned * ranges_base_out,
1562     Dwarf_Unsigned * addr_base_out,
1563     Dwarf_Error*error)
1564 {
1565     Dwarf_Debug tieddbg = 0;
1566     int res = 0;
1567     Dwarf_Unsigned tiedbase= 0;
1568     Dwarf_CU_Context tiedcontext = 0;
1569 
1570     if (!context->cc_signature_present) {
1571         _dwarf_error(dbg, error, DW_DLE_NO_SIGNATURE_TO_LOOKUP);
1572         return  DW_DLV_ERROR;
1573     }
1574     tieddbg = dbg->de_tied_data.td_tied_object;
1575     if (!tieddbg) {
1576         _dwarf_error(dbg, error, DW_DLE_NO_TIED_ADDR_AVAILABLE);
1577         return  DW_DLV_ERROR;
1578     }
1579     if (!context->cc_signature_present) {
1580         _dwarf_error(dbg, error, DW_DLE_NO_TIED_SIG_AVAILABLE);
1581         return  DW_DLV_ERROR;
1582     }
1583     res = _dwarf_search_for_signature(tieddbg,
1584         context->cc_signature,
1585         &tiedcontext,
1586         error);
1587     if ( res == DW_DLV_ERROR) {
1588         /* Associate the error with dbg, not tidedbg */
1589         _dwarf_error_mv_s_to_t(tieddbg,error,dbg,error);
1590         return res;
1591     } else if ( res == DW_DLV_NO_ENTRY) {
1592         return res;
1593     }
1594     res = _dwarf_get_ranges_base_attr_value(tieddbg, tiedcontext,
1595         &tiedbase, error);
1596     if (res != DW_DLV_OK) {
1597         /* Associate the error with dbg, not tidedbg */
1598         _dwarf_error_mv_s_to_t(tieddbg,error,dbg,error);
1599         return res;
1600     }
1601     *ranges_base_out = tiedbase;
1602     *addr_base_out =  tiedcontext->cc_addr_base;
1603     return DW_DLV_OK;
1604 }
1605 
1606 
1607 /*
1608     Takes a die, an attribute attr, and checks if attr
1609     occurs in die.  Attr is required to be an attribute
1610     whose form is in the "constant" class.  If attr occurs
1611     in die, the value is returned.
1612 
1613     Returns DW_DLV_OK, DW_DLV_ERROR, or DW_DLV_NO_ENTRY as
1614     appropriate. Sets the value thru the pointer return_val.
1615 
1616     This function is meant to do all the
1617     processing for dwarf_bytesize, dwarf_bitsize, dwarf_bitoffset,
1618     and dwarf_srclang. And it helps in dwarf_highpc_with_form().
1619 */
1620 static int
_dwarf_die_attr_unsigned_constant(Dwarf_Die die,Dwarf_Half attr,Dwarf_Unsigned * return_val,Dwarf_Error * error)1621 _dwarf_die_attr_unsigned_constant(Dwarf_Die die,
1622     Dwarf_Half attr,
1623     Dwarf_Unsigned * return_val,
1624     Dwarf_Error * error)
1625 {
1626     Dwarf_Byte_Ptr info_ptr = 0;
1627     Dwarf_Half attr_form = 0;
1628     Dwarf_Unsigned ret_value = 0;
1629     Dwarf_Debug dbg = 0;
1630     int res = 0;
1631     Dwarf_Byte_Ptr die_info_end = 0;
1632 
1633     CHECK_DIE(die, DW_DLV_ERROR);
1634 
1635     die_info_end = _dwarf_calculate_info_section_end_ptr(die->di_cu_context);
1636     dbg = die->di_cu_context->cc_dbg;
1637     res = _dwarf_get_value_ptr(die,attr,&attr_form,
1638         &info_ptr,0,error);
1639     if(res != DW_DLV_OK) {
1640         return res;
1641     }
1642     switch (attr_form) {
1643     case DW_FORM_data1:
1644         READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned,
1645             info_ptr, sizeof(Dwarf_Small),
1646             error,die_info_end);
1647         *return_val = ret_value;
1648         return (DW_DLV_OK);
1649 
1650     case DW_FORM_data2:
1651         READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned,
1652             info_ptr, sizeof(Dwarf_Shalf),
1653             error,die_info_end);
1654         *return_val = ret_value;
1655         return (DW_DLV_OK);
1656 
1657     case DW_FORM_data4:
1658         READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned,
1659             info_ptr, DWARF_32BIT_SIZE,
1660             error,die_info_end);
1661         *return_val = ret_value;
1662         return (DW_DLV_OK);
1663 
1664     case DW_FORM_data8:
1665         READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned,
1666             info_ptr, DWARF_64BIT_SIZE,
1667             error,die_info_end);
1668         *return_val = ret_value;
1669         return (DW_DLV_OK);
1670 
1671     case DW_FORM_udata: {
1672         Dwarf_Unsigned v = 0;
1673 
1674         DECODE_LEB128_UWORD_CK(info_ptr, v,dbg,error,die_info_end);
1675         *return_val = v;
1676         return DW_DLV_OK;
1677 
1678 
1679     }
1680 
1681     default:
1682         _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
1683         return (DW_DLV_ERROR);
1684     }
1685 }
1686 
1687 
1688 int
dwarf_bytesize(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)1689 dwarf_bytesize(Dwarf_Die die,
1690     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
1691 {
1692     Dwarf_Unsigned luns = 0;
1693     int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_byte_size,
1694         &luns, error);
1695     *ret_size = luns;
1696     return res;
1697 }
1698 
1699 
1700 int
dwarf_bitsize(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)1701 dwarf_bitsize(Dwarf_Die die,
1702     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
1703 {
1704     Dwarf_Unsigned luns = 0;
1705     int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_size,
1706         &luns, error);
1707     *ret_size = luns;
1708     return res;
1709 }
1710 
1711 
1712 int
dwarf_bitoffset(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)1713 dwarf_bitoffset(Dwarf_Die die,
1714     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
1715 {
1716     Dwarf_Unsigned luns = 0;
1717     int res = _dwarf_die_attr_unsigned_constant(die,
1718         DW_AT_bit_offset, &luns, error);
1719     *ret_size = luns;
1720     return res;
1721 }
1722 
1723 
1724 /* Refer section 3.1, page 21 in Dwarf Definition. */
1725 int
dwarf_srclang(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)1726 dwarf_srclang(Dwarf_Die die,
1727     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
1728 {
1729     Dwarf_Unsigned luns = 0;
1730     int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_language,
1731         &luns, error);
1732     *ret_size = luns;
1733     return res;
1734 }
1735 
1736 
1737 /* Refer section 5.4, page 37 in Dwarf Definition. */
1738 int
dwarf_arrayorder(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)1739 dwarf_arrayorder(Dwarf_Die die,
1740     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
1741 {
1742     Dwarf_Unsigned luns = 0;
1743     int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_ordering,
1744         &luns, error);
1745     *ret_size = luns;
1746     return res;
1747 }
1748 
1749 /*  Return DW_DLV_OK if ok
1750     DW_DLV_ERROR if failure.
1751 
1752     If the die and the attr are not related the result is
1753     meaningless.  */
1754 int
dwarf_attr_offset(Dwarf_Die die,Dwarf_Attribute attr,Dwarf_Off * offset,Dwarf_Error * error)1755 dwarf_attr_offset(Dwarf_Die die, Dwarf_Attribute attr,
1756     Dwarf_Off * offset /* return offset thru this ptr */,
1757     Dwarf_Error * error)
1758 {
1759     Dwarf_Off attroff = 0;
1760     Dwarf_Small *dataptr = 0;
1761     Dwarf_Debug dbg = 0;
1762 
1763     CHECK_DIE(die, DW_DLV_ERROR);
1764     dbg = die->di_cu_context->cc_dbg;
1765     dataptr = die->di_is_info? dbg->de_debug_info.dss_data:
1766         dbg->de_debug_types.dss_data;
1767 
1768     attroff = (attr->ar_debug_ptr - dataptr);
1769     *offset = attroff;
1770     return DW_DLV_OK;
1771 }
1772 
1773 int
dwarf_die_abbrev_code(Dwarf_Die die)1774 dwarf_die_abbrev_code(Dwarf_Die die)
1775 {
1776     return die->di_abbrev_code;
1777 }
1778 
1779 /*  Returns a flag through ablhas_child. Non-zero if
1780     the DIE has children, zero if it does not.
1781     It has no Dwarf_Error arg!
1782 */
1783 int
dwarf_die_abbrev_children_flag(Dwarf_Die die,Dwarf_Half * ab_has_child)1784 dwarf_die_abbrev_children_flag(Dwarf_Die die,Dwarf_Half *ab_has_child)
1785 {
1786     if (die->di_abbrev_list) {
1787         *ab_has_child = die->di_abbrev_list->abl_has_child;
1788         return DW_DLV_OK;
1789     }
1790     return DW_DLV_ERROR;
1791 }
1792 
1793 /* Helper function for finding form class. */
1794 static enum Dwarf_Form_Class
dw_get_special_offset(Dwarf_Half attrnum,Dwarf_Half dwversion)1795 dw_get_special_offset(Dwarf_Half attrnum,
1796     Dwarf_Half dwversion)
1797 {
1798     switch (attrnum) {
1799     case DW_AT_stmt_list:
1800         return DW_FORM_CLASS_LINEPTR;
1801     case DW_AT_macro_info: /* DWARF2-DWARF4 */
1802         return DW_FORM_CLASS_MACPTR;
1803     case DW_AT_start_scope:
1804     case DW_AT_ranges: {
1805         if (dwversion <= 4) {
1806             return DW_FORM_CLASS_RANGELISTPTR;
1807         }
1808         return DW_FORM_CLASS_RNGLIST;
1809         }
1810     case DW_AT_rnglists_base: /* DWARF5 */
1811         return DW_FORM_CLASS_RNGLISTSPTR;
1812     case DW_AT_macros:        /* DWARF5 */
1813         return DW_FORM_CLASS_MACROPTR;
1814     case DW_AT_loclists_base: /* DWARF5 */
1815         return DW_FORM_CLASS_LOCLISTSPTR;
1816     case DW_AT_addr_base:     /* DWARF5 */
1817         return DW_FORM_CLASS_ADDRPTR;
1818     case DW_AT_str_offsets_base: /* DWARF5 */
1819         return DW_FORM_CLASS_STROFFSETSPTR;
1820 
1821     case DW_AT_location:
1822     case DW_AT_string_length:
1823     case DW_AT_return_addr:
1824     case DW_AT_data_member_location:
1825     case DW_AT_frame_base:
1826     case DW_AT_segment:
1827     case DW_AT_static_link:
1828     case DW_AT_use_location:
1829     case DW_AT_vtable_elem_location: {
1830         if (dwversion <= 4) {
1831             return DW_FORM_CLASS_LOCLIST;
1832         }
1833         return DW_FORM_CLASS_LOCLISTPTR;
1834         }
1835     case DW_AT_sibling:
1836     case DW_AT_byte_size :
1837     case DW_AT_bit_offset :
1838     case DW_AT_bit_size :
1839     case DW_AT_discr :
1840     case DW_AT_import :
1841     case DW_AT_common_reference:
1842     case DW_AT_containing_type:
1843     case DW_AT_default_value:
1844     case DW_AT_lower_bound:
1845     case DW_AT_bit_stride:
1846     case DW_AT_upper_bound:
1847     case DW_AT_abstract_origin:
1848     case DW_AT_base_types:
1849     case DW_AT_count:
1850     case DW_AT_friend:
1851     case DW_AT_namelist_item:
1852     case DW_AT_priority:
1853     case DW_AT_specification:
1854     case DW_AT_type:
1855     case DW_AT_allocated:
1856     case DW_AT_associated:
1857     case DW_AT_byte_stride:
1858     case DW_AT_extension:
1859     case DW_AT_trampoline:
1860     case DW_AT_small:
1861     case DW_AT_object_pointer:
1862     case DW_AT_signature:
1863         return DW_FORM_CLASS_REFERENCE;
1864     case DW_AT_MIPS_fde: /* SGI/IRIX extension */
1865         return DW_FORM_CLASS_FRAMEPTR;
1866     }
1867     return DW_FORM_CLASS_UNKNOWN;
1868 }
1869 
1870 /* It takes 4 pieces of data (including the FORM)
1871    to accurately determine the form 'class' as documented
1872    in the DWARF spec. This is per DWARF4, but will work
1873    for DWARF2 or 3 as well.  */
1874 enum Dwarf_Form_Class
dwarf_get_form_class(Dwarf_Half dwversion,Dwarf_Half attrnum,Dwarf_Half offset_size,Dwarf_Half form)1875 dwarf_get_form_class(
1876     Dwarf_Half dwversion,
1877     Dwarf_Half attrnum,
1878     Dwarf_Half offset_size,
1879     Dwarf_Half form)
1880 {
1881     switch (form) {
1882     case  DW_FORM_addr:  return DW_FORM_CLASS_ADDRESS;
1883     case  DW_FORM_data2:  return DW_FORM_CLASS_CONSTANT;
1884 
1885     case  DW_FORM_data4:
1886         if (dwversion <= 3 && offset_size == 4) {
1887             enum Dwarf_Form_Class class = dw_get_special_offset(attrnum,
1888                 dwversion);
1889             if (class != DW_FORM_CLASS_UNKNOWN) {
1890                 return class;
1891             }
1892         }
1893         return DW_FORM_CLASS_CONSTANT;
1894     case  DW_FORM_data8:
1895         if (dwversion <= 3 && offset_size == 8) {
1896             enum Dwarf_Form_Class class = dw_get_special_offset(attrnum,
1897                 dwversion);
1898             if (class != DW_FORM_CLASS_UNKNOWN) {
1899                 return class;
1900             }
1901         }
1902         return DW_FORM_CLASS_CONSTANT;
1903     case  DW_FORM_sec_offset:
1904         {
1905             enum Dwarf_Form_Class class = dw_get_special_offset(attrnum,
1906                 dwversion);
1907             if (class != DW_FORM_CLASS_UNKNOWN) {
1908                 return class;
1909             }
1910         }
1911         /* We do not know what this is. */
1912         break;
1913 
1914     case  DW_FORM_string: return DW_FORM_CLASS_STRING;
1915     case  DW_FORM_strp:   return DW_FORM_CLASS_STRING;
1916 
1917     case  DW_FORM_block:  return DW_FORM_CLASS_BLOCK;
1918     case  DW_FORM_block1: return DW_FORM_CLASS_BLOCK;
1919     case  DW_FORM_block2: return DW_FORM_CLASS_BLOCK;
1920     case  DW_FORM_block4: return DW_FORM_CLASS_BLOCK;
1921 
1922     case  DW_FORM_data16:  return DW_FORM_CLASS_CONSTANT;
1923     case  DW_FORM_data1:  return DW_FORM_CLASS_CONSTANT;
1924     case  DW_FORM_sdata:  return DW_FORM_CLASS_CONSTANT;
1925     case  DW_FORM_udata:  return DW_FORM_CLASS_CONSTANT;
1926 
1927     case  DW_FORM_ref_addr:    return DW_FORM_CLASS_REFERENCE;
1928     case  DW_FORM_ref1:        return DW_FORM_CLASS_REFERENCE;
1929     case  DW_FORM_ref2:        return DW_FORM_CLASS_REFERENCE;
1930     case  DW_FORM_ref4:        return DW_FORM_CLASS_REFERENCE;
1931     case  DW_FORM_ref8:        return DW_FORM_CLASS_REFERENCE;
1932     case  DW_FORM_ref_udata:   return DW_FORM_CLASS_REFERENCE;
1933     case  DW_FORM_ref_sig8:    return DW_FORM_CLASS_REFERENCE;
1934 
1935     case  DW_FORM_exprloc:      return DW_FORM_CLASS_EXPRLOC;
1936 
1937     case  DW_FORM_flag:         return DW_FORM_CLASS_FLAG;
1938     case  DW_FORM_flag_present: return DW_FORM_CLASS_FLAG;
1939 
1940     case  DW_FORM_addrx:           return DW_FORM_CLASS_ADDRESS; /* DWARF5 */
1941     case  DW_FORM_GNU_addr_index:  return DW_FORM_CLASS_ADDRESS;
1942     case  DW_FORM_strx:            return DW_FORM_CLASS_STRING;  /* DWARF5 */
1943     case  DW_FORM_GNU_str_index:   return DW_FORM_CLASS_STRING;
1944 
1945     case  DW_FORM_rnglistx:     return DW_FORM_CLASS_RNGLIST;    /* DWARF5 */
1946     case  DW_FORM_loclistx:     return DW_FORM_CLASS_LOCLIST;    /* DWARF5 */
1947 
1948     case  DW_FORM_GNU_ref_alt:  return DW_FORM_CLASS_REFERENCE;
1949     case  DW_FORM_GNU_strp_alt: return DW_FORM_CLASS_STRING;
1950     case  DW_FORM_strp_sup:     return DW_FORM_CLASS_STRING;    /* DWARF5 */
1951     case  DW_FORM_implicit_const: return DW_FORM_CLASS_CONSTANT; /* DWARF5 */
1952 
1953     case  DW_FORM_indirect:
1954     default:
1955         break;
1956     };
1957     return DW_FORM_CLASS_UNKNOWN;
1958 }
1959 
1960 /*  Given a DIE, figure out what the CU's DWARF version is
1961     and the size of an offset
1962     and return it through the *version pointer and return
1963     DW_DLV_OK.
1964 
1965     If we cannot find a CU,
1966         return DW_DLV_ERROR on error.
1967         In case of error no Dwarf_Debug was available,
1968         so setting a Dwarf_Error is somewhat futile.
1969     Never returns DW_DLV_NO_ENTRY.
1970 */
1971 int
dwarf_get_version_of_die(Dwarf_Die die,Dwarf_Half * version,Dwarf_Half * offset_size)1972 dwarf_get_version_of_die(Dwarf_Die die,
1973     Dwarf_Half *version,
1974     Dwarf_Half *offset_size)
1975 {
1976     Dwarf_CU_Context cucontext = 0;
1977     if (!die) {
1978         return DW_DLV_ERROR;
1979     }
1980     cucontext = die->di_cu_context;
1981     if (!cucontext) {
1982         return DW_DLV_ERROR;
1983     }
1984     *version = cucontext->cc_version_stamp;
1985     *offset_size = cucontext->cc_length_size;
1986     return DW_DLV_OK;
1987 }
1988 
1989 Dwarf_Byte_Ptr
_dwarf_calculate_info_section_start_ptr(Dwarf_CU_Context context,Dwarf_Unsigned * section_len)1990 _dwarf_calculate_info_section_start_ptr(Dwarf_CU_Context context,
1991     Dwarf_Unsigned *section_len)
1992 {
1993     Dwarf_Debug dbg = 0;
1994     Dwarf_Small *dataptr = 0;
1995     struct Dwarf_Section_s *sec = 0;
1996 
1997     dbg = context->cc_dbg;
1998     sec = context->cc_is_info? &dbg->de_debug_info: &dbg->de_debug_types;
1999     dataptr = sec->dss_data;
2000     *section_len = sec->dss_size;
2001     return dataptr;
2002 }
2003 
2004 Dwarf_Byte_Ptr
_dwarf_calculate_info_section_end_ptr(Dwarf_CU_Context context)2005 _dwarf_calculate_info_section_end_ptr(Dwarf_CU_Context context)
2006 {
2007     Dwarf_Debug dbg = 0;
2008     Dwarf_Byte_Ptr info_end = 0;
2009     Dwarf_Byte_Ptr info_start = 0;
2010     Dwarf_Off off2 = 0;
2011     Dwarf_Small *dataptr = 0;
2012 
2013     dbg = context->cc_dbg;
2014     dataptr = context->cc_is_info? dbg->de_debug_info.dss_data:
2015         dbg->de_debug_types.dss_data;
2016     off2 = context->cc_debug_offset;
2017     info_start = dataptr + off2;
2018     info_end = info_start + context->cc_length +
2019         context->cc_length_size +
2020         context->cc_extension_size;
2021     return info_end;
2022 }
2023 Dwarf_Byte_Ptr
_dwarf_calculate_abbrev_section_end_ptr(Dwarf_CU_Context context)2024 _dwarf_calculate_abbrev_section_end_ptr(Dwarf_CU_Context context)
2025 {
2026     Dwarf_Debug dbg = 0;
2027     Dwarf_Byte_Ptr abbrev_end = 0;
2028     Dwarf_Byte_Ptr abbrev_start = 0;
2029     struct Dwarf_Section_s *sec = 0;
2030 
2031     dbg = context->cc_dbg;
2032     sec = &dbg->de_debug_abbrev;
2033     abbrev_start = sec->dss_data;
2034     abbrev_end = abbrev_start + sec->dss_size;
2035     return abbrev_end;
2036 }
2037