149d3bc91SRichard Lowe /*
207dc1947SRichard Lowe   Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
3*4d9fdb46SRobert Mustacchi   Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved.
4*4d9fdb46SRobert Mustacchi   Portions Copyright 2012 SN Systems Ltd. All rights reserved.
5*4d9fdb46SRobert Mustacchi 
6*4d9fdb46SRobert Mustacchi   This program is free software; you can redistribute it
7*4d9fdb46SRobert Mustacchi   and/or modify it under the terms of version 2.1 of the
8*4d9fdb46SRobert Mustacchi   GNU Lesser General Public License as published by the Free
9*4d9fdb46SRobert Mustacchi   Software Foundation.
10*4d9fdb46SRobert Mustacchi 
11*4d9fdb46SRobert Mustacchi   This program is distributed in the hope that it would be
12*4d9fdb46SRobert Mustacchi   useful, but WITHOUT ANY WARRANTY; without even the implied
13*4d9fdb46SRobert Mustacchi   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14*4d9fdb46SRobert Mustacchi   PURPOSE.
15*4d9fdb46SRobert Mustacchi 
16*4d9fdb46SRobert Mustacchi   Further, this software is distributed without any warranty
17*4d9fdb46SRobert Mustacchi   that it is free of the rightful claim of any third person
18*4d9fdb46SRobert Mustacchi   regarding infringement or the like.  Any license provided
19*4d9fdb46SRobert Mustacchi   herein, whether implied or otherwise, applies only to this
20*4d9fdb46SRobert Mustacchi   software file.  Patent licenses, if any, provided herein
21*4d9fdb46SRobert Mustacchi   do not apply to combinations of this program with other
22*4d9fdb46SRobert Mustacchi   software, or any other product whatsoever.
23*4d9fdb46SRobert Mustacchi 
24*4d9fdb46SRobert Mustacchi   You should have received a copy of the GNU Lesser General
25*4d9fdb46SRobert Mustacchi   Public License along with this program; if not, write the
26*4d9fdb46SRobert Mustacchi   Free Software Foundation, Inc., 51 Franklin Street - Fifth
27*4d9fdb46SRobert Mustacchi   Floor, Boston MA 02110-1301, USA.
2849d3bc91SRichard Lowe 
29*4d9fdb46SRobert Mustacchi */
3049d3bc91SRichard Lowe 
31*4d9fdb46SRobert Mustacchi #include "config.h"
32*4d9fdb46SRobert Mustacchi #include <stdio.h>
33*4d9fdb46SRobert Mustacchi #include "dwarf_incl.h"
34*4d9fdb46SRobert Mustacchi #include "dwarf_alloc.h"
35*4d9fdb46SRobert Mustacchi #include "dwarf_error.h"
36*4d9fdb46SRobert Mustacchi #include "dwarf_util.h"
37*4d9fdb46SRobert Mustacchi #include "dwarf_die_deliv.h"
38*4d9fdb46SRobert Mustacchi #include "dwarfstring.h"
3949d3bc91SRichard Lowe 
40*4d9fdb46SRobert Mustacchi #define TRUE 1
41*4d9fdb46SRobert Mustacchi static int _dwarf_die_attr_unsigned_constant(Dwarf_Die die,
42*4d9fdb46SRobert Mustacchi     Dwarf_Half attr,
43*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * return_val,
44*4d9fdb46SRobert Mustacchi     Dwarf_Error * error);
4549d3bc91SRichard Lowe 
46*4d9fdb46SRobert Mustacchi static int _dwarf_get_ranges_base_attr_value(Dwarf_Debug dbg,
47*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context context,
48*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * rabase_out,
49*4d9fdb46SRobert Mustacchi     Dwarf_Error    * error);
5007dc1947SRichard Lowe 
51*4d9fdb46SRobert Mustacchi static int _dwarf_get_address_base_attr_value(Dwarf_Debug dbg,
52*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context context,
53*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *abase_out,
54*4d9fdb46SRobert Mustacchi     Dwarf_Error *error);
5507dc1947SRichard Lowe 
dwarf_get_offset_size(Dwarf_Debug dbg,Dwarf_Half * offset_size,Dwarf_Error * error)56*4d9fdb46SRobert Mustacchi int dwarf_get_offset_size(Dwarf_Debug dbg,
57*4d9fdb46SRobert Mustacchi     Dwarf_Half  *    offset_size,
58*4d9fdb46SRobert Mustacchi     Dwarf_Error *    error)
59*4d9fdb46SRobert Mustacchi {
60*4d9fdb46SRobert Mustacchi     if (dbg == 0) {
61*4d9fdb46SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
62*4d9fdb46SRobert Mustacchi         return (DW_DLV_ERROR);
63*4d9fdb46SRobert Mustacchi     }
64*4d9fdb46SRobert Mustacchi     *offset_size = dbg->de_length_size;
65*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
66*4d9fdb46SRobert Mustacchi }
6749d3bc91SRichard Lowe 
68*4d9fdb46SRobert Mustacchi #if 0
69*4d9fdb46SRobert Mustacchi static void
70*4d9fdb46SRobert Mustacchi dump_bytes(char * msg,Dwarf_Small * start, long len)
71*4d9fdb46SRobert Mustacchi {
72*4d9fdb46SRobert Mustacchi     Dwarf_Small *end = start + len;
73*4d9fdb46SRobert Mustacchi     Dwarf_Small *cur = start;
7449d3bc91SRichard Lowe 
75*4d9fdb46SRobert Mustacchi     printf("%s ",msg);
76*4d9fdb46SRobert Mustacchi     for (; cur < end; cur++) {
77*4d9fdb46SRobert Mustacchi         printf("%02x ", *cur);
78*4d9fdb46SRobert Mustacchi     }
79*4d9fdb46SRobert Mustacchi     printf("\n");
80*4d9fdb46SRobert Mustacchi }
81*4d9fdb46SRobert Mustacchi #endif
8249d3bc91SRichard Lowe 
8307dc1947SRichard Lowe /* This is normally reliable.
8407dc1947SRichard Lowe But not always.
8507dc1947SRichard Lowe If different compilation
86*4d9fdb46SRobert Mustacchi units have different address sizes
87*4d9fdb46SRobert Mustacchi this may not give the correct value in all contexts.
88*4d9fdb46SRobert Mustacchi If the Elf offset size != address_size
8907dc1947SRichard Lowe (for example if address_size = 4 but recorded in elf64 object)
90*4d9fdb46SRobert Mustacchi this may not give the correct value in all contexts.
9107dc1947SRichard Lowe */
9249d3bc91SRichard Lowe int
dwarf_get_address_size(Dwarf_Debug dbg,Dwarf_Half * ret_addr_size,Dwarf_Error * error)9349d3bc91SRichard Lowe dwarf_get_address_size(Dwarf_Debug dbg,
9407dc1947SRichard Lowe     Dwarf_Half * ret_addr_size, Dwarf_Error * error)
9549d3bc91SRichard Lowe {
9607dc1947SRichard Lowe     Dwarf_Half address_size = 0;
9749d3bc91SRichard Lowe 
9849d3bc91SRichard Lowe     if (dbg == 0) {
9907dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
10007dc1947SRichard Lowe         return (DW_DLV_ERROR);
10149d3bc91SRichard Lowe     }
10249d3bc91SRichard Lowe     address_size = dbg->de_pointer_size;
10349d3bc91SRichard Lowe     *ret_addr_size = address_size;
10449d3bc91SRichard Lowe     return DW_DLV_OK;
10549d3bc91SRichard Lowe }
10649d3bc91SRichard Lowe 
10707dc1947SRichard Lowe /* This will be correct in all contexts where the
10807dc1947SRichard Lowe    CU context of a DIE is known.
10907dc1947SRichard Lowe */
11007dc1947SRichard Lowe int
dwarf_get_die_address_size(Dwarf_Die die,Dwarf_Half * ret_addr_size,Dwarf_Error * error)11107dc1947SRichard Lowe dwarf_get_die_address_size(Dwarf_Die die,
11207dc1947SRichard Lowe     Dwarf_Half * ret_addr_size, Dwarf_Error * error)
11307dc1947SRichard Lowe {
11407dc1947SRichard Lowe     Dwarf_Half address_size = 0;
11507dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
11607dc1947SRichard Lowe     address_size = die->di_cu_context->cc_address_size;
11707dc1947SRichard Lowe     *ret_addr_size = address_size;
11807dc1947SRichard Lowe     return DW_DLV_OK;
11907dc1947SRichard Lowe }
12007dc1947SRichard Lowe 
12149d3bc91SRichard Lowe int
dwarf_dieoffset(Dwarf_Die die,Dwarf_Off * ret_offset,Dwarf_Error * error)12249d3bc91SRichard Lowe dwarf_dieoffset(Dwarf_Die die,
12307dc1947SRichard Lowe     Dwarf_Off * ret_offset, Dwarf_Error * error)
12449d3bc91SRichard Lowe {
125*4d9fdb46SRobert Mustacchi     Dwarf_Small *dataptr = 0;
126*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
127*4d9fdb46SRobert Mustacchi 
12807dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
129*4d9fdb46SRobert Mustacchi     dbg = die->di_cu_context->cc_dbg;
130*4d9fdb46SRobert Mustacchi     dataptr = die->di_is_info? dbg->de_debug_info.dss_data:
131*4d9fdb46SRobert Mustacchi         dbg->de_debug_types.dss_data;
13249d3bc91SRichard Lowe 
133*4d9fdb46SRobert Mustacchi     *ret_offset = (die->di_debug_ptr - dataptr);
13449d3bc91SRichard Lowe     return DW_DLV_OK;
13549d3bc91SRichard Lowe }
13649d3bc91SRichard Lowe 
13749d3bc91SRichard Lowe 
138*4d9fdb46SRobert Mustacchi /*  This function returns the offset of
13949d3bc91SRichard Lowe     the die relative to the start of its
14049d3bc91SRichard Lowe     compilation-unit rather than .debug_info.
141*4d9fdb46SRobert Mustacchi     Returns DW_DLV_ERROR on error.  */
14249d3bc91SRichard Lowe int
dwarf_die_CU_offset(Dwarf_Die die,Dwarf_Off * cu_off,Dwarf_Error * error)14349d3bc91SRichard Lowe dwarf_die_CU_offset(Dwarf_Die die,
14407dc1947SRichard Lowe     Dwarf_Off * cu_off, Dwarf_Error * error)
14549d3bc91SRichard Lowe {
14607dc1947SRichard Lowe     Dwarf_CU_Context cu_context = 0;
147*4d9fdb46SRobert Mustacchi     Dwarf_Small *dataptr = 0;
148*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
14949d3bc91SRichard Lowe 
15007dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
15107dc1947SRichard Lowe     cu_context = die->di_cu_context;
152*4d9fdb46SRobert Mustacchi     dbg = die->di_cu_context->cc_dbg;
153*4d9fdb46SRobert Mustacchi     dataptr = die->di_is_info? dbg->de_debug_info.dss_data:
154*4d9fdb46SRobert Mustacchi         dbg->de_debug_types.dss_data;
15549d3bc91SRichard Lowe 
156*4d9fdb46SRobert Mustacchi     *cu_off = (die->di_debug_ptr - dataptr - cu_context->cc_debug_offset);
15749d3bc91SRichard Lowe     return DW_DLV_OK;
15849d3bc91SRichard Lowe }
15949d3bc91SRichard Lowe 
160*4d9fdb46SRobert Mustacchi /*  A common function to get both offsets (local and global)
161*4d9fdb46SRobert Mustacchi     It's unusual in that it sets both return offsets
162*4d9fdb46SRobert Mustacchi     to zero on entry.  Normally we only set any
163*4d9fdb46SRobert Mustacchi     output-args (through their pointers) in case
164*4d9fdb46SRobert Mustacchi     of success.  */
165*4d9fdb46SRobert Mustacchi int
dwarf_die_offsets(Dwarf_Die die,Dwarf_Off * off,Dwarf_Off * cu_off,Dwarf_Error * error)166*4d9fdb46SRobert Mustacchi dwarf_die_offsets(Dwarf_Die die,
167*4d9fdb46SRobert Mustacchi     Dwarf_Off *off,
168*4d9fdb46SRobert Mustacchi     Dwarf_Off *cu_off,
169*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
170*4d9fdb46SRobert Mustacchi {
171*4d9fdb46SRobert Mustacchi     int res = 0;
172*4d9fdb46SRobert Mustacchi     Dwarf_Off lcuoff = 0;
173*4d9fdb46SRobert Mustacchi     Dwarf_Off loff = 0;
174*4d9fdb46SRobert Mustacchi 
175*4d9fdb46SRobert Mustacchi     res = dwarf_dieoffset(die,&loff,error);
176*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_OK) {
177*4d9fdb46SRobert Mustacchi         res = dwarf_die_CU_offset(die,&lcuoff,error);
178*4d9fdb46SRobert Mustacchi     }
179*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_OK) {
180*4d9fdb46SRobert Mustacchi         /*  Waiting till both succeed before
181*4d9fdb46SRobert Mustacchi             returning any value at all to retain
182*4d9fdb46SRobert Mustacchi             normal libdwarf call semantics. */
183*4d9fdb46SRobert Mustacchi         *off = loff;
184*4d9fdb46SRobert Mustacchi         *cu_off = lcuoff;
185*4d9fdb46SRobert Mustacchi     } else {
186*4d9fdb46SRobert Mustacchi         *off = 0;
187*4d9fdb46SRobert Mustacchi         *cu_off = 0;
188*4d9fdb46SRobert Mustacchi     }
189*4d9fdb46SRobert Mustacchi     return res;
190*4d9fdb46SRobert Mustacchi }
191*4d9fdb46SRobert Mustacchi 
192*4d9fdb46SRobert Mustacchi /*  This function returns the global offset
19307dc1947SRichard Lowe     (meaning the section offset) and length of
19407dc1947SRichard Lowe     the CU that this die is a part of.
195*4d9fdb46SRobert Mustacchi     Used for correctness checking by dwarfdump.  */
19649d3bc91SRichard Lowe int
dwarf_die_CU_offset_range(Dwarf_Die die,Dwarf_Off * cu_off,Dwarf_Off * cu_length,Dwarf_Error * error)19707dc1947SRichard Lowe dwarf_die_CU_offset_range(Dwarf_Die die,
198*4d9fdb46SRobert Mustacchi     Dwarf_Off * cu_off,
199*4d9fdb46SRobert Mustacchi     Dwarf_Off * cu_length,
200*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
20149d3bc91SRichard Lowe {
20207dc1947SRichard Lowe     Dwarf_CU_Context cu_context = 0;
20349d3bc91SRichard Lowe 
20407dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
20507dc1947SRichard Lowe     cu_context = die->di_cu_context;
20649d3bc91SRichard Lowe 
207*4d9fdb46SRobert Mustacchi     *cu_off = cu_context->cc_debug_offset;
20807dc1947SRichard Lowe     *cu_length = cu_context->cc_length + cu_context->cc_length_size
209*4d9fdb46SRobert Mustacchi         + cu_context->cc_extension_size;
21007dc1947SRichard Lowe     return DW_DLV_OK;
21107dc1947SRichard Lowe }
21207dc1947SRichard Lowe 
21307dc1947SRichard Lowe 
21407dc1947SRichard Lowe 
21507dc1947SRichard Lowe int
dwarf_tag(Dwarf_Die die,Dwarf_Half * tag,Dwarf_Error * error)21607dc1947SRichard Lowe dwarf_tag(Dwarf_Die die, Dwarf_Half * tag, Dwarf_Error * error)
21707dc1947SRichard Lowe {
21807dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
219*4d9fdb46SRobert Mustacchi     *tag = die->di_abbrev_list->abl_tag;
220*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
221*4d9fdb46SRobert Mustacchi }
222*4d9fdb46SRobert Mustacchi 
223*4d9fdb46SRobert Mustacchi /* Returns the children offsets for the given offset */
224*4d9fdb46SRobert Mustacchi int
dwarf_offset_list(Dwarf_Debug dbg,Dwarf_Off offset,Dwarf_Bool is_info,Dwarf_Off ** offbuf,Dwarf_Unsigned * offcnt,Dwarf_Error * error)225*4d9fdb46SRobert Mustacchi dwarf_offset_list(Dwarf_Debug dbg,
226*4d9fdb46SRobert Mustacchi     Dwarf_Off offset, Dwarf_Bool is_info,
227*4d9fdb46SRobert Mustacchi     Dwarf_Off **offbuf, Dwarf_Unsigned *offcnt,
228*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
229*4d9fdb46SRobert Mustacchi {
230*4d9fdb46SRobert Mustacchi     Dwarf_Die die = 0;
231*4d9fdb46SRobert Mustacchi     Dwarf_Die child = 0;
232*4d9fdb46SRobert Mustacchi     Dwarf_Die sib_die = 0;
233*4d9fdb46SRobert Mustacchi     Dwarf_Die cur_die = 0;
234*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned off_count = 0;
235*4d9fdb46SRobert Mustacchi     int res = 0;
236*4d9fdb46SRobert Mustacchi 
237*4d9fdb46SRobert Mustacchi     /* Temporary counter. */
238*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
239*4d9fdb46SRobert Mustacchi 
240*4d9fdb46SRobert Mustacchi     /* Points to contiguous block of Dwarf_Off's to be returned. */
241*4d9fdb46SRobert Mustacchi     Dwarf_Off *ret_offsets = 0;
242*4d9fdb46SRobert Mustacchi 
243*4d9fdb46SRobert Mustacchi     Dwarf_Chain_2 curr_chain = 0;
244*4d9fdb46SRobert Mustacchi     Dwarf_Chain_2 prev_chain = 0;
245*4d9fdb46SRobert Mustacchi     Dwarf_Chain_2 head_chain = 0;
246*4d9fdb46SRobert Mustacchi 
247*4d9fdb46SRobert Mustacchi     *offbuf = NULL;
248*4d9fdb46SRobert Mustacchi     *offcnt = 0;
249*4d9fdb46SRobert Mustacchi 
250*4d9fdb46SRobert Mustacchi     /* Get DIE for offset */
251*4d9fdb46SRobert Mustacchi     res = dwarf_offdie_b(dbg,offset,is_info,&die,error);
252*4d9fdb46SRobert Mustacchi     if (DW_DLV_OK != res) {
253*4d9fdb46SRobert Mustacchi         return res;
254*4d9fdb46SRobert Mustacchi     }
255*4d9fdb46SRobert Mustacchi 
256*4d9fdb46SRobert Mustacchi     /* Get first child for die */
257*4d9fdb46SRobert Mustacchi     res = dwarf_child(die,&child,error);
258*4d9fdb46SRobert Mustacchi     if (DW_DLV_ERROR == res || DW_DLV_NO_ENTRY == res) {
259*4d9fdb46SRobert Mustacchi         return res;
260*4d9fdb46SRobert Mustacchi     }
261*4d9fdb46SRobert Mustacchi 
262*4d9fdb46SRobert Mustacchi     cur_die = child;
263*4d9fdb46SRobert Mustacchi     for (;;) {
264*4d9fdb46SRobert Mustacchi         if (DW_DLV_OK == res) {
265*4d9fdb46SRobert Mustacchi             int dres = 0;
266*4d9fdb46SRobert Mustacchi             Dwarf_Off cur_off = 0;
267*4d9fdb46SRobert Mustacchi 
268*4d9fdb46SRobert Mustacchi             /* Get Global offset for current die */
269*4d9fdb46SRobert Mustacchi             dres = dwarf_dieoffset(cur_die,&cur_off,error);
270*4d9fdb46SRobert Mustacchi             if (dres == DW_DLV_OK) {
271*4d9fdb46SRobert Mustacchi                 /* Normal. use cur_off. */
272*4d9fdb46SRobert Mustacchi             } else if (dres == DW_DLV_ERROR) {
273*4d9fdb46SRobert Mustacchi                 /* Should be impossible unless... */
274*4d9fdb46SRobert Mustacchi                 /* avoid leak. */
275*4d9fdb46SRobert Mustacchi                 /*  Just leave cur_off as zero. */
276*4d9fdb46SRobert Mustacchi                 /* dwarf_dealloc(dbg,*error,DW_DLA_ERROR); */
277*4d9fdb46SRobert Mustacchi                 /* *error = NULL; */
278*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
279*4d9fdb46SRobert Mustacchi             } else { /* DW_DLV_NO_ENTRY */
280*4d9fdb46SRobert Mustacchi                 /* Impossible, dwarf_dieoffset never returns this */
281*4d9fdb46SRobert Mustacchi             }
282*4d9fdb46SRobert Mustacchi             /* Record offset in current entry chain */
283*4d9fdb46SRobert Mustacchi             curr_chain = (Dwarf_Chain_2)_dwarf_get_alloc(
284*4d9fdb46SRobert Mustacchi                 dbg,DW_DLA_CHAIN_2,1);
285*4d9fdb46SRobert Mustacchi             if (curr_chain == NULL) {
286*4d9fdb46SRobert Mustacchi                 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
287*4d9fdb46SRobert Mustacchi                 return (DW_DLV_ERROR);
288*4d9fdb46SRobert Mustacchi             }
289*4d9fdb46SRobert Mustacchi 
290*4d9fdb46SRobert Mustacchi             /* Put current offset on singly_linked list. */
291*4d9fdb46SRobert Mustacchi             curr_chain->ch_item = cur_off;
292*4d9fdb46SRobert Mustacchi             ++off_count;
293*4d9fdb46SRobert Mustacchi 
294*4d9fdb46SRobert Mustacchi             if (head_chain == NULL) {
295*4d9fdb46SRobert Mustacchi                 head_chain = prev_chain = curr_chain;
296*4d9fdb46SRobert Mustacchi             }
297*4d9fdb46SRobert Mustacchi             else {
298*4d9fdb46SRobert Mustacchi                 prev_chain->ch_next = curr_chain;
299*4d9fdb46SRobert Mustacchi                 prev_chain = curr_chain;
300*4d9fdb46SRobert Mustacchi             }
301*4d9fdb46SRobert Mustacchi         }
302*4d9fdb46SRobert Mustacchi 
303*4d9fdb46SRobert Mustacchi         /* Process any siblings entries if any */
304*4d9fdb46SRobert Mustacchi         sib_die = 0;
305*4d9fdb46SRobert Mustacchi         res = dwarf_siblingof_b(dbg,cur_die,is_info,&sib_die,error);
306*4d9fdb46SRobert Mustacchi         if (DW_DLV_ERROR == res) {
307*4d9fdb46SRobert Mustacchi             return res;
308*4d9fdb46SRobert Mustacchi         }
309*4d9fdb46SRobert Mustacchi         if (DW_DLV_NO_ENTRY == res) {
310*4d9fdb46SRobert Mustacchi             /* Done at this level. */
311*4d9fdb46SRobert Mustacchi             break;
312*4d9fdb46SRobert Mustacchi         }
313*4d9fdb46SRobert Mustacchi         /* res == DW_DLV_OK */
314*4d9fdb46SRobert Mustacchi         if (cur_die != die) {
315*4d9fdb46SRobert Mustacchi             dwarf_dealloc(dbg,cur_die,DW_DLA_DIE);
316*4d9fdb46SRobert Mustacchi         }
317*4d9fdb46SRobert Mustacchi         cur_die = sib_die;
318*4d9fdb46SRobert Mustacchi     }
319*4d9fdb46SRobert Mustacchi 
320*4d9fdb46SRobert Mustacchi     /* Points to contiguous block of Dwarf_Off's. */
321*4d9fdb46SRobert Mustacchi     ret_offsets = (Dwarf_Off *) _dwarf_get_alloc(dbg,
322*4d9fdb46SRobert Mustacchi         DW_DLA_ADDR, off_count);
323*4d9fdb46SRobert Mustacchi     if (ret_offsets == NULL) {
324*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
325*4d9fdb46SRobert Mustacchi         return (DW_DLV_ERROR);
326*4d9fdb46SRobert Mustacchi     }
327*4d9fdb46SRobert Mustacchi 
328*4d9fdb46SRobert Mustacchi     /*  Store offsets in contiguous block,
329*4d9fdb46SRobert Mustacchi         and deallocate the chain. */
330*4d9fdb46SRobert Mustacchi     curr_chain = head_chain;
331*4d9fdb46SRobert Mustacchi     for (i = 0; i < off_count; i++) {
332*4d9fdb46SRobert Mustacchi         *(ret_offsets + i) = curr_chain->ch_item;
333*4d9fdb46SRobert Mustacchi         prev_chain = curr_chain;
334*4d9fdb46SRobert Mustacchi         curr_chain = curr_chain->ch_next;
335*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN_2);
336*4d9fdb46SRobert Mustacchi     }
337*4d9fdb46SRobert Mustacchi 
338*4d9fdb46SRobert Mustacchi     *offbuf = ret_offsets;
339*4d9fdb46SRobert Mustacchi     *offcnt = off_count;
340*4d9fdb46SRobert Mustacchi 
34149d3bc91SRichard Lowe     return DW_DLV_OK;
34249d3bc91SRichard Lowe }
34349d3bc91SRichard Lowe 
344*4d9fdb46SRobert Mustacchi static void
empty_local_attrlist(Dwarf_Debug dbg,Dwarf_Attribute attr)345*4d9fdb46SRobert Mustacchi empty_local_attrlist(Dwarf_Debug dbg,
346*4d9fdb46SRobert Mustacchi     Dwarf_Attribute attr)
347*4d9fdb46SRobert Mustacchi {
348*4d9fdb46SRobert Mustacchi     Dwarf_Attribute cur = 0;
349*4d9fdb46SRobert Mustacchi     Dwarf_Attribute next = 0;
350*4d9fdb46SRobert Mustacchi 
351*4d9fdb46SRobert Mustacchi     for (cur = attr; cur ; cur = next) {
352*4d9fdb46SRobert Mustacchi         next = cur->ar_next;
353*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg,cur,DW_DLA_ATTR);
354*4d9fdb46SRobert Mustacchi     }
355*4d9fdb46SRobert Mustacchi }
35649d3bc91SRichard Lowe 
357*4d9fdb46SRobert Mustacchi /*  Now we use *_wrapper here,
358*4d9fdb46SRobert Mustacchi     We cannot leak memory.
359*4d9fdb46SRobert Mustacchi */
36049d3bc91SRichard Lowe int
dwarf_attrlist(Dwarf_Die die,Dwarf_Attribute ** attrbuf,Dwarf_Signed * attrcnt,Dwarf_Error * error)36149d3bc91SRichard Lowe dwarf_attrlist(Dwarf_Die die,
36207dc1947SRichard Lowe     Dwarf_Attribute ** attrbuf,
36307dc1947SRichard Lowe     Dwarf_Signed * attrcnt, Dwarf_Error * error)
36449d3bc91SRichard Lowe {
365*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned attr_count = 0;
366*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned attr = 0;
367*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned attr_form = 0;
368*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
36907dc1947SRichard Lowe     Dwarf_Byte_Ptr abbrev_ptr = 0;
370*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr abbrev_end = 0;
37107dc1947SRichard Lowe     Dwarf_Abbrev_List abbrev_list = 0;
37207dc1947SRichard Lowe     Dwarf_Attribute head_attr = NULL;
37307dc1947SRichard Lowe     Dwarf_Attribute curr_attr = NULL;
37407dc1947SRichard Lowe     Dwarf_Attribute *attr_ptr = 0;
37507dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
37607dc1947SRichard Lowe     Dwarf_Byte_Ptr info_ptr = 0;
377*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr die_info_end = 0;
378*4d9fdb46SRobert Mustacchi     int lres = 0;
379*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context context = 0;
38007dc1947SRichard Lowe 
38107dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
382*4d9fdb46SRobert Mustacchi     context = die->di_cu_context;
383*4d9fdb46SRobert Mustacchi     dbg = context->cc_dbg;
384*4d9fdb46SRobert Mustacchi     die_info_end =
385*4d9fdb46SRobert Mustacchi         _dwarf_calculate_info_section_end_ptr(context);
386*4d9fdb46SRobert Mustacchi 
387*4d9fdb46SRobert Mustacchi     lres = _dwarf_get_abbrev_for_code(context,
388*4d9fdb46SRobert Mustacchi         die->di_abbrev_list->abl_code,
389*4d9fdb46SRobert Mustacchi         &abbrev_list,error);
390*4d9fdb46SRobert Mustacchi     if (lres == DW_DLV_ERROR) {
391*4d9fdb46SRobert Mustacchi         return lres;
392*4d9fdb46SRobert Mustacchi     }
393*4d9fdb46SRobert Mustacchi     if (lres == DW_DLV_NO_ENTRY) {
394*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ABBREV_MISSING);
395*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
39649d3bc91SRichard Lowe     }
39749d3bc91SRichard Lowe 
398*4d9fdb46SRobert Mustacchi     abbrev_ptr = abbrev_list->abl_abbrev_ptr;
399*4d9fdb46SRobert Mustacchi     abbrev_end = _dwarf_calculate_abbrev_section_end_ptr(context);
400*4d9fdb46SRobert Mustacchi 
401*4d9fdb46SRobert Mustacchi 
402*4d9fdb46SRobert Mustacchi     info_ptr = die->di_debug_ptr;
403*4d9fdb46SRobert Mustacchi     {
404*4d9fdb46SRobert Mustacchi         /* SKIP_LEB128_WORD_CK(info_ptr,dbg,error,die_info_end); */
405*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned ignore_this = 0;
406*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned len = 0;
407*4d9fdb46SRobert Mustacchi 
408*4d9fdb46SRobert Mustacchi         lres = _dwarf_decode_u_leb128_chk(info_ptr,
409*4d9fdb46SRobert Mustacchi             &len,&ignore_this,die_info_end);
410*4d9fdb46SRobert Mustacchi         if (lres == DW_DLV_ERROR) {
411*4d9fdb46SRobert Mustacchi             /* Stepped off the end SKIPping the leb  */
412*4d9fdb46SRobert Mustacchi             dwarfstring m;
413*4d9fdb46SRobert Mustacchi 
414*4d9fdb46SRobert Mustacchi             dwarfstring_constructor(&m);
415*4d9fdb46SRobert Mustacchi             dwarfstring_append_printf_u(&m,
416*4d9fdb46SRobert Mustacchi                 "DW_DLE_DIE_BAD: In building an attrlist "
417*4d9fdb46SRobert Mustacchi                 "we run off the end of the DIE while skipping "
418*4d9fdb46SRobert Mustacchi                 " the DIE tag, seeing the leb length as 0x%u ",
419*4d9fdb46SRobert Mustacchi                 len);
420*4d9fdb46SRobert Mustacchi             _dwarf_error_string(dbg, error, DW_DLE_DIE_BAD,
421*4d9fdb46SRobert Mustacchi                 dwarfstring_string(&m));
422*4d9fdb46SRobert Mustacchi             dwarfstring_destructor(&m);
423*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
424*4d9fdb46SRobert Mustacchi         }
425*4d9fdb46SRobert Mustacchi         info_ptr += len;
426*4d9fdb46SRobert Mustacchi     }
42707dc1947SRichard Lowe 
42807dc1947SRichard Lowe     do {
429*4d9fdb46SRobert Mustacchi         Dwarf_Signed implicit_const = 0;
430*4d9fdb46SRobert Mustacchi         Dwarf_Attribute new_attr = 0;
431*4d9fdb46SRobert Mustacchi         int res = 0;
432*4d9fdb46SRobert Mustacchi 
433*4d9fdb46SRobert Mustacchi         /*  The DECODE have to be wrapped in functions to
434*4d9fdb46SRobert Mustacchi             catch errors before return. */
435*4d9fdb46SRobert Mustacchi         /*DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2,
436*4d9fdb46SRobert Mustacchi             dbg,error,abbrev_end); */
437*4d9fdb46SRobert Mustacchi         res = _dwarf_leb128_uword_wrapper(dbg,
438*4d9fdb46SRobert Mustacchi             &abbrev_ptr,abbrev_end,&attr,error);
439*4d9fdb46SRobert Mustacchi         if (res == DW_DLV_ERROR) {
440*4d9fdb46SRobert Mustacchi             empty_local_attrlist(dbg,head_attr);
441*4d9fdb46SRobert Mustacchi             return res;
442*4d9fdb46SRobert Mustacchi         }
443*4d9fdb46SRobert Mustacchi         if (attr > DW_AT_hi_user) {
444*4d9fdb46SRobert Mustacchi             empty_local_attrlist(dbg,head_attr);
445*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error,DW_DLE_ATTR_CORRUPT);
446*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
447*4d9fdb46SRobert Mustacchi         }
448*4d9fdb46SRobert Mustacchi         /*DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2,
449*4d9fdb46SRobert Mustacchi             dbg,error,abbrev_end); */
450*4d9fdb46SRobert Mustacchi         res = _dwarf_leb128_uword_wrapper(dbg,
451*4d9fdb46SRobert Mustacchi             &abbrev_ptr,abbrev_end,&attr_form,error);
452*4d9fdb46SRobert Mustacchi         if (res == DW_DLV_ERROR) {
453*4d9fdb46SRobert Mustacchi             empty_local_attrlist(dbg,head_attr);
454*4d9fdb46SRobert Mustacchi             return res;
455*4d9fdb46SRobert Mustacchi         }
456*4d9fdb46SRobert Mustacchi         if (!_dwarf_valid_form_we_know(attr_form,attr)) {
457*4d9fdb46SRobert Mustacchi             empty_local_attrlist(dbg,head_attr);
458*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM);
459*4d9fdb46SRobert Mustacchi             return (DW_DLV_ERROR);
460*4d9fdb46SRobert Mustacchi         }
461*4d9fdb46SRobert Mustacchi         if (attr_form == DW_FORM_implicit_const) {
462*4d9fdb46SRobert Mustacchi             /* The value is here, not in a DIE. */
463*4d9fdb46SRobert Mustacchi             res = _dwarf_leb128_sword_wrapper(dbg,&abbrev_ptr,
464*4d9fdb46SRobert Mustacchi                 abbrev_end, &implicit_const, error);
465*4d9fdb46SRobert Mustacchi             if (res == DW_DLV_ERROR) {
466*4d9fdb46SRobert Mustacchi                 empty_local_attrlist(dbg,head_attr);
467*4d9fdb46SRobert Mustacchi                 return res;
468*4d9fdb46SRobert Mustacchi             }
469*4d9fdb46SRobert Mustacchi             /*DECODE_LEB128_SWORD_CK(abbrev_ptr, implicit_const,
470*4d9fdb46SRobert Mustacchi                 dbg,error,abbrev_end); */
471*4d9fdb46SRobert Mustacchi         }
47207dc1947SRichard Lowe 
473*4d9fdb46SRobert Mustacchi         if (!_dwarf_valid_form_we_know(attr_form,attr)) {
474*4d9fdb46SRobert Mustacchi             empty_local_attrlist(dbg,head_attr);
475*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM);
476*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
477*4d9fdb46SRobert Mustacchi         }
47807dc1947SRichard Lowe         if (attr != 0) {
479*4d9fdb46SRobert Mustacchi             new_attr = (Dwarf_Attribute)
480*4d9fdb46SRobert Mustacchi                 _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
48107dc1947SRichard Lowe             if (new_attr == NULL) {
482*4d9fdb46SRobert Mustacchi                 empty_local_attrlist(dbg,head_attr);
48307dc1947SRichard Lowe                 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
484*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
48507dc1947SRichard Lowe             }
48607dc1947SRichard Lowe             new_attr->ar_attribute = attr;
48707dc1947SRichard Lowe             new_attr->ar_attribute_form_direct = attr_form;
48807dc1947SRichard Lowe             new_attr->ar_attribute_form = attr_form;
48907dc1947SRichard Lowe             if (attr_form == DW_FORM_indirect) {
490*4d9fdb46SRobert Mustacchi                 Dwarf_Unsigned utmp6 = 0;
491*4d9fdb46SRobert Mustacchi 
492*4d9fdb46SRobert Mustacchi                 if (_dwarf_reference_outside_section(die,
493*4d9fdb46SRobert Mustacchi                     (Dwarf_Small*) info_ptr,
494*4d9fdb46SRobert Mustacchi                     ((Dwarf_Small*) info_ptr )+1)) {
495*4d9fdb46SRobert Mustacchi                     dwarf_dealloc(dbg,new_attr,DW_DLA_ATTR);
496*4d9fdb46SRobert Mustacchi                     empty_local_attrlist(dbg,head_attr);
497*4d9fdb46SRobert Mustacchi                     _dwarf_error_string(dbg, error,
498*4d9fdb46SRobert Mustacchi                         DW_DLE_ATTR_OUTSIDE_SECTION,
499*4d9fdb46SRobert Mustacchi                         "DW_DLE_ATTR_OUTSIDE_SECTION: "
500*4d9fdb46SRobert Mustacchi                         " Reading Attriutes: "
501*4d9fdb46SRobert Mustacchi                         "For DW_FORM_indirect there is"
502*4d9fdb46SRobert Mustacchi                         " no room for the form. Corrupt Dwarf");
503*4d9fdb46SRobert Mustacchi                     return DW_DLV_ERROR;
504*4d9fdb46SRobert Mustacchi                 }
505*4d9fdb46SRobert Mustacchi 
506*4d9fdb46SRobert Mustacchi                 /*  DECODE_LEB128_UWORD does info_ptr update
507*4d9fdb46SRobert Mustacchi                     DECODE_LEB128_UWORD_CK(info_ptr, utmp6,
508*4d9fdb46SRobert Mustacchi                         dbg,error,die_info_end);
509*4d9fdb46SRobert Mustacchi                 */
510*4d9fdb46SRobert Mustacchi                 res = _dwarf_leb128_uword_wrapper(dbg,
511*4d9fdb46SRobert Mustacchi                     &info_ptr,die_info_end,&utmp6,error);
51249d3bc91SRichard Lowe                 attr_form = (Dwarf_Half) utmp6;
51307dc1947SRichard Lowe                 new_attr->ar_attribute_form = attr_form;
51407dc1947SRichard Lowe             }
515*4d9fdb46SRobert Mustacchi             /*  Here the final address must be *inside* the
516*4d9fdb46SRobert Mustacchi                 section, as we will read from there, and read
517*4d9fdb46SRobert Mustacchi                 at least one byte, we think.
518*4d9fdb46SRobert Mustacchi                 We do not want info_ptr to point past end so
519*4d9fdb46SRobert Mustacchi                 we add 1 to the end-pointer.  */
520*4d9fdb46SRobert Mustacchi             if ( attr_form != DW_FORM_implicit_const &&
521*4d9fdb46SRobert Mustacchi                 _dwarf_reference_outside_section(die,
522*4d9fdb46SRobert Mustacchi                 (Dwarf_Small*) info_ptr,
523*4d9fdb46SRobert Mustacchi                 ((Dwarf_Small*) info_ptr )+1)) {
524*4d9fdb46SRobert Mustacchi                 dwarf_dealloc(dbg,new_attr,DW_DLA_ATTR);
525*4d9fdb46SRobert Mustacchi                 empty_local_attrlist(dbg,head_attr);
526*4d9fdb46SRobert Mustacchi                 _dwarf_error_string(dbg, error,
527*4d9fdb46SRobert Mustacchi                     DW_DLE_ATTR_OUTSIDE_SECTION,
528*4d9fdb46SRobert Mustacchi                     "DW_DLE_ATTR_OUTSIDE_SECTION: "
529*4d9fdb46SRobert Mustacchi                     " Reading Attriutes: "
530*4d9fdb46SRobert Mustacchi                     "We have run off the end of the section. "
531*4d9fdb46SRobert Mustacchi                     "Corrupt Dwarf");
532*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
533*4d9fdb46SRobert Mustacchi             }
53407dc1947SRichard Lowe             new_attr->ar_cu_context = die->di_cu_context;
535*4d9fdb46SRobert Mustacchi             new_attr->ar_debug_ptr = info_ptr;
536*4d9fdb46SRobert Mustacchi             new_attr->ar_die = die;
537*4d9fdb46SRobert Mustacchi             new_attr->ar_dbg = dbg;
538*4d9fdb46SRobert Mustacchi             if (attr_form == DW_FORM_implicit_const) {
539*4d9fdb46SRobert Mustacchi                 /*  The value is here, not in a DIE.
540*4d9fdb46SRobert Mustacchi                     Do not increment info_ptr */
541*4d9fdb46SRobert Mustacchi                 new_attr->ar_implicit_const = implicit_const;
542*4d9fdb46SRobert Mustacchi             } else {
543*4d9fdb46SRobert Mustacchi                 Dwarf_Unsigned sov = 0;
544*4d9fdb46SRobert Mustacchi                 int vres = 0;
545*4d9fdb46SRobert Mustacchi 
546*4d9fdb46SRobert Mustacchi                 vres = _dwarf_get_size_of_val(dbg,
547*4d9fdb46SRobert Mustacchi                     attr_form,
548*4d9fdb46SRobert Mustacchi                     die->di_cu_context->cc_version_stamp,
54907dc1947SRichard Lowe                     die->di_cu_context->cc_address_size,
55007dc1947SRichard Lowe                     info_ptr,
551*4d9fdb46SRobert Mustacchi                     die->di_cu_context->cc_length_size,
552*4d9fdb46SRobert Mustacchi                     &sov,
553*4d9fdb46SRobert Mustacchi                     die_info_end,
554*4d9fdb46SRobert Mustacchi                     error);
555*4d9fdb46SRobert Mustacchi                 if(vres!= DW_DLV_OK) {
556*4d9fdb46SRobert Mustacchi                     dwarf_dealloc(dbg,new_attr,DW_DLA_ATTR);
557*4d9fdb46SRobert Mustacchi                     empty_local_attrlist(dbg,head_attr);
558*4d9fdb46SRobert Mustacchi                     return vres;
559*4d9fdb46SRobert Mustacchi                 }
56007dc1947SRichard Lowe                 info_ptr += sov;
56107dc1947SRichard Lowe             }
56207dc1947SRichard Lowe             if (head_attr == NULL)
56307dc1947SRichard Lowe                 head_attr = curr_attr = new_attr;
56407dc1947SRichard Lowe             else {
56507dc1947SRichard Lowe                 curr_attr->ar_next = new_attr;
56607dc1947SRichard Lowe                 curr_attr = new_attr;
56707dc1947SRichard Lowe             }
56807dc1947SRichard Lowe             attr_count++;
56907dc1947SRichard Lowe         }
570*4d9fdb46SRobert Mustacchi     } while (attr || attr_form);
571*4d9fdb46SRobert Mustacchi     if (!attr_count) {
57207dc1947SRichard Lowe         *attrbuf = NULL;
57307dc1947SRichard Lowe         *attrcnt = 0;
57407dc1947SRichard Lowe         return (DW_DLV_NO_ENTRY);
57549d3bc91SRichard Lowe     }
57649d3bc91SRichard Lowe     attr_ptr = (Dwarf_Attribute *)
57707dc1947SRichard Lowe         _dwarf_get_alloc(dbg, DW_DLA_LIST, attr_count);
57849d3bc91SRichard Lowe     if (attr_ptr == NULL) {
579*4d9fdb46SRobert Mustacchi         empty_local_attrlist(dbg,head_attr);
58007dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
58107dc1947SRichard Lowe         return (DW_DLV_ERROR);
58249d3bc91SRichard Lowe     }
58349d3bc91SRichard Lowe     curr_attr = head_attr;
58449d3bc91SRichard Lowe     for (i = 0; i < attr_count; i++) {
58507dc1947SRichard Lowe         *(attr_ptr + i) = curr_attr;
58607dc1947SRichard Lowe         curr_attr = curr_attr->ar_next;
58749d3bc91SRichard Lowe     }
58849d3bc91SRichard Lowe     *attrbuf = attr_ptr;
58949d3bc91SRichard Lowe     *attrcnt = attr_count;
59049d3bc91SRichard Lowe     return (DW_DLV_OK);
59149d3bc91SRichard Lowe }
59249d3bc91SRichard Lowe 
59349d3bc91SRichard Lowe 
59449d3bc91SRichard Lowe /*
59549d3bc91SRichard Lowe     This function takes a die, and an attr, and returns
59649d3bc91SRichard Lowe     a pointer to the start of the value of that attr in
59749d3bc91SRichard Lowe     the given die in the .debug_info section.  The form
59849d3bc91SRichard Lowe     is returned in *attr_form.
59949d3bc91SRichard Lowe 
600*4d9fdb46SRobert Mustacchi     If the attr_form is DW_FORM_implicit_const
601*4d9fdb46SRobert Mustacchi     (known signed, so most callers)
602*4d9fdb46SRobert Mustacchi     that is fine, but in that case we do not
603*4d9fdb46SRobert Mustacchi     need to actually set the *ptr_to_value.
604*4d9fdb46SRobert Mustacchi 
60549d3bc91SRichard Lowe     Returns NULL on error, or if attr is not found.
606*4d9fdb46SRobert Mustacchi     However, *attr_form is 0 on error, and positive
60749d3bc91SRichard Lowe     otherwise.
60849d3bc91SRichard Lowe */
609*4d9fdb46SRobert Mustacchi 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)61049d3bc91SRichard Lowe _dwarf_get_value_ptr(Dwarf_Die die,
611*4d9fdb46SRobert Mustacchi     Dwarf_Half attr,
612*4d9fdb46SRobert Mustacchi     Dwarf_Half * attr_form,
613*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr * ptr_to_value,
614*4d9fdb46SRobert Mustacchi     Dwarf_Signed *implicit_const_out,
615*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
61649d3bc91SRichard Lowe {
61707dc1947SRichard Lowe     Dwarf_Byte_Ptr abbrev_ptr = 0;
618*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr abbrev_end = 0;
61949d3bc91SRichard Lowe     Dwarf_Abbrev_List abbrev_list;
62007dc1947SRichard Lowe     Dwarf_Half curr_attr = 0;
62107dc1947SRichard Lowe     Dwarf_Half curr_attr_form = 0;
62207dc1947SRichard Lowe     Dwarf_Byte_Ptr info_ptr = 0;
623*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context context = die->di_cu_context;
624*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr die_info_end = 0;
625*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
626*4d9fdb46SRobert Mustacchi     int lres = 0;
62749d3bc91SRichard Lowe 
628*4d9fdb46SRobert Mustacchi     if (!context) {
629*4d9fdb46SRobert Mustacchi         _dwarf_error(NULL,error,DW_DLE_DIE_NO_CU_CONTEXT);
630*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
631*4d9fdb46SRobert Mustacchi     }
632*4d9fdb46SRobert Mustacchi     dbg = context->cc_dbg;
633*4d9fdb46SRobert Mustacchi     die_info_end =
634*4d9fdb46SRobert Mustacchi         _dwarf_calculate_info_section_end_ptr(context);
635*4d9fdb46SRobert Mustacchi 
636*4d9fdb46SRobert Mustacchi     lres = _dwarf_get_abbrev_for_code(context,
637*4d9fdb46SRobert Mustacchi         die->di_abbrev_list->abl_code,
638*4d9fdb46SRobert Mustacchi         &abbrev_list,error);
639*4d9fdb46SRobert Mustacchi     if (lres == DW_DLV_ERROR) {
640*4d9fdb46SRobert Mustacchi         return lres;
641*4d9fdb46SRobert Mustacchi     }
642*4d9fdb46SRobert Mustacchi     if (lres == DW_DLV_NO_ENTRY) {
643*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg,error,DW_DLE_CU_DIE_NO_ABBREV_LIST);
644*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
64549d3bc91SRichard Lowe     }
64649d3bc91SRichard Lowe 
647*4d9fdb46SRobert Mustacchi     abbrev_ptr = abbrev_list->abl_abbrev_ptr;
648*4d9fdb46SRobert Mustacchi     abbrev_end = _dwarf_calculate_abbrev_section_end_ptr(context);
649*4d9fdb46SRobert Mustacchi 
650*4d9fdb46SRobert Mustacchi     info_ptr = die->di_debug_ptr;
651*4d9fdb46SRobert Mustacchi     /* This ensures and checks die_info_end >= info_ptr */
652*4d9fdb46SRobert Mustacchi     {
653*4d9fdb46SRobert Mustacchi         /* SKIP_LEB128_WORD_CK(info_ptr,dbg,error,die_info_end); */
654*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned ignore_this = 0;
655*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned len = 0;
656*4d9fdb46SRobert Mustacchi 
657*4d9fdb46SRobert Mustacchi         lres = _dwarf_decode_u_leb128_chk(info_ptr,
658*4d9fdb46SRobert Mustacchi             &len,&ignore_this,die_info_end);
659*4d9fdb46SRobert Mustacchi         if (lres == DW_DLV_ERROR) {
660*4d9fdb46SRobert Mustacchi             /* Stepped off the end SKIPping the leb  */
661*4d9fdb46SRobert Mustacchi             dwarfstring m;
662*4d9fdb46SRobert Mustacchi             dwarfstring_constructor(&m);
663*4d9fdb46SRobert Mustacchi             dwarfstring_append_printf_u(&m,
664*4d9fdb46SRobert Mustacchi                 "DW_DLE_DIE_BAD: In building an attrlist "
665*4d9fdb46SRobert Mustacchi                 "we run off the end of the DIE while skipping "
666*4d9fdb46SRobert Mustacchi                 " the DIE tag, seeing the leb length as 0x%u ",
667*4d9fdb46SRobert Mustacchi                 len);
668*4d9fdb46SRobert Mustacchi             _dwarf_error_string(dbg, error, DW_DLE_DIE_BAD,
669*4d9fdb46SRobert Mustacchi                 dwarfstring_string(&m));
670*4d9fdb46SRobert Mustacchi             dwarfstring_destructor(&m);
671*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
672*4d9fdb46SRobert Mustacchi         }
673*4d9fdb46SRobert Mustacchi         info_ptr += len;
674*4d9fdb46SRobert Mustacchi     }
67549d3bc91SRichard Lowe     do {
676*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned formtmp3 = 0;
677*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned atmp3 = 0;
678*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned value_size=0;
679*4d9fdb46SRobert Mustacchi         Dwarf_Signed implicit_const = 0;
680*4d9fdb46SRobert Mustacchi         int res = 0;
681*4d9fdb46SRobert Mustacchi 
682*4d9fdb46SRobert Mustacchi         DECODE_LEB128_UWORD_CK(abbrev_ptr, atmp3,dbg,error,abbrev_end);
683*4d9fdb46SRobert Mustacchi         if (atmp3 > DW_AT_hi_user) {
684*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error,DW_DLE_ATTR_CORRUPT);
685*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
686*4d9fdb46SRobert Mustacchi         }
687*4d9fdb46SRobert Mustacchi         curr_attr = (Dwarf_Half) atmp3;
688*4d9fdb46SRobert Mustacchi 
689*4d9fdb46SRobert Mustacchi         DECODE_LEB128_UWORD_CK(abbrev_ptr,formtmp3,
690*4d9fdb46SRobert Mustacchi             dbg,error,abbrev_end);
691*4d9fdb46SRobert Mustacchi         if (!_dwarf_valid_form_we_know(formtmp3,curr_attr)) {
692*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM);
693*4d9fdb46SRobert Mustacchi             return (DW_DLV_ERROR);
694*4d9fdb46SRobert Mustacchi         }
69507dc1947SRichard Lowe 
696*4d9fdb46SRobert Mustacchi         curr_attr_form = (Dwarf_Half) formtmp3;
69707dc1947SRichard Lowe         if (curr_attr_form == DW_FORM_indirect) {
69807dc1947SRichard Lowe             Dwarf_Unsigned utmp6;
69907dc1947SRichard Lowe 
70007dc1947SRichard Lowe             /* DECODE_LEB128_UWORD updates info_ptr */
701*4d9fdb46SRobert Mustacchi             DECODE_LEB128_UWORD_CK(info_ptr, utmp6,dbg,error,die_info_end);
70207dc1947SRichard Lowe             curr_attr_form = (Dwarf_Half) utmp6;
70349d3bc91SRichard Lowe         }
704*4d9fdb46SRobert Mustacchi         if (curr_attr_form == DW_FORM_implicit_const) {
705*4d9fdb46SRobert Mustacchi             /* The value is here, not in a DIE. */
706*4d9fdb46SRobert Mustacchi             DECODE_LEB128_SWORD_CK(abbrev_ptr, implicit_const,
707*4d9fdb46SRobert Mustacchi                 dbg,error,abbrev_end);
708*4d9fdb46SRobert Mustacchi         }
70907dc1947SRichard Lowe         if (curr_attr == attr) {
71007dc1947SRichard Lowe             *attr_form = curr_attr_form;
711*4d9fdb46SRobert Mustacchi             if(implicit_const_out) {
712*4d9fdb46SRobert Mustacchi                 *implicit_const_out = implicit_const;
713*4d9fdb46SRobert Mustacchi             }
714*4d9fdb46SRobert Mustacchi             *ptr_to_value = info_ptr;
715*4d9fdb46SRobert Mustacchi             return DW_DLV_OK;
71607dc1947SRichard Lowe         }
717*4d9fdb46SRobert Mustacchi         res = _dwarf_get_size_of_val(dbg,
718*4d9fdb46SRobert Mustacchi             curr_attr_form,
719*4d9fdb46SRobert Mustacchi             die->di_cu_context->cc_version_stamp,
720*4d9fdb46SRobert Mustacchi             die->di_cu_context->cc_address_size,
721*4d9fdb46SRobert Mustacchi             info_ptr,
722*4d9fdb46SRobert Mustacchi             die->di_cu_context->cc_length_size,
723*4d9fdb46SRobert Mustacchi             &value_size,
724*4d9fdb46SRobert Mustacchi             die_info_end,
725*4d9fdb46SRobert Mustacchi             error);
726*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
727*4d9fdb46SRobert Mustacchi             return res;
728*4d9fdb46SRobert Mustacchi         }
729*4d9fdb46SRobert Mustacchi         {
730*4d9fdb46SRobert Mustacchi             /* ptrdiff_t is signed type, so use DW signed type */
731*4d9fdb46SRobert Mustacchi             Dwarf_Signed len = die_info_end - info_ptr;
732*4d9fdb46SRobert Mustacchi             if (len < 0 || (value_size > ((Dwarf_Unsigned)len))) {
733*4d9fdb46SRobert Mustacchi                 /*  Something badly wrong. We point past end
734*4d9fdb46SRobert Mustacchi                     of debug_info or debug_types or a
735*4d9fdb46SRobert Mustacchi                     section is unreasonably sized or we are
736*4d9fdb46SRobert Mustacchi                     pointing to two different sections? */
737*4d9fdb46SRobert Mustacchi                 _dwarf_error(dbg,error,DW_DLE_DIE_ABBREV_BAD);
738*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
739*4d9fdb46SRobert Mustacchi             }
740*4d9fdb46SRobert Mustacchi         }
741*4d9fdb46SRobert Mustacchi         info_ptr+= value_size;
74249d3bc91SRichard Lowe     } while (curr_attr != 0 || curr_attr_form != 0);
743*4d9fdb46SRobert Mustacchi     return DW_DLV_NO_ENTRY;
74449d3bc91SRichard Lowe }
74549d3bc91SRichard Lowe 
74649d3bc91SRichard Lowe int
dwarf_die_text(Dwarf_Die die,Dwarf_Half attrnum,char ** ret_name,Dwarf_Error * error)747*4d9fdb46SRobert Mustacchi dwarf_die_text(Dwarf_Die die,
748*4d9fdb46SRobert Mustacchi     Dwarf_Half attrnum,
749*4d9fdb46SRobert Mustacchi     char **ret_name,
750*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
75149d3bc91SRichard Lowe {
75207dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
75307dc1947SRichard Lowe     int res = DW_DLV_ERROR;
754*4d9fdb46SRobert Mustacchi     Dwarf_Attribute attr = 0;
755*4d9fdb46SRobert Mustacchi     Dwarf_Error lerr = 0;
75649d3bc91SRichard Lowe 
75707dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
75849d3bc91SRichard Lowe 
759*4d9fdb46SRobert Mustacchi     res = dwarf_attr(die,attrnum,&attr,&lerr);
76049d3bc91SRichard Lowe     dbg = die->di_cu_context->cc_dbg;
761*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_ERROR) {
762*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
76349d3bc91SRichard Lowe     }
764*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_NO_ENTRY) {
76549d3bc91SRichard Lowe         return res;
76649d3bc91SRichard Lowe     }
767*4d9fdb46SRobert Mustacchi     res = dwarf_formstring(attr,ret_name,error);
768*4d9fdb46SRobert Mustacchi     dwarf_dealloc(dbg,attr, DW_DLA_ATTR);
769*4d9fdb46SRobert Mustacchi     attr = 0;
770*4d9fdb46SRobert Mustacchi     return res;
77149d3bc91SRichard Lowe }
77249d3bc91SRichard Lowe 
773*4d9fdb46SRobert Mustacchi int
dwarf_diename(Dwarf_Die die,char ** ret_name,Dwarf_Error * error)774*4d9fdb46SRobert Mustacchi dwarf_diename(Dwarf_Die die,
775*4d9fdb46SRobert Mustacchi     char **ret_name,
776*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
777*4d9fdb46SRobert Mustacchi {
778*4d9fdb46SRobert Mustacchi     return dwarf_die_text(die,DW_AT_name,ret_name,error);
779*4d9fdb46SRobert Mustacchi }
78049d3bc91SRichard Lowe 
78149d3bc91SRichard Lowe int
dwarf_hasattr(Dwarf_Die die,Dwarf_Half attr,Dwarf_Bool * return_bool,Dwarf_Error * error)78249d3bc91SRichard Lowe dwarf_hasattr(Dwarf_Die die,
78307dc1947SRichard Lowe     Dwarf_Half attr,
78407dc1947SRichard Lowe     Dwarf_Bool * return_bool, Dwarf_Error * error)
78549d3bc91SRichard Lowe {
78607dc1947SRichard Lowe     Dwarf_Half attr_form = 0;
787*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr info_ptr = 0;
788*4d9fdb46SRobert Mustacchi     int res = 0;
789*4d9fdb46SRobert Mustacchi     Dwarf_Signed implicit_const;
79049d3bc91SRichard Lowe 
79107dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
79249d3bc91SRichard Lowe 
793*4d9fdb46SRobert Mustacchi     res = _dwarf_get_value_ptr(die, attr, &attr_form,&info_ptr,
794*4d9fdb46SRobert Mustacchi         &implicit_const,error);
795*4d9fdb46SRobert Mustacchi     if(res == DW_DLV_ERROR) {
796*4d9fdb46SRobert Mustacchi         return res;
797*4d9fdb46SRobert Mustacchi     }
798*4d9fdb46SRobert Mustacchi     if(res == DW_DLV_NO_ENTRY) {
79907dc1947SRichard Lowe         *return_bool = false;
80007dc1947SRichard Lowe         return DW_DLV_OK;
80149d3bc91SRichard Lowe     }
80249d3bc91SRichard Lowe     *return_bool = (true);
80349d3bc91SRichard Lowe     return DW_DLV_OK;
80449d3bc91SRichard Lowe }
80549d3bc91SRichard Lowe 
80649d3bc91SRichard Lowe int
dwarf_attr(Dwarf_Die die,Dwarf_Half attr,Dwarf_Attribute * ret_attr,Dwarf_Error * error)80749d3bc91SRichard Lowe dwarf_attr(Dwarf_Die die,
80807dc1947SRichard Lowe     Dwarf_Half attr,
80907dc1947SRichard Lowe     Dwarf_Attribute * ret_attr, Dwarf_Error * error)
81049d3bc91SRichard Lowe {
81107dc1947SRichard Lowe     Dwarf_Half attr_form = 0;
81207dc1947SRichard Lowe     Dwarf_Attribute attrib = 0;
81307dc1947SRichard Lowe     Dwarf_Byte_Ptr info_ptr = 0;
81407dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
815*4d9fdb46SRobert Mustacchi     int res = 0;
816*4d9fdb46SRobert Mustacchi     Dwarf_Signed implicit_const = 0;
81749d3bc91SRichard Lowe 
81807dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
81907dc1947SRichard Lowe     dbg = die->di_cu_context->cc_dbg;
82049d3bc91SRichard Lowe 
821*4d9fdb46SRobert Mustacchi     res = _dwarf_get_value_ptr(die, attr, &attr_form,&info_ptr,
822*4d9fdb46SRobert Mustacchi         &implicit_const,error);
823*4d9fdb46SRobert Mustacchi     if(res == DW_DLV_ERROR) {
824*4d9fdb46SRobert Mustacchi         return res;
825*4d9fdb46SRobert Mustacchi     }
826*4d9fdb46SRobert Mustacchi     if(res == DW_DLV_NO_ENTRY) {
827*4d9fdb46SRobert Mustacchi         return res;
82849d3bc91SRichard Lowe     }
82949d3bc91SRichard Lowe 
83049d3bc91SRichard Lowe     attrib = (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
831*4d9fdb46SRobert Mustacchi     if (!attrib) {
832*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL,
833*4d9fdb46SRobert Mustacchi             "DW_DLE_ALLOC_FAIL allocating a single Dwarf_Attribute"
834*4d9fdb46SRobert Mustacchi             " in function dwarf_attr().");
835*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
83649d3bc91SRichard Lowe     }
83749d3bc91SRichard Lowe 
83849d3bc91SRichard Lowe     attrib->ar_attribute = attr;
83949d3bc91SRichard Lowe     attrib->ar_attribute_form = attr_form;
84049d3bc91SRichard Lowe     attrib->ar_attribute_form_direct = attr_form;
84149d3bc91SRichard Lowe     attrib->ar_cu_context = die->di_cu_context;
842*4d9fdb46SRobert Mustacchi 
843*4d9fdb46SRobert Mustacchi     /*  Only nonzero if DW_FORM_implicit_const */
844*4d9fdb46SRobert Mustacchi     attrib->ar_implicit_const = implicit_const;
845*4d9fdb46SRobert Mustacchi     /*  Only nonnull if not DW_FORM_implicit_const */
846*4d9fdb46SRobert Mustacchi     attrib->ar_debug_ptr = info_ptr;
847*4d9fdb46SRobert Mustacchi     attrib->ar_die = die;
848*4d9fdb46SRobert Mustacchi     attrib->ar_dbg = dbg;
84949d3bc91SRichard Lowe     *ret_attr = (attrib);
85049d3bc91SRichard Lowe     return DW_DLV_OK;
85149d3bc91SRichard Lowe }
85249d3bc91SRichard Lowe 
853*4d9fdb46SRobert Mustacchi /*  A DWP (.dwp) package object never contains .debug_addr,
854*4d9fdb46SRobert Mustacchi     only a normal .o or executable object.
855*4d9fdb46SRobert Mustacchi     Error returned here is on dbg, not tieddbg.
856*4d9fdb46SRobert Mustacchi     This looks for DW_AT_addr_base and if present
857*4d9fdb46SRobert Mustacchi     adds it in appropriately. */
858*4d9fdb46SRobert Mustacchi 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*4d9fdb46SRobert Mustacchi _dwarf_extract_address_from_debug_addr(Dwarf_Debug dbg,
860*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context context,
861*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned index_to_addr,
862*4d9fdb46SRobert Mustacchi     Dwarf_Addr *addr_out,
863*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
864*4d9fdb46SRobert Mustacchi {
865*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned address_base = 0;
866*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned addrindex = index_to_addr;
867*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned addr_offset = 0;
868*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned ret_addr = 0;
869*4d9fdb46SRobert Mustacchi     int res = 0;
870*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr  sectionstart = 0;
871*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr  sectionend = 0;
872*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned  sectionsize  = 0;
873*4d9fdb46SRobert Mustacchi 
874*4d9fdb46SRobert Mustacchi     res = _dwarf_get_address_base_attr_value(dbg,context,
875*4d9fdb46SRobert Mustacchi         &address_base, error);
876*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
877*4d9fdb46SRobert Mustacchi         return res;
878*4d9fdb46SRobert Mustacchi     }
879*4d9fdb46SRobert Mustacchi     res = _dwarf_load_section(dbg, &dbg->de_debug_addr,error);
880*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
881*4d9fdb46SRobert Mustacchi         /*  Ignore the inner error, report something meaningful */
882*4d9fdb46SRobert Mustacchi         if (res == DW_DLV_ERROR) {
883*4d9fdb46SRobert Mustacchi             dwarf_dealloc(dbg,*error, DW_DLA_ERROR);
884*4d9fdb46SRobert Mustacchi             *error = 0;
885*4d9fdb46SRobert Mustacchi         }
886*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg,error,
887*4d9fdb46SRobert Mustacchi             DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION);
888*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
889*4d9fdb46SRobert Mustacchi     }
890*4d9fdb46SRobert Mustacchi     /*  DW_FORM_addrx has a base value from the CU die:
891*4d9fdb46SRobert Mustacchi         DW_AT_addr_base.  DW_OP_addrx and DW_OP_constx
892*4d9fdb46SRobert Mustacchi         rely on DW_AT_addr_base too. */
893*4d9fdb46SRobert Mustacchi     /*  DW_FORM_GNU_addr_index  relies on DW_AT_GNU_addr_base
894*4d9fdb46SRobert Mustacchi         which is in the CU die. */
895*4d9fdb46SRobert Mustacchi 
896*4d9fdb46SRobert Mustacchi     sectionstart = dbg->de_debug_addr.dss_data;
897*4d9fdb46SRobert Mustacchi     addr_offset = address_base + (addrindex * context->cc_address_size);
898*4d9fdb46SRobert Mustacchi     /*  The offsets table is a series of address-size entries
899*4d9fdb46SRobert Mustacchi         but with a base. */
900*4d9fdb46SRobert Mustacchi     sectionsize = dbg->de_debug_addr.dss_size;
901*4d9fdb46SRobert Mustacchi     sectionend = sectionstart + sectionsize;
902*4d9fdb46SRobert Mustacchi     if (addr_offset > (sectionsize - context->cc_address_size)) {
903*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
904*4d9fdb46SRobert Mustacchi         return (DW_DLV_ERROR);
905*4d9fdb46SRobert Mustacchi     }
906*4d9fdb46SRobert Mustacchi     READ_UNALIGNED_CK(dbg,ret_addr,Dwarf_Addr,
907*4d9fdb46SRobert Mustacchi         sectionstart + addr_offset,
908*4d9fdb46SRobert Mustacchi         context->cc_address_size,
909*4d9fdb46SRobert Mustacchi         error,sectionend);
910*4d9fdb46SRobert Mustacchi     *addr_out = ret_addr;
911*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
912*4d9fdb46SRobert Mustacchi }
913*4d9fdb46SRobert Mustacchi 
914*4d9fdb46SRobert Mustacchi 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*4d9fdb46SRobert Mustacchi _dwarf_look_in_local_and_tied_by_index(
916*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg,
917*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context context,
918*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned index,
919*4d9fdb46SRobert Mustacchi     Dwarf_Addr *return_addr,
920*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
921*4d9fdb46SRobert Mustacchi {
922*4d9fdb46SRobert Mustacchi     int res2 = 0;
923*4d9fdb46SRobert Mustacchi 
924*4d9fdb46SRobert Mustacchi     res2 = _dwarf_extract_address_from_debug_addr(dbg,
925*4d9fdb46SRobert Mustacchi         context, index, return_addr, error);
926*4d9fdb46SRobert Mustacchi     if (res2 != DW_DLV_OK) {
927*4d9fdb46SRobert Mustacchi         if (res2 == DW_DLV_ERROR &&
928*4d9fdb46SRobert Mustacchi             error &&
929*4d9fdb46SRobert Mustacchi             dwarf_errno(*error) == DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION
930*4d9fdb46SRobert Mustacchi             && dbg->de_tied_data.td_tied_object) {
931*4d9fdb46SRobert Mustacchi             int res3 = 0;
932*4d9fdb46SRobert Mustacchi 
933*4d9fdb46SRobert Mustacchi             /*  We do not want to leak error structs... */
934*4d9fdb46SRobert Mustacchi             dwarf_dealloc(dbg,*error,DW_DLA_ERROR);
935*4d9fdb46SRobert Mustacchi 
936*4d9fdb46SRobert Mustacchi             *error = 0;
937*4d9fdb46SRobert Mustacchi             /* error is returned on dbg, not tieddbg. */
938*4d9fdb46SRobert Mustacchi             res3 = _dwarf_get_addr_from_tied(dbg,
939*4d9fdb46SRobert Mustacchi                 context,index,return_addr,error);
940*4d9fdb46SRobert Mustacchi             return res3;
941*4d9fdb46SRobert Mustacchi         }
942*4d9fdb46SRobert Mustacchi         return res2;
943*4d9fdb46SRobert Mustacchi     }
944*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
945*4d9fdb46SRobert Mustacchi }
946*4d9fdb46SRobert Mustacchi 
947*4d9fdb46SRobert Mustacchi /*  The DIE here can be any DIE in the relevant CU.
948*4d9fdb46SRobert Mustacchi     index is an index into .debug_addr */
949*4d9fdb46SRobert Mustacchi int
dwarf_debug_addr_index_to_addr(Dwarf_Die die,Dwarf_Unsigned index,Dwarf_Addr * return_addr,Dwarf_Error * error)950*4d9fdb46SRobert Mustacchi dwarf_debug_addr_index_to_addr(Dwarf_Die die,
951*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned index,
952*4d9fdb46SRobert Mustacchi     Dwarf_Addr *return_addr,
953*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
954*4d9fdb46SRobert Mustacchi {
955*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
956*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context context = 0;
957*4d9fdb46SRobert Mustacchi     int res = 0;
958*4d9fdb46SRobert Mustacchi 
959*4d9fdb46SRobert Mustacchi 
960*4d9fdb46SRobert Mustacchi     CHECK_DIE(die, DW_DLV_ERROR);
961*4d9fdb46SRobert Mustacchi     context = die->di_cu_context;
962*4d9fdb46SRobert Mustacchi     dbg = context->cc_dbg;
963*4d9fdb46SRobert Mustacchi 
964*4d9fdb46SRobert Mustacchi     /* error is returned on dbg, not tieddbg. */
965*4d9fdb46SRobert Mustacchi     res = _dwarf_look_in_local_and_tied_by_index(dbg,
966*4d9fdb46SRobert Mustacchi         context,
967*4d9fdb46SRobert Mustacchi         index,
968*4d9fdb46SRobert Mustacchi         return_addr,
969*4d9fdb46SRobert Mustacchi         error);
970*4d9fdb46SRobert Mustacchi     return res;
971*4d9fdb46SRobert Mustacchi }
972*4d9fdb46SRobert Mustacchi /* ASSERT:
973*4d9fdb46SRobert Mustacchi     attr_form == DW_FORM_GNU_addr_index ||
974*4d9fdb46SRobert Mustacchi         attr_form == DW_FORM_addrx
975*4d9fdb46SRobert Mustacchi */
976*4d9fdb46SRobert Mustacchi 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*4d9fdb46SRobert Mustacchi _dwarf_look_in_local_and_tied(Dwarf_Half attr_form,
978*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context context,
979*4d9fdb46SRobert Mustacchi     Dwarf_Small *info_ptr,
980*4d9fdb46SRobert Mustacchi     Dwarf_Addr *return_addr,
981*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
982*4d9fdb46SRobert Mustacchi {
983*4d9fdb46SRobert Mustacchi     int res2 = 0;
984*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned index_to_addr = 0;
985*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
986*4d9fdb46SRobert Mustacchi 
987*4d9fdb46SRobert Mustacchi     /*  We get the index. It might apply here
988*4d9fdb46SRobert Mustacchi         or in tied object. Checking that next. */
989*4d9fdb46SRobert Mustacchi     dbg = context->cc_dbg;
990*4d9fdb46SRobert Mustacchi     res2 = _dwarf_get_addr_index_itself(attr_form,
991*4d9fdb46SRobert Mustacchi         info_ptr,dbg,context, &index_to_addr,error);
992*4d9fdb46SRobert Mustacchi     if(res2 != DW_DLV_OK) {
993*4d9fdb46SRobert Mustacchi         return res2;
994*4d9fdb46SRobert Mustacchi     }
995*4d9fdb46SRobert Mustacchi     /* error is returned on dbg, not tieddbg. */
996*4d9fdb46SRobert Mustacchi     res2 = _dwarf_look_in_local_and_tied_by_index(
997*4d9fdb46SRobert Mustacchi         dbg,context,index_to_addr,return_addr,error);
998*4d9fdb46SRobert Mustacchi     return res2;
999*4d9fdb46SRobert Mustacchi 
1000*4d9fdb46SRobert Mustacchi }
100149d3bc91SRichard Lowe 
100249d3bc91SRichard Lowe int
dwarf_lowpc(Dwarf_Die die,Dwarf_Addr * return_addr,Dwarf_Error * error)100349d3bc91SRichard Lowe dwarf_lowpc(Dwarf_Die die,
1004*4d9fdb46SRobert Mustacchi     Dwarf_Addr * return_addr,
1005*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
100649d3bc91SRichard Lowe {
100707dc1947SRichard Lowe     Dwarf_Addr ret_addr = 0;
100807dc1947SRichard Lowe     Dwarf_Byte_Ptr info_ptr = 0;
100907dc1947SRichard Lowe     Dwarf_Half attr_form = 0;
101007dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
101107dc1947SRichard Lowe     Dwarf_Half address_size = 0;
1012*4d9fdb46SRobert Mustacchi     Dwarf_Half offset_size = 0;
1013*4d9fdb46SRobert Mustacchi     int version = 0;
1014*4d9fdb46SRobert Mustacchi     enum Dwarf_Form_Class class = DW_FORM_CLASS_UNKNOWN;
1015*4d9fdb46SRobert Mustacchi     int res = 0;
1016*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context context = die->di_cu_context;
1017*4d9fdb46SRobert Mustacchi     Dwarf_Small *die_info_end = 0;
101849d3bc91SRichard Lowe 
101907dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
102049d3bc91SRichard Lowe 
1021*4d9fdb46SRobert Mustacchi     dbg = context->cc_dbg;
1022*4d9fdb46SRobert Mustacchi     address_size = context->cc_address_size;
1023*4d9fdb46SRobert Mustacchi     offset_size = context->cc_length_size;
1024*4d9fdb46SRobert Mustacchi     res = _dwarf_get_value_ptr(die, DW_AT_low_pc,
1025*4d9fdb46SRobert Mustacchi         &attr_form,&info_ptr,0,error);
1026*4d9fdb46SRobert Mustacchi     if(res == DW_DLV_ERROR) {
1027*4d9fdb46SRobert Mustacchi         return res;
102849d3bc91SRichard Lowe     }
1029*4d9fdb46SRobert Mustacchi     if(res == DW_DLV_NO_ENTRY) {
1030*4d9fdb46SRobert Mustacchi         return res;
1031*4d9fdb46SRobert Mustacchi     }
1032*4d9fdb46SRobert Mustacchi     version = context->cc_version_stamp;
1033*4d9fdb46SRobert Mustacchi     class = dwarf_get_form_class(version,DW_AT_low_pc,
1034*4d9fdb46SRobert Mustacchi         offset_size,attr_form);
1035*4d9fdb46SRobert Mustacchi     if (class != DW_FORM_CLASS_ADDRESS) {
1036*4d9fdb46SRobert Mustacchi         /* Not the correct form for DW_AT_low_pc */
1037*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_LOWPC_WRONG_CLASS);
1038*4d9fdb46SRobert Mustacchi         return (DW_DLV_ERROR);
103949d3bc91SRichard Lowe     }
104049d3bc91SRichard Lowe 
1041*4d9fdb46SRobert Mustacchi     if(attr_form == DW_FORM_GNU_addr_index ||
1042*4d9fdb46SRobert Mustacchi         attr_form == DW_FORM_addrx) {
1043*4d9fdb46SRobert Mustacchi         /* error is returned on dbg, not tieddbg. */
1044*4d9fdb46SRobert Mustacchi         res = _dwarf_look_in_local_and_tied(
1045*4d9fdb46SRobert Mustacchi             attr_form,
1046*4d9fdb46SRobert Mustacchi             context,
1047*4d9fdb46SRobert Mustacchi             info_ptr,
1048*4d9fdb46SRobert Mustacchi             return_addr,
1049*4d9fdb46SRobert Mustacchi             error);
1050*4d9fdb46SRobert Mustacchi         return res;
1051*4d9fdb46SRobert Mustacchi     }
1052*4d9fdb46SRobert Mustacchi     die_info_end = _dwarf_calculate_info_section_end_ptr(context);
1053*4d9fdb46SRobert Mustacchi     READ_UNALIGNED_CK(dbg, ret_addr, Dwarf_Addr,
1054*4d9fdb46SRobert Mustacchi         info_ptr, address_size,
1055*4d9fdb46SRobert Mustacchi         error,die_info_end);
105649d3bc91SRichard Lowe 
105749d3bc91SRichard Lowe     *return_addr = ret_addr;
105849d3bc91SRichard Lowe     return (DW_DLV_OK);
105949d3bc91SRichard Lowe }
106049d3bc91SRichard Lowe 
106149d3bc91SRichard Lowe 
1062*4d9fdb46SRobert Mustacchi /*  This works for DWARF2 and DWARF3 but fails for DWARF4
1063*4d9fdb46SRobert Mustacchi     DW_AT_high_pc attributes of class constant.
1064*4d9fdb46SRobert Mustacchi     It is best to cease using this interface.
1065*4d9fdb46SRobert Mustacchi     */
106649d3bc91SRichard Lowe int
dwarf_highpc(Dwarf_Die die,Dwarf_Addr * return_addr,Dwarf_Error * error)106749d3bc91SRichard Lowe dwarf_highpc(Dwarf_Die die,
106807dc1947SRichard Lowe     Dwarf_Addr * return_addr, Dwarf_Error * error)
106949d3bc91SRichard Lowe {
1070*4d9fdb46SRobert Mustacchi     int res = 0;
1071*4d9fdb46SRobert Mustacchi     enum Dwarf_Form_Class class = DW_FORM_CLASS_UNKNOWN;
1072*4d9fdb46SRobert Mustacchi     Dwarf_Half form = 0;
1073*4d9fdb46SRobert Mustacchi 
1074*4d9fdb46SRobert Mustacchi     CHECK_DIE(die, DW_DLV_ERROR);
1075*4d9fdb46SRobert Mustacchi     res = dwarf_highpc_b(die,return_addr,&form,&class,error);
1076*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1077*4d9fdb46SRobert Mustacchi         return res;
1078*4d9fdb46SRobert Mustacchi     }
1079*4d9fdb46SRobert Mustacchi     if (form != DW_FORM_addr) {
1080*4d9fdb46SRobert Mustacchi         /* Not the correct form for DWARF2/3 DW_AT_high_pc */
1081*4d9fdb46SRobert Mustacchi         Dwarf_Debug dbg = die->di_cu_context->cc_dbg;
1082*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_HIGHPC_WRONG_FORM);
1083*4d9fdb46SRobert Mustacchi         return (DW_DLV_ERROR);
1084*4d9fdb46SRobert Mustacchi     }
1085*4d9fdb46SRobert Mustacchi     return (DW_DLV_OK);
1086*4d9fdb46SRobert Mustacchi }
1087*4d9fdb46SRobert Mustacchi 
1088*4d9fdb46SRobert Mustacchi /*  If the giving 'die' contains the DW_AT_type attribute, it returns
1089*4d9fdb46SRobert Mustacchi     the offset referenced by the attribute.
1090*4d9fdb46SRobert Mustacchi     In case of DW_DLV_NO_ENTRY or DW_DLV_ERROR it sets offset zero. */
1091*4d9fdb46SRobert Mustacchi int
dwarf_dietype_offset(Dwarf_Die die,Dwarf_Off * return_off,Dwarf_Error * error)1092*4d9fdb46SRobert Mustacchi dwarf_dietype_offset(Dwarf_Die die,
1093*4d9fdb46SRobert Mustacchi     Dwarf_Off *return_off, Dwarf_Error *error)
1094*4d9fdb46SRobert Mustacchi {
1095*4d9fdb46SRobert Mustacchi     int res = 0;
1096*4d9fdb46SRobert Mustacchi     Dwarf_Off offset = 0;
1097*4d9fdb46SRobert Mustacchi     Dwarf_Attribute attr = 0;
1098*4d9fdb46SRobert Mustacchi 
1099*4d9fdb46SRobert Mustacchi     CHECK_DIE(die, DW_DLV_ERROR);
1100*4d9fdb46SRobert Mustacchi     res = dwarf_attr(die,DW_AT_type,&attr,error);
1101*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_OK) {
1102*4d9fdb46SRobert Mustacchi         res = dwarf_global_formref(attr,&offset,error);
1103*4d9fdb46SRobert Mustacchi         dwarf_dealloc(die->di_cu_context->cc_dbg,attr,DW_DLA_ATTR);
1104*4d9fdb46SRobert Mustacchi     }
1105*4d9fdb46SRobert Mustacchi     *return_off = offset;
1106*4d9fdb46SRobert Mustacchi     return res;
1107*4d9fdb46SRobert Mustacchi }
1108*4d9fdb46SRobert Mustacchi 
1109*4d9fdb46SRobert Mustacchi 
1110*4d9fdb46SRobert Mustacchi 
1111*4d9fdb46SRobert Mustacchi int
_dwarf_get_string_base_attr_value(Dwarf_Debug dbg,Dwarf_CU_Context context,Dwarf_Unsigned * sbase_out,Dwarf_Error * error)1112*4d9fdb46SRobert Mustacchi _dwarf_get_string_base_attr_value(Dwarf_Debug dbg,
1113*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context context,
1114*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *sbase_out,
1115*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
1116*4d9fdb46SRobert Mustacchi {
1117*4d9fdb46SRobert Mustacchi     int res = 0;
1118*4d9fdb46SRobert Mustacchi     Dwarf_Die cudie = 0;
1119*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned cu_die_offset = 0;
1120*4d9fdb46SRobert Mustacchi     Dwarf_Attribute myattr = 0;
1121*4d9fdb46SRobert Mustacchi 
1122*4d9fdb46SRobert Mustacchi     if(context->cc_str_offsets_base_present) {
1123*4d9fdb46SRobert Mustacchi         *sbase_out = context->cc_str_offsets_base;
1124*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
1125*4d9fdb46SRobert Mustacchi     }
1126*4d9fdb46SRobert Mustacchi     cu_die_offset = context->cc_cu_die_global_sec_offset;
1127*4d9fdb46SRobert Mustacchi     context->cc_cu_die_offset_present  = TRUE;
1128*4d9fdb46SRobert Mustacchi     res = dwarf_offdie_b(dbg,cu_die_offset,
1129*4d9fdb46SRobert Mustacchi         context->cc_is_info,
1130*4d9fdb46SRobert Mustacchi         &cudie,
1131*4d9fdb46SRobert Mustacchi         error);
1132*4d9fdb46SRobert Mustacchi     if(res != DW_DLV_OK) {
1133*4d9fdb46SRobert Mustacchi         return res;
1134*4d9fdb46SRobert Mustacchi     }
1135*4d9fdb46SRobert Mustacchi     res = dwarf_attr(cudie,DW_AT_str_offsets_base,
1136*4d9fdb46SRobert Mustacchi         &myattr,error);
1137*4d9fdb46SRobert Mustacchi     if(res == DW_DLV_ERROR) {
1138*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1139*4d9fdb46SRobert Mustacchi         return res;
1140*4d9fdb46SRobert Mustacchi     }
1141*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_OK) {
1142*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned val = 0;
1143*4d9fdb46SRobert Mustacchi         /* Expect DW_FORM_sec_offset */
1144*4d9fdb46SRobert Mustacchi         if (myattr->ar_attribute_form != DW_FORM_sec_offset) {
1145*4d9fdb46SRobert Mustacchi             dwarf_dealloc(dbg,myattr,DW_DLA_ATTR);
1146*4d9fdb46SRobert Mustacchi             dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1147*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg, error,DW_DLE_STR_OFFSETS_BASE_WRONG_FORM);
1148*4d9fdb46SRobert Mustacchi             return (DW_DLV_ERROR);
1149*4d9fdb46SRobert Mustacchi         }
1150*4d9fdb46SRobert Mustacchi         res = dwarf_global_formref(myattr,&val,error);
1151*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg,myattr,DW_DLA_ATTR);
1152*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1153*4d9fdb46SRobert Mustacchi         if(res != DW_DLV_OK) {
1154*4d9fdb46SRobert Mustacchi             return res;
1155*4d9fdb46SRobert Mustacchi         }
1156*4d9fdb46SRobert Mustacchi         *sbase_out  = val;
1157*4d9fdb46SRobert Mustacchi         context->cc_str_offsets_base = val;
1158*4d9fdb46SRobert Mustacchi         context->cc_str_offsets_base_present = TRUE;
1159*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
1160*4d9fdb46SRobert Mustacchi     }
1161*4d9fdb46SRobert Mustacchi     /*  NO ENTRY, No other attr.Not even GNU, this one is standard
1162*4d9fdb46SRobert Mustacchi         DWARF5 only.  */
1163*4d9fdb46SRobert Mustacchi     dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1164*4d9fdb46SRobert Mustacchi     /*  We do not need a base for a .dwo. We might for .dwp
1165*4d9fdb46SRobert Mustacchi         and would or .o or executable.
1166*4d9fdb46SRobert Mustacchi         FIXME: assume we do not need this.
1167*4d9fdb46SRobert Mustacchi         Should we really return DW_DLV_NO_ENTRY?
1168*4d9fdb46SRobert Mustacchi     */
1169*4d9fdb46SRobert Mustacchi     *sbase_out = 0;
1170*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1171*4d9fdb46SRobert Mustacchi }
1172*4d9fdb46SRobert Mustacchi /*  Goes to the CU die and finds the DW_AT_GNU_addr_base
1173*4d9fdb46SRobert Mustacchi     (or DW_AT_addr_base ) and gets the value from that CU die
1174*4d9fdb46SRobert Mustacchi     and returns it through abase_out. If we cannot find the value
1175*4d9fdb46SRobert Mustacchi     it is a serious error in the DWARF.
1176*4d9fdb46SRobert Mustacchi     */
1177*4d9fdb46SRobert Mustacchi static int
_dwarf_get_address_base_attr_value(Dwarf_Debug dbg,Dwarf_CU_Context context,Dwarf_Unsigned * abase_out,Dwarf_Error * error)1178*4d9fdb46SRobert Mustacchi _dwarf_get_address_base_attr_value(Dwarf_Debug dbg,
1179*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context context,
1180*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *abase_out,
1181*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
1182*4d9fdb46SRobert Mustacchi {
1183*4d9fdb46SRobert Mustacchi     int res = 0;
1184*4d9fdb46SRobert Mustacchi     Dwarf_Die cudie = 0;
1185*4d9fdb46SRobert Mustacchi     Dwarf_Bool cu_die_offset_present = 0;
1186*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned cu_die_offset = 0;
1187*4d9fdb46SRobert Mustacchi     Dwarf_Attribute myattr = 0;
1188*4d9fdb46SRobert Mustacchi     if(context->cc_addr_base_present) {
1189*4d9fdb46SRobert Mustacchi         *abase_out = context->cc_addr_base;
1190*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
1191*4d9fdb46SRobert Mustacchi     }
1192*4d9fdb46SRobert Mustacchi 
1193*4d9fdb46SRobert Mustacchi     cu_die_offset = context->cc_cu_die_global_sec_offset;
1194*4d9fdb46SRobert Mustacchi     cu_die_offset_present = context->cc_cu_die_offset_present;
1195*4d9fdb46SRobert Mustacchi     if(!cu_die_offset_present) {
1196*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error,
1197*4d9fdb46SRobert Mustacchi             DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM);
1198*4d9fdb46SRobert Mustacchi         return (DW_DLV_ERROR);
1199*4d9fdb46SRobert Mustacchi 
1200*4d9fdb46SRobert Mustacchi     }
1201*4d9fdb46SRobert Mustacchi     res = dwarf_offdie_b(dbg,cu_die_offset,
1202*4d9fdb46SRobert Mustacchi         context->cc_is_info,
1203*4d9fdb46SRobert Mustacchi         &cudie,
1204*4d9fdb46SRobert Mustacchi         error);
1205*4d9fdb46SRobert Mustacchi     if(res != DW_DLV_OK) {
1206*4d9fdb46SRobert Mustacchi         return res;
1207*4d9fdb46SRobert Mustacchi     }
1208*4d9fdb46SRobert Mustacchi     res = dwarf_attr(cudie,DW_AT_addr_base,
1209*4d9fdb46SRobert Mustacchi         &myattr,error);
1210*4d9fdb46SRobert Mustacchi     if(res == DW_DLV_ERROR) {
1211*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1212*4d9fdb46SRobert Mustacchi         return res;
1213*4d9fdb46SRobert Mustacchi     }
1214*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_OK) {
1215*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned val = 0;
1216*4d9fdb46SRobert Mustacchi         res = dwarf_formudata(myattr,&val,error);
1217*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg,myattr,DW_DLA_ATTR);
1218*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1219*4d9fdb46SRobert Mustacchi         if(res != DW_DLV_OK) {
1220*4d9fdb46SRobert Mustacchi             return res;
1221*4d9fdb46SRobert Mustacchi         }
1222*4d9fdb46SRobert Mustacchi         *abase_out  = val;
1223*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
1224*4d9fdb46SRobert Mustacchi     }
1225*4d9fdb46SRobert Mustacchi     /* NO ENTRY, try the other attr. */
1226*4d9fdb46SRobert Mustacchi     res = dwarf_attr(cudie,DW_AT_GNU_addr_base, &myattr,error);
1227*4d9fdb46SRobert Mustacchi     if(res == DW_DLV_NO_ENTRY) {
1228*4d9fdb46SRobert Mustacchi         res = dwarf_attr(cudie,DW_AT_addr_base, &myattr,error);
1229*4d9fdb46SRobert Mustacchi         if (res == DW_DLV_NO_ENTRY) {
1230*4d9fdb46SRobert Mustacchi             /*  A .o or .dwp needs a base, but a .dwo does not.
1231*4d9fdb46SRobert Mustacchi                 FIXME: check this claim...
1232*4d9fdb46SRobert Mustacchi                 Assume zero is ok and works. */
1233*4d9fdb46SRobert Mustacchi             *abase_out = 0;
1234*4d9fdb46SRobert Mustacchi             dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1235*4d9fdb46SRobert Mustacchi             return DW_DLV_OK;
1236*4d9fdb46SRobert Mustacchi         }
1237*4d9fdb46SRobert Mustacchi         if (res == DW_DLV_ERROR) {
1238*4d9fdb46SRobert Mustacchi             dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1239*4d9fdb46SRobert Mustacchi             return res;
1240*4d9fdb46SRobert Mustacchi         }
1241*4d9fdb46SRobert Mustacchi     } else if (res == DW_DLV_ERROR) {
1242*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1243*4d9fdb46SRobert Mustacchi         return res;
1244*4d9fdb46SRobert Mustacchi     }
1245*4d9fdb46SRobert Mustacchi 
1246*4d9fdb46SRobert Mustacchi     {
1247*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned val = 0;
1248*4d9fdb46SRobert Mustacchi         res = dwarf_formudata(myattr,&val,error);
1249*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg,myattr,DW_DLA_ATTR);
1250*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1251*4d9fdb46SRobert Mustacchi         if(res != DW_DLV_OK) {
1252*4d9fdb46SRobert Mustacchi             return res;
1253*4d9fdb46SRobert Mustacchi         }
1254*4d9fdb46SRobert Mustacchi         *abase_out  = val;
1255*4d9fdb46SRobert Mustacchi     }
1256*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1257*4d9fdb46SRobert Mustacchi }
1258*4d9fdb46SRobert Mustacchi 
1259*4d9fdb46SRobert Mustacchi 
1260*4d9fdb46SRobert Mustacchi /* The dbg here will be the tieddbg, and context will be
1261*4d9fdb46SRobert Mustacchi    a tied context.  */
1262*4d9fdb46SRobert Mustacchi static int
_dwarf_get_ranges_base_attr_value(Dwarf_Debug dbg,Dwarf_CU_Context context,Dwarf_Unsigned * rangesbase_out,Dwarf_Error * error)1263*4d9fdb46SRobert Mustacchi _dwarf_get_ranges_base_attr_value(Dwarf_Debug dbg,
1264*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context context,
1265*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * rangesbase_out,
1266*4d9fdb46SRobert Mustacchi     Dwarf_Error    * error)
1267*4d9fdb46SRobert Mustacchi {
1268*4d9fdb46SRobert Mustacchi     int res = 0;
1269*4d9fdb46SRobert Mustacchi     Dwarf_Die cudie = 0;
1270*4d9fdb46SRobert Mustacchi     Dwarf_Bool cu_die_offset_present = 0;
1271*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned cu_die_offset = 0;
1272*4d9fdb46SRobert Mustacchi     Dwarf_Attribute myattr = 0;
1273*4d9fdb46SRobert Mustacchi 
1274*4d9fdb46SRobert Mustacchi     if (!context) {
1275*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error,
1276*4d9fdb46SRobert Mustacchi             DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM);
1277*4d9fdb46SRobert Mustacchi         return (DW_DLV_ERROR);
1278*4d9fdb46SRobert Mustacchi     }
1279*4d9fdb46SRobert Mustacchi     if(context->cc_ranges_base_present) {
1280*4d9fdb46SRobert Mustacchi         *rangesbase_out = context->cc_ranges_base;
1281*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
1282*4d9fdb46SRobert Mustacchi     }
1283*4d9fdb46SRobert Mustacchi     cu_die_offset = context->cc_cu_die_global_sec_offset;
1284*4d9fdb46SRobert Mustacchi     cu_die_offset_present = context->cc_cu_die_offset_present;
1285*4d9fdb46SRobert Mustacchi     if(!cu_die_offset_present) {
1286*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error,
1287*4d9fdb46SRobert Mustacchi             DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM);
1288*4d9fdb46SRobert Mustacchi         return (DW_DLV_ERROR);
1289*4d9fdb46SRobert Mustacchi 
1290*4d9fdb46SRobert Mustacchi     }
1291*4d9fdb46SRobert Mustacchi     res = dwarf_offdie_b(dbg,cu_die_offset,
1292*4d9fdb46SRobert Mustacchi         context->cc_is_info,
1293*4d9fdb46SRobert Mustacchi         &cudie,
1294*4d9fdb46SRobert Mustacchi         error);
1295*4d9fdb46SRobert Mustacchi     if(res != DW_DLV_OK) {
1296*4d9fdb46SRobert Mustacchi         return res;
1297*4d9fdb46SRobert Mustacchi     }
1298*4d9fdb46SRobert Mustacchi     res = dwarf_attr(cudie,DW_AT_rnglists_base,
1299*4d9fdb46SRobert Mustacchi         &myattr,error);
1300*4d9fdb46SRobert Mustacchi     if(res == DW_DLV_ERROR) {
1301*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1302*4d9fdb46SRobert Mustacchi         return res;
1303*4d9fdb46SRobert Mustacchi     }
1304*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_OK) {
1305*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned val = 0;
1306*4d9fdb46SRobert Mustacchi         res = dwarf_formudata(myattr,&val,error);
1307*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg,myattr,DW_DLA_ATTR);
1308*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1309*4d9fdb46SRobert Mustacchi         if(res != DW_DLV_OK) {
1310*4d9fdb46SRobert Mustacchi             return res;
1311*4d9fdb46SRobert Mustacchi         }
1312*4d9fdb46SRobert Mustacchi         *rangesbase_out  = val;
1313*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
1314*4d9fdb46SRobert Mustacchi     }
1315*4d9fdb46SRobert Mustacchi     /* NO ENTRY, try the other attr. */
1316*4d9fdb46SRobert Mustacchi     res = dwarf_attr(cudie,DW_AT_GNU_ranges_base, &myattr,error);
1317*4d9fdb46SRobert Mustacchi     if(res == DW_DLV_NO_ENTRY) {
1318*4d9fdb46SRobert Mustacchi         res = dwarf_attr(cudie,DW_AT_rnglists_base, &myattr,error);
1319*4d9fdb46SRobert Mustacchi         if (res == DW_DLV_NO_ENTRY) {
1320*4d9fdb46SRobert Mustacchi             /*  A .o or execeutable skeleton  needs
1321*4d9fdb46SRobert Mustacchi                 a base , but a .dwo does not.
1322*4d9fdb46SRobert Mustacchi                 Assume zero is ok and works. */
1323*4d9fdb46SRobert Mustacchi             *rangesbase_out = 0;
1324*4d9fdb46SRobert Mustacchi             dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1325*4d9fdb46SRobert Mustacchi             return DW_DLV_OK;
1326*4d9fdb46SRobert Mustacchi         }
1327*4d9fdb46SRobert Mustacchi         if (res == DW_DLV_ERROR) {
1328*4d9fdb46SRobert Mustacchi             dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1329*4d9fdb46SRobert Mustacchi             return res;
1330*4d9fdb46SRobert Mustacchi         }
1331*4d9fdb46SRobert Mustacchi     } else if (res == DW_DLV_ERROR) {
1332*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1333*4d9fdb46SRobert Mustacchi         return res;
1334*4d9fdb46SRobert Mustacchi     }
1335*4d9fdb46SRobert Mustacchi 
1336*4d9fdb46SRobert Mustacchi     {
1337*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned val = 0;
1338*4d9fdb46SRobert Mustacchi         res = dwarf_formudata(myattr,&val,error);
1339*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg,myattr,DW_DLA_ATTR);
1340*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1341*4d9fdb46SRobert Mustacchi         if(res != DW_DLV_OK) {
1342*4d9fdb46SRobert Mustacchi             return res;
1343*4d9fdb46SRobert Mustacchi         }
1344*4d9fdb46SRobert Mustacchi         *rangesbase_out  = val;
1345*4d9fdb46SRobert Mustacchi     }
1346*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1347*4d9fdb46SRobert Mustacchi }
1348*4d9fdb46SRobert Mustacchi /*  This works for  all versions of DWARF.
1349*4d9fdb46SRobert Mustacchi     This is the preferred interface, cease using dwarf_highpc.
1350*4d9fdb46SRobert Mustacchi     The consumer has to check the return_form or
1351*4d9fdb46SRobert Mustacchi     return_class to decide if the value returned
1352*4d9fdb46SRobert Mustacchi     through return_value is an address or an address-offset.
1353*4d9fdb46SRobert Mustacchi 
1354*4d9fdb46SRobert Mustacchi     See  DWARF4 section 2.17.2,
1355*4d9fdb46SRobert Mustacchi     "Contiguous Address Range".
1356*4d9fdb46SRobert Mustacchi     */
1357*4d9fdb46SRobert Mustacchi 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*4d9fdb46SRobert Mustacchi dwarf_highpc_b(Dwarf_Die die,
1359*4d9fdb46SRobert Mustacchi     Dwarf_Addr * return_value,
1360*4d9fdb46SRobert Mustacchi     Dwarf_Half * return_form,
1361*4d9fdb46SRobert Mustacchi     enum Dwarf_Form_Class * return_class,
1362*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
1363*4d9fdb46SRobert Mustacchi {
136407dc1947SRichard Lowe     Dwarf_Byte_Ptr info_ptr = 0;
136507dc1947SRichard Lowe     Dwarf_Half attr_form = 0;
136607dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
136707dc1947SRichard Lowe     Dwarf_Half address_size = 0;
1368*4d9fdb46SRobert Mustacchi     Dwarf_Half offset_size = 0;
1369*4d9fdb46SRobert Mustacchi     enum Dwarf_Form_Class class = DW_FORM_CLASS_UNKNOWN;
1370*4d9fdb46SRobert Mustacchi     Dwarf_Half version = 0;
1371*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr die_info_end = 0;
1372*4d9fdb46SRobert Mustacchi     int res = 0;
137349d3bc91SRichard Lowe 
137407dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
137507dc1947SRichard Lowe     dbg = die->di_cu_context->cc_dbg;
137607dc1947SRichard Lowe     address_size = die->di_cu_context->cc_address_size;
1377*4d9fdb46SRobert Mustacchi 
1378*4d9fdb46SRobert Mustacchi     res = _dwarf_get_value_ptr(die, DW_AT_high_pc,
1379*4d9fdb46SRobert Mustacchi         &attr_form,&info_ptr,0,error);
1380*4d9fdb46SRobert Mustacchi     if(res == DW_DLV_ERROR) {
1381*4d9fdb46SRobert Mustacchi         return res;
138249d3bc91SRichard Lowe     }
1383*4d9fdb46SRobert Mustacchi     if(res == DW_DLV_NO_ENTRY) {
1384*4d9fdb46SRobert Mustacchi         return res;
138549d3bc91SRichard Lowe     }
1386*4d9fdb46SRobert Mustacchi     die_info_end = _dwarf_calculate_info_section_end_ptr(
1387*4d9fdb46SRobert Mustacchi         die->di_cu_context);
1388*4d9fdb46SRobert Mustacchi 
1389*4d9fdb46SRobert Mustacchi     version = die->di_cu_context->cc_version_stamp;
1390*4d9fdb46SRobert Mustacchi     offset_size = die->di_cu_context->cc_length_size;
1391*4d9fdb46SRobert Mustacchi     class = dwarf_get_form_class(version,DW_AT_high_pc,
1392*4d9fdb46SRobert Mustacchi         offset_size,attr_form);
1393*4d9fdb46SRobert Mustacchi 
1394*4d9fdb46SRobert Mustacchi     if (class == DW_FORM_CLASS_ADDRESS) {
1395*4d9fdb46SRobert Mustacchi         Dwarf_Addr addr = 0;
1396*4d9fdb46SRobert Mustacchi         if (dwarf_addr_form_is_indexed(attr_form)) {
1397*4d9fdb46SRobert Mustacchi             Dwarf_Unsigned addr_out = 0;
1398*4d9fdb46SRobert Mustacchi             Dwarf_Unsigned index_to_addr = 0;
1399*4d9fdb46SRobert Mustacchi             int res2 = 0;
1400*4d9fdb46SRobert Mustacchi             Dwarf_CU_Context context = die->di_cu_context;
1401*4d9fdb46SRobert Mustacchi 
1402*4d9fdb46SRobert Mustacchi             /*  index_to_addr we get here might apply
1403*4d9fdb46SRobert Mustacchi                 to this dbg or to tieddbg. */
1404*4d9fdb46SRobert Mustacchi             /* error is returned on dbg, not tied */
1405*4d9fdb46SRobert Mustacchi             res2 = _dwarf_get_addr_index_itself(attr_form,
1406*4d9fdb46SRobert Mustacchi                 info_ptr,dbg,context,&index_to_addr,error);
1407*4d9fdb46SRobert Mustacchi             if(res2 != DW_DLV_OK) {
1408*4d9fdb46SRobert Mustacchi                 return res2;
1409*4d9fdb46SRobert Mustacchi             }
141049d3bc91SRichard Lowe 
1411*4d9fdb46SRobert Mustacchi             res2 = _dwarf_extract_address_from_debug_addr(dbg,
1412*4d9fdb46SRobert Mustacchi                 context,
1413*4d9fdb46SRobert Mustacchi                 index_to_addr,
1414*4d9fdb46SRobert Mustacchi                 &addr_out,
1415*4d9fdb46SRobert Mustacchi                 error);
1416*4d9fdb46SRobert Mustacchi             if(res2 != DW_DLV_OK) {
1417*4d9fdb46SRobert Mustacchi                 if (res2 == DW_DLV_ERROR &&
1418*4d9fdb46SRobert Mustacchi                     error &&
1419*4d9fdb46SRobert Mustacchi                     dwarf_errno(*error) ==
1420*4d9fdb46SRobert Mustacchi                     DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION
1421*4d9fdb46SRobert Mustacchi                     && dbg->de_tied_data.td_tied_object) {
1422*4d9fdb46SRobert Mustacchi                     /*  .debug_addr is in tied dbg. */
1423*4d9fdb46SRobert Mustacchi                     int res3 = 0;
1424*4d9fdb46SRobert Mustacchi 
1425*4d9fdb46SRobert Mustacchi                     /*  Do not leak the above error pointer,
1426*4d9fdb46SRobert Mustacchi                         we have something else to try here. */
1427*4d9fdb46SRobert Mustacchi                     dwarf_dealloc(dbg,*error, DW_DLA_ERROR);
1428*4d9fdb46SRobert Mustacchi                     *error = 0;
1429*4d9fdb46SRobert Mustacchi 
1430*4d9fdb46SRobert Mustacchi                     /*  .debug_addr is in tied dbg.
1431*4d9fdb46SRobert Mustacchi                         Get the index of the addr */
1432*4d9fdb46SRobert Mustacchi                     res3 = _dwarf_get_addr_from_tied(dbg,
1433*4d9fdb46SRobert Mustacchi                         context,index_to_addr,&addr_out,error);
1434*4d9fdb46SRobert Mustacchi                     if ( res3 != DW_DLV_OK) {
1435*4d9fdb46SRobert Mustacchi                         return res3;
1436*4d9fdb46SRobert Mustacchi                     }
1437*4d9fdb46SRobert Mustacchi                 } else {
1438*4d9fdb46SRobert Mustacchi                     return res2;
1439*4d9fdb46SRobert Mustacchi                 }
1440*4d9fdb46SRobert Mustacchi             }
1441*4d9fdb46SRobert Mustacchi             *return_value = addr_out;
1442*4d9fdb46SRobert Mustacchi             /*  Allow null args starting 22 April 2019. */
1443*4d9fdb46SRobert Mustacchi             if (return_form) {
1444*4d9fdb46SRobert Mustacchi                 *return_form = attr_form;
1445*4d9fdb46SRobert Mustacchi             }
1446*4d9fdb46SRobert Mustacchi             if (return_class) {
1447*4d9fdb46SRobert Mustacchi                 *return_class = class;
1448*4d9fdb46SRobert Mustacchi             }
1449*4d9fdb46SRobert Mustacchi             return (DW_DLV_OK);
1450*4d9fdb46SRobert Mustacchi         }
145149d3bc91SRichard Lowe 
1452*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, addr, Dwarf_Addr,
1453*4d9fdb46SRobert Mustacchi             info_ptr, address_size,
1454*4d9fdb46SRobert Mustacchi             error,die_info_end);
1455*4d9fdb46SRobert Mustacchi         *return_value = addr;
1456*4d9fdb46SRobert Mustacchi     } else {
1457*4d9fdb46SRobert Mustacchi         int res3 = 0;
1458*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned v = 0;
1459*4d9fdb46SRobert Mustacchi         res3 = _dwarf_die_attr_unsigned_constant(die,DW_AT_high_pc,
1460*4d9fdb46SRobert Mustacchi             &v,error);
1461*4d9fdb46SRobert Mustacchi         if(res3 != DW_DLV_OK) {
1462*4d9fdb46SRobert Mustacchi             Dwarf_Byte_Ptr info_ptr2 = 0;
1463*4d9fdb46SRobert Mustacchi 
1464*4d9fdb46SRobert Mustacchi             res3 = _dwarf_get_value_ptr(die, DW_AT_high_pc,
1465*4d9fdb46SRobert Mustacchi                 &attr_form,&info_ptr2,0,error);
1466*4d9fdb46SRobert Mustacchi             if(res3 == DW_DLV_ERROR) {
1467*4d9fdb46SRobert Mustacchi                 return res3;
1468*4d9fdb46SRobert Mustacchi             }
1469*4d9fdb46SRobert Mustacchi             if(res3 == DW_DLV_NO_ENTRY) {
1470*4d9fdb46SRobert Mustacchi                 return res3;
1471*4d9fdb46SRobert Mustacchi             }
1472*4d9fdb46SRobert Mustacchi             if (attr_form == DW_FORM_sdata) {
1473*4d9fdb46SRobert Mustacchi                 Dwarf_Signed sval = 0;
1474*4d9fdb46SRobert Mustacchi 
1475*4d9fdb46SRobert Mustacchi                 /*  DWARF4 defines the value as an unsigned offset
1476*4d9fdb46SRobert Mustacchi                     in section 2.17.2. */
1477*4d9fdb46SRobert Mustacchi                 DECODE_LEB128_UWORD_CK(info_ptr2, sval,
1478*4d9fdb46SRobert Mustacchi                     dbg,error,die_info_end);
1479*4d9fdb46SRobert Mustacchi                 *return_value = (Dwarf_Unsigned)sval;
1480*4d9fdb46SRobert Mustacchi             } else {
1481*4d9fdb46SRobert Mustacchi                 _dwarf_error(dbg, error, DW_DLE_HIGHPC_WRONG_FORM);
1482*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
1483*4d9fdb46SRobert Mustacchi             }
1484*4d9fdb46SRobert Mustacchi         } else {
1485*4d9fdb46SRobert Mustacchi             *return_value = v;
1486*4d9fdb46SRobert Mustacchi         }
1487*4d9fdb46SRobert Mustacchi     }
1488*4d9fdb46SRobert Mustacchi     /*  Allow null args starting 22 April 2019. */
1489*4d9fdb46SRobert Mustacchi     if (return_form) {
1490*4d9fdb46SRobert Mustacchi         *return_form = attr_form;
1491*4d9fdb46SRobert Mustacchi     }
1492*4d9fdb46SRobert Mustacchi     if (return_class) {
1493*4d9fdb46SRobert Mustacchi         *return_class = class;
1494*4d9fdb46SRobert Mustacchi     }
1495*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1496*4d9fdb46SRobert Mustacchi }
1497*4d9fdb46SRobert Mustacchi 
1498*4d9fdb46SRobert Mustacchi /* The dbg and context here are a file with DW_FORM_addrx
1499*4d9fdb46SRobert Mustacchi     but missing .debug_addr. So go to the tied file
1500*4d9fdb46SRobert Mustacchi     and using the signature from the current context
1501*4d9fdb46SRobert Mustacchi     locate the target CU in the tied file Then
1502*4d9fdb46SRobert Mustacchi     get the address.
1503*4d9fdb46SRobert Mustacchi 
1504*4d9fdb46SRobert Mustacchi */
1505*4d9fdb46SRobert Mustacchi int
_dwarf_get_addr_from_tied(Dwarf_Debug dbg,Dwarf_CU_Context context,Dwarf_Unsigned index,Dwarf_Addr * addr_out,Dwarf_Error * error)1506*4d9fdb46SRobert Mustacchi _dwarf_get_addr_from_tied(Dwarf_Debug dbg,
1507*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context context,
1508*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned index,
1509*4d9fdb46SRobert Mustacchi     Dwarf_Addr *addr_out,
1510*4d9fdb46SRobert Mustacchi     Dwarf_Error*error)
1511*4d9fdb46SRobert Mustacchi {
1512*4d9fdb46SRobert Mustacchi     Dwarf_Debug tieddbg = 0;
1513*4d9fdb46SRobert Mustacchi     int res = 0;
1514*4d9fdb46SRobert Mustacchi     Dwarf_Addr local_addr = 0;
1515*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context tiedcontext = 0;
1516*4d9fdb46SRobert Mustacchi 
1517*4d9fdb46SRobert Mustacchi     if (!context->cc_signature_present) {
1518*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_NO_SIGNATURE_TO_LOOKUP);
1519*4d9fdb46SRobert Mustacchi         return  DW_DLV_ERROR;
1520*4d9fdb46SRobert Mustacchi     }
1521*4d9fdb46SRobert Mustacchi     tieddbg = dbg->de_tied_data.td_tied_object;
1522*4d9fdb46SRobert Mustacchi     if (!tieddbg) {
1523*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_NO_TIED_ADDR_AVAILABLE);
1524*4d9fdb46SRobert Mustacchi         return  DW_DLV_ERROR;
1525*4d9fdb46SRobert Mustacchi     }
1526*4d9fdb46SRobert Mustacchi     if (!context->cc_signature_present) {
1527*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_NO_TIED_SIG_AVAILABLE);
1528*4d9fdb46SRobert Mustacchi         return  DW_DLV_ERROR;
1529*4d9fdb46SRobert Mustacchi     }
1530*4d9fdb46SRobert Mustacchi     res = _dwarf_search_for_signature(tieddbg,
1531*4d9fdb46SRobert Mustacchi         context->cc_signature,
1532*4d9fdb46SRobert Mustacchi         &tiedcontext,
1533*4d9fdb46SRobert Mustacchi         error);
1534*4d9fdb46SRobert Mustacchi     if ( res == DW_DLV_ERROR) {
1535*4d9fdb46SRobert Mustacchi         /* Associate the error with dbg, not tieddbg */
1536*4d9fdb46SRobert Mustacchi         _dwarf_error_mv_s_to_t(tieddbg,error,dbg,error);
1537*4d9fdb46SRobert Mustacchi         return res;
1538*4d9fdb46SRobert Mustacchi     } else if ( res == DW_DLV_NO_ENTRY) {
1539*4d9fdb46SRobert Mustacchi         return res;
1540*4d9fdb46SRobert Mustacchi     }
1541*4d9fdb46SRobert Mustacchi 
1542*4d9fdb46SRobert Mustacchi     res = _dwarf_extract_address_from_debug_addr(tieddbg,
1543*4d9fdb46SRobert Mustacchi         tiedcontext,
1544*4d9fdb46SRobert Mustacchi         index,
1545*4d9fdb46SRobert Mustacchi         &local_addr,
1546*4d9fdb46SRobert Mustacchi         error);
1547*4d9fdb46SRobert Mustacchi     if ( res == DW_DLV_ERROR) {
1548*4d9fdb46SRobert Mustacchi         /* Associate the error with dbg, not tidedbg */
1549*4d9fdb46SRobert Mustacchi         _dwarf_error_mv_s_to_t(tieddbg,error,dbg,error);
1550*4d9fdb46SRobert Mustacchi         return res;
1551*4d9fdb46SRobert Mustacchi     } else if ( res == DW_DLV_NO_ENTRY) {
1552*4d9fdb46SRobert Mustacchi         return res;
1553*4d9fdb46SRobert Mustacchi     }
1554*4d9fdb46SRobert Mustacchi     *addr_out = local_addr;
1555*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1556*4d9fdb46SRobert Mustacchi }
1557*4d9fdb46SRobert Mustacchi 
1558*4d9fdb46SRobert Mustacchi 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*4d9fdb46SRobert Mustacchi _dwarf_get_ranges_base_attr_from_tied(Dwarf_Debug dbg,
1560*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context context,
1561*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * ranges_base_out,
1562*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * addr_base_out,
1563*4d9fdb46SRobert Mustacchi     Dwarf_Error*error)
1564*4d9fdb46SRobert Mustacchi {
1565*4d9fdb46SRobert Mustacchi     Dwarf_Debug tieddbg = 0;
1566*4d9fdb46SRobert Mustacchi     int res = 0;
1567*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned tiedbase= 0;
1568*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context tiedcontext = 0;
1569*4d9fdb46SRobert Mustacchi 
1570*4d9fdb46SRobert Mustacchi     if (!context->cc_signature_present) {
1571*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_NO_SIGNATURE_TO_LOOKUP);
1572*4d9fdb46SRobert Mustacchi         return  DW_DLV_ERROR;
1573*4d9fdb46SRobert Mustacchi     }
1574*4d9fdb46SRobert Mustacchi     tieddbg = dbg->de_tied_data.td_tied_object;
1575*4d9fdb46SRobert Mustacchi     if (!tieddbg) {
1576*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_NO_TIED_ADDR_AVAILABLE);
1577*4d9fdb46SRobert Mustacchi         return  DW_DLV_ERROR;
1578*4d9fdb46SRobert Mustacchi     }
1579*4d9fdb46SRobert Mustacchi     if (!context->cc_signature_present) {
1580*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_NO_TIED_SIG_AVAILABLE);
1581*4d9fdb46SRobert Mustacchi         return  DW_DLV_ERROR;
1582*4d9fdb46SRobert Mustacchi     }
1583*4d9fdb46SRobert Mustacchi     res = _dwarf_search_for_signature(tieddbg,
1584*4d9fdb46SRobert Mustacchi         context->cc_signature,
1585*4d9fdb46SRobert Mustacchi         &tiedcontext,
1586*4d9fdb46SRobert Mustacchi         error);
1587*4d9fdb46SRobert Mustacchi     if ( res == DW_DLV_ERROR) {
1588*4d9fdb46SRobert Mustacchi         /* Associate the error with dbg, not tidedbg */
1589*4d9fdb46SRobert Mustacchi         _dwarf_error_mv_s_to_t(tieddbg,error,dbg,error);
1590*4d9fdb46SRobert Mustacchi         return res;
1591*4d9fdb46SRobert Mustacchi     } else if ( res == DW_DLV_NO_ENTRY) {
1592*4d9fdb46SRobert Mustacchi         return res;
1593*4d9fdb46SRobert Mustacchi     }
1594*4d9fdb46SRobert Mustacchi     res = _dwarf_get_ranges_base_attr_value(tieddbg, tiedcontext,
1595*4d9fdb46SRobert Mustacchi         &tiedbase, error);
1596*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1597*4d9fdb46SRobert Mustacchi         /* Associate the error with dbg, not tidedbg */
1598*4d9fdb46SRobert Mustacchi         _dwarf_error_mv_s_to_t(tieddbg,error,dbg,error);
1599*4d9fdb46SRobert Mustacchi         return res;
1600*4d9fdb46SRobert Mustacchi     }
1601*4d9fdb46SRobert Mustacchi     *ranges_base_out = tiedbase;
1602*4d9fdb46SRobert Mustacchi     *addr_base_out =  tiedcontext->cc_addr_base;
1603*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
160449d3bc91SRichard Lowe }
160549d3bc91SRichard Lowe 
160649d3bc91SRichard Lowe 
160749d3bc91SRichard Lowe /*
1608*4d9fdb46SRobert Mustacchi     Takes a die, an attribute attr, and checks if attr
160949d3bc91SRichard Lowe     occurs in die.  Attr is required to be an attribute
1610*4d9fdb46SRobert Mustacchi     whose form is in the "constant" class.  If attr occurs
1611*4d9fdb46SRobert Mustacchi     in die, the value is returned.
1612*4d9fdb46SRobert Mustacchi 
1613*4d9fdb46SRobert Mustacchi     Returns DW_DLV_OK, DW_DLV_ERROR, or DW_DLV_NO_ENTRY as
161449d3bc91SRichard Lowe     appropriate. Sets the value thru the pointer return_val.
1615*4d9fdb46SRobert Mustacchi 
1616*4d9fdb46SRobert Mustacchi     This function is meant to do all the
1617*4d9fdb46SRobert Mustacchi     processing for dwarf_bytesize, dwarf_bitsize, dwarf_bitoffset,
1618*4d9fdb46SRobert Mustacchi     and dwarf_srclang. And it helps in dwarf_highpc_with_form().
161949d3bc91SRichard Lowe */
162049d3bc91SRichard Lowe static int
_dwarf_die_attr_unsigned_constant(Dwarf_Die die,Dwarf_Half attr,Dwarf_Unsigned * return_val,Dwarf_Error * error)162149d3bc91SRichard Lowe _dwarf_die_attr_unsigned_constant(Dwarf_Die die,
162207dc1947SRichard Lowe     Dwarf_Half attr,
162307dc1947SRichard Lowe     Dwarf_Unsigned * return_val,
162407dc1947SRichard Lowe     Dwarf_Error * error)
162549d3bc91SRichard Lowe {
1626*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr info_ptr = 0;
1627*4d9fdb46SRobert Mustacchi     Dwarf_Half attr_form = 0;
1628*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned ret_value = 0;
1629*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
1630*4d9fdb46SRobert Mustacchi     int res = 0;
1631*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr die_info_end = 0;
163249d3bc91SRichard Lowe 
163307dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
163449d3bc91SRichard Lowe 
1635*4d9fdb46SRobert Mustacchi     die_info_end = _dwarf_calculate_info_section_end_ptr(die->di_cu_context);
163607dc1947SRichard Lowe     dbg = die->di_cu_context->cc_dbg;
1637*4d9fdb46SRobert Mustacchi     res = _dwarf_get_value_ptr(die,attr,&attr_form,
1638*4d9fdb46SRobert Mustacchi         &info_ptr,0,error);
1639*4d9fdb46SRobert Mustacchi     if(res != DW_DLV_OK) {
1640*4d9fdb46SRobert Mustacchi         return res;
1641*4d9fdb46SRobert Mustacchi     }
1642*4d9fdb46SRobert Mustacchi     switch (attr_form) {
1643*4d9fdb46SRobert Mustacchi     case DW_FORM_data1:
1644*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned,
1645*4d9fdb46SRobert Mustacchi             info_ptr, sizeof(Dwarf_Small),
1646*4d9fdb46SRobert Mustacchi             error,die_info_end);
1647*4d9fdb46SRobert Mustacchi         *return_val = ret_value;
1648*4d9fdb46SRobert Mustacchi         return (DW_DLV_OK);
1649*4d9fdb46SRobert Mustacchi 
1650*4d9fdb46SRobert Mustacchi     case DW_FORM_data2:
1651*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned,
1652*4d9fdb46SRobert Mustacchi             info_ptr, sizeof(Dwarf_Shalf),
1653*4d9fdb46SRobert Mustacchi             error,die_info_end);
1654*4d9fdb46SRobert Mustacchi         *return_val = ret_value;
1655*4d9fdb46SRobert Mustacchi         return (DW_DLV_OK);
1656*4d9fdb46SRobert Mustacchi 
1657*4d9fdb46SRobert Mustacchi     case DW_FORM_data4:
1658*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned,
1659*4d9fdb46SRobert Mustacchi             info_ptr, DWARF_32BIT_SIZE,
1660*4d9fdb46SRobert Mustacchi             error,die_info_end);
1661*4d9fdb46SRobert Mustacchi         *return_val = ret_value;
1662*4d9fdb46SRobert Mustacchi         return (DW_DLV_OK);
1663*4d9fdb46SRobert Mustacchi 
1664*4d9fdb46SRobert Mustacchi     case DW_FORM_data8:
1665*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned,
1666*4d9fdb46SRobert Mustacchi             info_ptr, DWARF_64BIT_SIZE,
1667*4d9fdb46SRobert Mustacchi             error,die_info_end);
1668*4d9fdb46SRobert Mustacchi         *return_val = ret_value;
1669*4d9fdb46SRobert Mustacchi         return (DW_DLV_OK);
1670*4d9fdb46SRobert Mustacchi 
1671*4d9fdb46SRobert Mustacchi     case DW_FORM_udata: {
1672*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned v = 0;
1673*4d9fdb46SRobert Mustacchi 
1674*4d9fdb46SRobert Mustacchi         DECODE_LEB128_UWORD_CK(info_ptr, v,dbg,error,die_info_end);
1675*4d9fdb46SRobert Mustacchi         *return_val = v;
1676*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
167707dc1947SRichard Lowe 
167807dc1947SRichard Lowe 
167949d3bc91SRichard Lowe     }
1680*4d9fdb46SRobert Mustacchi 
1681*4d9fdb46SRobert Mustacchi     default:
168207dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
168307dc1947SRichard Lowe         return (DW_DLV_ERROR);
168449d3bc91SRichard Lowe     }
168549d3bc91SRichard Lowe }
168649d3bc91SRichard Lowe 
168749d3bc91SRichard Lowe 
168849d3bc91SRichard Lowe int
dwarf_bytesize(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)168949d3bc91SRichard Lowe dwarf_bytesize(Dwarf_Die die,
169007dc1947SRichard Lowe     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
169149d3bc91SRichard Lowe {
169207dc1947SRichard Lowe     Dwarf_Unsigned luns = 0;
1693*4d9fdb46SRobert Mustacchi     int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_byte_size,
169407dc1947SRichard Lowe         &luns, error);
169549d3bc91SRichard Lowe     *ret_size = luns;
169649d3bc91SRichard Lowe     return res;
169749d3bc91SRichard Lowe }
169849d3bc91SRichard Lowe 
169949d3bc91SRichard Lowe 
170049d3bc91SRichard Lowe int
dwarf_bitsize(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)170149d3bc91SRichard Lowe dwarf_bitsize(Dwarf_Die die,
170207dc1947SRichard Lowe     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
170349d3bc91SRichard Lowe {
170407dc1947SRichard Lowe     Dwarf_Unsigned luns = 0;
1705*4d9fdb46SRobert Mustacchi     int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_size,
170607dc1947SRichard Lowe         &luns, error);
170749d3bc91SRichard Lowe     *ret_size = luns;
170849d3bc91SRichard Lowe     return res;
170949d3bc91SRichard Lowe }
171049d3bc91SRichard Lowe 
171149d3bc91SRichard Lowe 
171249d3bc91SRichard Lowe int
dwarf_bitoffset(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)171349d3bc91SRichard Lowe dwarf_bitoffset(Dwarf_Die die,
171407dc1947SRichard Lowe     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
171549d3bc91SRichard Lowe {
171607dc1947SRichard Lowe     Dwarf_Unsigned luns = 0;
1717*4d9fdb46SRobert Mustacchi     int res = _dwarf_die_attr_unsigned_constant(die,
171807dc1947SRichard Lowe         DW_AT_bit_offset, &luns, error);
171949d3bc91SRichard Lowe     *ret_size = luns;
172049d3bc91SRichard Lowe     return res;
172149d3bc91SRichard Lowe }
172249d3bc91SRichard Lowe 
172349d3bc91SRichard Lowe 
172449d3bc91SRichard Lowe /* Refer section 3.1, page 21 in Dwarf Definition. */
172549d3bc91SRichard Lowe int
dwarf_srclang(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)172649d3bc91SRichard Lowe dwarf_srclang(Dwarf_Die die,
172707dc1947SRichard Lowe     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
172849d3bc91SRichard Lowe {
172907dc1947SRichard Lowe     Dwarf_Unsigned luns = 0;
1730*4d9fdb46SRobert Mustacchi     int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_language,
173107dc1947SRichard Lowe         &luns, error);
173249d3bc91SRichard Lowe     *ret_size = luns;
173349d3bc91SRichard Lowe     return res;
173449d3bc91SRichard Lowe }
173549d3bc91SRichard Lowe 
173649d3bc91SRichard Lowe 
173749d3bc91SRichard Lowe /* Refer section 5.4, page 37 in Dwarf Definition. */
173849d3bc91SRichard Lowe int
dwarf_arrayorder(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)173949d3bc91SRichard Lowe dwarf_arrayorder(Dwarf_Die die,
174007dc1947SRichard Lowe     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
174149d3bc91SRichard Lowe {
174207dc1947SRichard Lowe     Dwarf_Unsigned luns = 0;
1743*4d9fdb46SRobert Mustacchi     int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_ordering,
174407dc1947SRichard Lowe         &luns, error);
174549d3bc91SRichard Lowe     *ret_size = luns;
174649d3bc91SRichard Lowe     return res;
174749d3bc91SRichard Lowe }
174849d3bc91SRichard Lowe 
1749*4d9fdb46SRobert Mustacchi /*  Return DW_DLV_OK if ok
1750*4d9fdb46SRobert Mustacchi     DW_DLV_ERROR if failure.
175149d3bc91SRichard Lowe 
1752*4d9fdb46SRobert Mustacchi     If the die and the attr are not related the result is
1753*4d9fdb46SRobert Mustacchi     meaningless.  */
175449d3bc91SRichard Lowe int
dwarf_attr_offset(Dwarf_Die die,Dwarf_Attribute attr,Dwarf_Off * offset,Dwarf_Error * error)1755*4d9fdb46SRobert Mustacchi dwarf_attr_offset(Dwarf_Die die, Dwarf_Attribute attr,
175607dc1947SRichard Lowe     Dwarf_Off * offset /* return offset thru this ptr */,
175707dc1947SRichard Lowe     Dwarf_Error * error)
175849d3bc91SRichard Lowe {
175907dc1947SRichard Lowe     Dwarf_Off attroff = 0;
1760*4d9fdb46SRobert Mustacchi     Dwarf_Small *dataptr = 0;
1761*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
176249d3bc91SRichard Lowe 
176307dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
1764*4d9fdb46SRobert Mustacchi     dbg = die->di_cu_context->cc_dbg;
1765*4d9fdb46SRobert Mustacchi     dataptr = die->di_is_info? dbg->de_debug_info.dss_data:
1766*4d9fdb46SRobert Mustacchi         dbg->de_debug_types.dss_data;
176749d3bc91SRichard Lowe 
1768*4d9fdb46SRobert Mustacchi     attroff = (attr->ar_debug_ptr - dataptr);
176949d3bc91SRichard Lowe     *offset = attroff;
177049d3bc91SRichard Lowe     return DW_DLV_OK;
177149d3bc91SRichard Lowe }
177207dc1947SRichard Lowe 
177307dc1947SRichard Lowe int
dwarf_die_abbrev_code(Dwarf_Die die)177407dc1947SRichard Lowe dwarf_die_abbrev_code(Dwarf_Die die)
177507dc1947SRichard Lowe {
177607dc1947SRichard Lowe     return die->di_abbrev_code;
177707dc1947SRichard Lowe }
177807dc1947SRichard Lowe 
1779*4d9fdb46SRobert Mustacchi /*  Returns a flag through ablhas_child. Non-zero if
1780*4d9fdb46SRobert Mustacchi     the DIE has children, zero if it does not.
1781*4d9fdb46SRobert Mustacchi     It has no Dwarf_Error arg!
1782*4d9fdb46SRobert Mustacchi */
1783*4d9fdb46SRobert Mustacchi int
dwarf_die_abbrev_children_flag(Dwarf_Die die,Dwarf_Half * ab_has_child)1784*4d9fdb46SRobert Mustacchi dwarf_die_abbrev_children_flag(Dwarf_Die die,Dwarf_Half *ab_has_child)
1785*4d9fdb46SRobert Mustacchi {
1786*4d9fdb46SRobert Mustacchi     if (die->di_abbrev_list) {
1787*4d9fdb46SRobert Mustacchi         *ab_has_child = die->di_abbrev_list->abl_has_child;
1788*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
1789*4d9fdb46SRobert Mustacchi     }
1790*4d9fdb46SRobert Mustacchi     return DW_DLV_ERROR;
1791*4d9fdb46SRobert Mustacchi }
1792*4d9fdb46SRobert Mustacchi 
179307dc1947SRichard Lowe /* Helper function for finding form class. */
1794*4d9fdb46SRobert Mustacchi static enum Dwarf_Form_Class
dw_get_special_offset(Dwarf_Half attrnum,Dwarf_Half dwversion)1795*4d9fdb46SRobert Mustacchi dw_get_special_offset(Dwarf_Half attrnum,
1796*4d9fdb46SRobert Mustacchi     Dwarf_Half dwversion)
179707dc1947SRichard Lowe {
1798*4d9fdb46SRobert Mustacchi     switch (attrnum) {
179907dc1947SRichard Lowe     case DW_AT_stmt_list:
1800*4d9fdb46SRobert Mustacchi         return DW_FORM_CLASS_LINEPTR;
1801*4d9fdb46SRobert Mustacchi     case DW_AT_macro_info: /* DWARF2-DWARF4 */
1802*4d9fdb46SRobert Mustacchi         return DW_FORM_CLASS_MACPTR;
1803*4d9fdb46SRobert Mustacchi     case DW_AT_start_scope:
1804*4d9fdb46SRobert Mustacchi     case DW_AT_ranges: {
1805*4d9fdb46SRobert Mustacchi         if (dwversion <= 4) {
1806*4d9fdb46SRobert Mustacchi             return DW_FORM_CLASS_RANGELISTPTR;
1807*4d9fdb46SRobert Mustacchi         }
1808*4d9fdb46SRobert Mustacchi         return DW_FORM_CLASS_RNGLIST;
1809*4d9fdb46SRobert Mustacchi         }
1810*4d9fdb46SRobert Mustacchi     case DW_AT_rnglists_base: /* DWARF5 */
1811*4d9fdb46SRobert Mustacchi         return DW_FORM_CLASS_RNGLISTSPTR;
1812*4d9fdb46SRobert Mustacchi     case DW_AT_macros:        /* DWARF5 */
1813*4d9fdb46SRobert Mustacchi         return DW_FORM_CLASS_MACROPTR;
1814*4d9fdb46SRobert Mustacchi     case DW_AT_loclists_base: /* DWARF5 */
1815*4d9fdb46SRobert Mustacchi         return DW_FORM_CLASS_LOCLISTSPTR;
1816*4d9fdb46SRobert Mustacchi     case DW_AT_addr_base:     /* DWARF5 */
1817*4d9fdb46SRobert Mustacchi         return DW_FORM_CLASS_ADDRPTR;
1818*4d9fdb46SRobert Mustacchi     case DW_AT_str_offsets_base: /* DWARF5 */
1819*4d9fdb46SRobert Mustacchi         return DW_FORM_CLASS_STROFFSETSPTR;
1820*4d9fdb46SRobert Mustacchi 
182107dc1947SRichard Lowe     case DW_AT_location:
182207dc1947SRichard Lowe     case DW_AT_string_length:
182307dc1947SRichard Lowe     case DW_AT_return_addr:
182407dc1947SRichard Lowe     case DW_AT_data_member_location:
182507dc1947SRichard Lowe     case DW_AT_frame_base:
182607dc1947SRichard Lowe     case DW_AT_segment:
182707dc1947SRichard Lowe     case DW_AT_static_link:
182807dc1947SRichard Lowe     case DW_AT_use_location:
1829*4d9fdb46SRobert Mustacchi     case DW_AT_vtable_elem_location: {
1830*4d9fdb46SRobert Mustacchi         if (dwversion <= 4) {
1831*4d9fdb46SRobert Mustacchi             return DW_FORM_CLASS_LOCLIST;
1832*4d9fdb46SRobert Mustacchi         }
1833*4d9fdb46SRobert Mustacchi         return DW_FORM_CLASS_LOCLISTPTR;
1834*4d9fdb46SRobert Mustacchi         }
183507dc1947SRichard Lowe     case DW_AT_sibling:
183607dc1947SRichard Lowe     case DW_AT_byte_size :
183707dc1947SRichard Lowe     case DW_AT_bit_offset :
183807dc1947SRichard Lowe     case DW_AT_bit_size :
183907dc1947SRichard Lowe     case DW_AT_discr :
184007dc1947SRichard Lowe     case DW_AT_import :
184107dc1947SRichard Lowe     case DW_AT_common_reference:
184207dc1947SRichard Lowe     case DW_AT_containing_type:
184307dc1947SRichard Lowe     case DW_AT_default_value:
184407dc1947SRichard Lowe     case DW_AT_lower_bound:
184507dc1947SRichard Lowe     case DW_AT_bit_stride:
184607dc1947SRichard Lowe     case DW_AT_upper_bound:
184707dc1947SRichard Lowe     case DW_AT_abstract_origin:
184807dc1947SRichard Lowe     case DW_AT_base_types:
184907dc1947SRichard Lowe     case DW_AT_count:
185007dc1947SRichard Lowe     case DW_AT_friend:
185107dc1947SRichard Lowe     case DW_AT_namelist_item:
185207dc1947SRichard Lowe     case DW_AT_priority:
185307dc1947SRichard Lowe     case DW_AT_specification:
185407dc1947SRichard Lowe     case DW_AT_type:
185507dc1947SRichard Lowe     case DW_AT_allocated:
185607dc1947SRichard Lowe     case DW_AT_associated:
185707dc1947SRichard Lowe     case DW_AT_byte_stride:
185807dc1947SRichard Lowe     case DW_AT_extension:
185907dc1947SRichard Lowe     case DW_AT_trampoline:
186007dc1947SRichard Lowe     case DW_AT_small:
186107dc1947SRichard Lowe     case DW_AT_object_pointer:
186207dc1947SRichard Lowe     case DW_AT_signature:
1863*4d9fdb46SRobert Mustacchi         return DW_FORM_CLASS_REFERENCE;
186407dc1947SRichard Lowe     case DW_AT_MIPS_fde: /* SGI/IRIX extension */
1865*4d9fdb46SRobert Mustacchi         return DW_FORM_CLASS_FRAMEPTR;
186607dc1947SRichard Lowe     }
186707dc1947SRichard Lowe     return DW_FORM_CLASS_UNKNOWN;
186807dc1947SRichard Lowe }
186907dc1947SRichard Lowe 
187007dc1947SRichard Lowe /* It takes 4 pieces of data (including the FORM)
187107dc1947SRichard Lowe    to accurately determine the form 'class' as documented
187207dc1947SRichard Lowe    in the DWARF spec. This is per DWARF4, but will work
187307dc1947SRichard Lowe    for DWARF2 or 3 as well.  */
1874*4d9fdb46SRobert Mustacchi enum Dwarf_Form_Class
dwarf_get_form_class(Dwarf_Half dwversion,Dwarf_Half attrnum,Dwarf_Half offset_size,Dwarf_Half form)1875*4d9fdb46SRobert Mustacchi dwarf_get_form_class(
187607dc1947SRichard Lowe     Dwarf_Half dwversion,
1877*4d9fdb46SRobert Mustacchi     Dwarf_Half attrnum,
1878*4d9fdb46SRobert Mustacchi     Dwarf_Half offset_size,
187907dc1947SRichard Lowe     Dwarf_Half form)
188007dc1947SRichard Lowe {
1881*4d9fdb46SRobert Mustacchi     switch (form) {
1882*4d9fdb46SRobert Mustacchi     case  DW_FORM_addr:  return DW_FORM_CLASS_ADDRESS;
188307dc1947SRichard Lowe     case  DW_FORM_data2:  return DW_FORM_CLASS_CONSTANT;
188407dc1947SRichard Lowe 
1885*4d9fdb46SRobert Mustacchi     case  DW_FORM_data4:
1886*4d9fdb46SRobert Mustacchi         if (dwversion <= 3 && offset_size == 4) {
1887*4d9fdb46SRobert Mustacchi             enum Dwarf_Form_Class class = dw_get_special_offset(attrnum,
1888*4d9fdb46SRobert Mustacchi                 dwversion);
1889*4d9fdb46SRobert Mustacchi             if (class != DW_FORM_CLASS_UNKNOWN) {
189007dc1947SRichard Lowe                 return class;
189107dc1947SRichard Lowe             }
189207dc1947SRichard Lowe         }
189307dc1947SRichard Lowe         return DW_FORM_CLASS_CONSTANT;
189407dc1947SRichard Lowe     case  DW_FORM_data8:
1895*4d9fdb46SRobert Mustacchi         if (dwversion <= 3 && offset_size == 8) {
1896*4d9fdb46SRobert Mustacchi             enum Dwarf_Form_Class class = dw_get_special_offset(attrnum,
1897*4d9fdb46SRobert Mustacchi                 dwversion);
1898*4d9fdb46SRobert Mustacchi             if (class != DW_FORM_CLASS_UNKNOWN) {
189907dc1947SRichard Lowe                 return class;
190007dc1947SRichard Lowe             }
190107dc1947SRichard Lowe         }
190207dc1947SRichard Lowe         return DW_FORM_CLASS_CONSTANT;
190307dc1947SRichard Lowe     case  DW_FORM_sec_offset:
190407dc1947SRichard Lowe         {
1905*4d9fdb46SRobert Mustacchi             enum Dwarf_Form_Class class = dw_get_special_offset(attrnum,
1906*4d9fdb46SRobert Mustacchi                 dwversion);
1907*4d9fdb46SRobert Mustacchi             if (class != DW_FORM_CLASS_UNKNOWN) {
190807dc1947SRichard Lowe                 return class;
190907dc1947SRichard Lowe             }
191007dc1947SRichard Lowe         }
191107dc1947SRichard Lowe         /* We do not know what this is. */
191207dc1947SRichard Lowe         break;
191307dc1947SRichard Lowe 
191407dc1947SRichard Lowe     case  DW_FORM_string: return DW_FORM_CLASS_STRING;
191507dc1947SRichard Lowe     case  DW_FORM_strp:   return DW_FORM_CLASS_STRING;
191607dc1947SRichard Lowe 
191707dc1947SRichard Lowe     case  DW_FORM_block:  return DW_FORM_CLASS_BLOCK;
191807dc1947SRichard Lowe     case  DW_FORM_block1: return DW_FORM_CLASS_BLOCK;
191907dc1947SRichard Lowe     case  DW_FORM_block2: return DW_FORM_CLASS_BLOCK;
192007dc1947SRichard Lowe     case  DW_FORM_block4: return DW_FORM_CLASS_BLOCK;
192107dc1947SRichard Lowe 
1922*4d9fdb46SRobert Mustacchi     case  DW_FORM_data16:  return DW_FORM_CLASS_CONSTANT;
192307dc1947SRichard Lowe     case  DW_FORM_data1:  return DW_FORM_CLASS_CONSTANT;
192407dc1947SRichard Lowe     case  DW_FORM_sdata:  return DW_FORM_CLASS_CONSTANT;
192507dc1947SRichard Lowe     case  DW_FORM_udata:  return DW_FORM_CLASS_CONSTANT;
192607dc1947SRichard Lowe 
192707dc1947SRichard Lowe     case  DW_FORM_ref_addr:    return DW_FORM_CLASS_REFERENCE;
192807dc1947SRichard Lowe     case  DW_FORM_ref1:        return DW_FORM_CLASS_REFERENCE;
192907dc1947SRichard Lowe     case  DW_FORM_ref2:        return DW_FORM_CLASS_REFERENCE;
193007dc1947SRichard Lowe     case  DW_FORM_ref4:        return DW_FORM_CLASS_REFERENCE;
193107dc1947SRichard Lowe     case  DW_FORM_ref8:        return DW_FORM_CLASS_REFERENCE;
193207dc1947SRichard Lowe     case  DW_FORM_ref_udata:   return DW_FORM_CLASS_REFERENCE;
193307dc1947SRichard Lowe     case  DW_FORM_ref_sig8:    return DW_FORM_CLASS_REFERENCE;
193407dc1947SRichard Lowe 
193507dc1947SRichard Lowe     case  DW_FORM_exprloc:      return DW_FORM_CLASS_EXPRLOC;
193607dc1947SRichard Lowe 
193707dc1947SRichard Lowe     case  DW_FORM_flag:         return DW_FORM_CLASS_FLAG;
193807dc1947SRichard Lowe     case  DW_FORM_flag_present: return DW_FORM_CLASS_FLAG;
193907dc1947SRichard Lowe 
1940*4d9fdb46SRobert Mustacchi     case  DW_FORM_addrx:           return DW_FORM_CLASS_ADDRESS; /* DWARF5 */
1941*4d9fdb46SRobert Mustacchi     case  DW_FORM_GNU_addr_index:  return DW_FORM_CLASS_ADDRESS;
1942*4d9fdb46SRobert Mustacchi     case  DW_FORM_strx:            return DW_FORM_CLASS_STRING;  /* DWARF5 */
1943*4d9fdb46SRobert Mustacchi     case  DW_FORM_GNU_str_index:   return DW_FORM_CLASS_STRING;
1944*4d9fdb46SRobert Mustacchi 
1945*4d9fdb46SRobert Mustacchi     case  DW_FORM_rnglistx:     return DW_FORM_CLASS_RNGLIST;    /* DWARF5 */
1946*4d9fdb46SRobert Mustacchi     case  DW_FORM_loclistx:     return DW_FORM_CLASS_LOCLIST;    /* DWARF5 */
1947*4d9fdb46SRobert Mustacchi 
1948*4d9fdb46SRobert Mustacchi     case  DW_FORM_GNU_ref_alt:  return DW_FORM_CLASS_REFERENCE;
1949*4d9fdb46SRobert Mustacchi     case  DW_FORM_GNU_strp_alt: return DW_FORM_CLASS_STRING;
1950*4d9fdb46SRobert Mustacchi     case  DW_FORM_strp_sup:     return DW_FORM_CLASS_STRING;    /* DWARF5 */
1951*4d9fdb46SRobert Mustacchi     case  DW_FORM_implicit_const: return DW_FORM_CLASS_CONSTANT; /* DWARF5 */
1952*4d9fdb46SRobert Mustacchi 
1953*4d9fdb46SRobert Mustacchi     case  DW_FORM_indirect:
1954*4d9fdb46SRobert Mustacchi     default:
195507dc1947SRichard Lowe         break;
195607dc1947SRichard Lowe     };
195707dc1947SRichard Lowe     return DW_FORM_CLASS_UNKNOWN;
195807dc1947SRichard Lowe }
195907dc1947SRichard Lowe 
1960*4d9fdb46SRobert Mustacchi /*  Given a DIE, figure out what the CU's DWARF version is
1961*4d9fdb46SRobert Mustacchi     and the size of an offset
1962*4d9fdb46SRobert Mustacchi     and return it through the *version pointer and return
1963*4d9fdb46SRobert Mustacchi     DW_DLV_OK.
1964*4d9fdb46SRobert Mustacchi 
1965*4d9fdb46SRobert Mustacchi     If we cannot find a CU,
1966*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR on error.
1967*4d9fdb46SRobert Mustacchi         In case of error no Dwarf_Debug was available,
1968*4d9fdb46SRobert Mustacchi         so setting a Dwarf_Error is somewhat futile.
1969*4d9fdb46SRobert Mustacchi     Never returns DW_DLV_NO_ENTRY.
1970*4d9fdb46SRobert Mustacchi */
1971*4d9fdb46SRobert Mustacchi int
dwarf_get_version_of_die(Dwarf_Die die,Dwarf_Half * version,Dwarf_Half * offset_size)1972*4d9fdb46SRobert Mustacchi dwarf_get_version_of_die(Dwarf_Die die,
1973*4d9fdb46SRobert Mustacchi     Dwarf_Half *version,
1974*4d9fdb46SRobert Mustacchi     Dwarf_Half *offset_size)
1975*4d9fdb46SRobert Mustacchi {
1976*4d9fdb46SRobert Mustacchi     Dwarf_CU_Context cucontext = 0;
1977*4d9fdb46SRobert Mustacchi     if (!die) {
1978*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1979*4d9fdb46SRobert Mustacchi     }
1980*4d9fdb46SRobert Mustacchi     cucontext = die->di_cu_context;
1981*4d9fdb46SRobert Mustacchi     if (!cucontext) {
1982*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1983*4d9fdb46SRobert Mustacchi     }
1984*4d9fdb46SRobert Mustacchi     *version = cucontext->cc_version_stamp;
1985*4d9fdb46SRobert Mustacchi     *offset_size = cucontext->cc_length_size;
1986*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1987*4d9fdb46SRobert Mustacchi }
1988*4d9fdb46SRobert Mustacchi 
1989*4d9fdb46SRobert Mustacchi Dwarf_Byte_Ptr
_dwarf_calculate_info_section_start_ptr(Dwarf_CU_Context context,Dwarf_Unsigned * section_len)1990*4d9fdb46SRobert Mustacchi _dwarf_calculate_info_section_start_ptr(Dwarf_CU_Context context,
1991*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *section_len)
1992*4d9fdb46SRobert Mustacchi {
1993*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
1994*4d9fdb46SRobert Mustacchi     Dwarf_Small *dataptr = 0;
1995*4d9fdb46SRobert Mustacchi     struct Dwarf_Section_s *sec = 0;
1996*4d9fdb46SRobert Mustacchi 
1997*4d9fdb46SRobert Mustacchi     dbg = context->cc_dbg;
1998*4d9fdb46SRobert Mustacchi     sec = context->cc_is_info? &dbg->de_debug_info: &dbg->de_debug_types;
1999*4d9fdb46SRobert Mustacchi     dataptr = sec->dss_data;
2000*4d9fdb46SRobert Mustacchi     *section_len = sec->dss_size;
2001*4d9fdb46SRobert Mustacchi     return dataptr;
2002*4d9fdb46SRobert Mustacchi }
2003*4d9fdb46SRobert Mustacchi 
2004*4d9fdb46SRobert Mustacchi Dwarf_Byte_Ptr
_dwarf_calculate_info_section_end_ptr(Dwarf_CU_Context context)2005*4d9fdb46SRobert Mustacchi _dwarf_calculate_info_section_end_ptr(Dwarf_CU_Context context)
2006*4d9fdb46SRobert Mustacchi {
2007*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
2008*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr info_end = 0;
2009*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr info_start = 0;
2010*4d9fdb46SRobert Mustacchi     Dwarf_Off off2 = 0;
2011*4d9fdb46SRobert Mustacchi     Dwarf_Small *dataptr = 0;
2012*4d9fdb46SRobert Mustacchi 
2013*4d9fdb46SRobert Mustacchi     dbg = context->cc_dbg;
2014*4d9fdb46SRobert Mustacchi     dataptr = context->cc_is_info? dbg->de_debug_info.dss_data:
2015*4d9fdb46SRobert Mustacchi         dbg->de_debug_types.dss_data;
2016*4d9fdb46SRobert Mustacchi     off2 = context->cc_debug_offset;
2017*4d9fdb46SRobert Mustacchi     info_start = dataptr + off2;
2018*4d9fdb46SRobert Mustacchi     info_end = info_start + context->cc_length +
2019*4d9fdb46SRobert Mustacchi         context->cc_length_size +
2020*4d9fdb46SRobert Mustacchi         context->cc_extension_size;
2021*4d9fdb46SRobert Mustacchi     return info_end;
2022*4d9fdb46SRobert Mustacchi }
2023*4d9fdb46SRobert Mustacchi Dwarf_Byte_Ptr
_dwarf_calculate_abbrev_section_end_ptr(Dwarf_CU_Context context)2024*4d9fdb46SRobert Mustacchi _dwarf_calculate_abbrev_section_end_ptr(Dwarf_CU_Context context)
2025*4d9fdb46SRobert Mustacchi {
2026*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = 0;
2027*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr abbrev_end = 0;
2028*4d9fdb46SRobert Mustacchi     Dwarf_Byte_Ptr abbrev_start = 0;
2029*4d9fdb46SRobert Mustacchi     struct Dwarf_Section_s *sec = 0;
2030*4d9fdb46SRobert Mustacchi 
2031*4d9fdb46SRobert Mustacchi     dbg = context->cc_dbg;
2032*4d9fdb46SRobert Mustacchi     sec = &dbg->de_debug_abbrev;
2033*4d9fdb46SRobert Mustacchi     abbrev_start = sec->dss_data;
2034*4d9fdb46SRobert Mustacchi     abbrev_end = abbrev_start + sec->dss_size;
2035*4d9fdb46SRobert Mustacchi     return abbrev_end;
2036*4d9fdb46SRobert Mustacchi }
2037