xref: /illumos-gate/usr/src/lib/libdwarf/common/pro_die.c (revision 4d9fdb46b215739778ebc12079842c9905586999)
1bc1f688bSRobert Mustacchi /*
2bc1f688bSRobert Mustacchi 
3bc1f688bSRobert Mustacchi   Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
4bc1f688bSRobert Mustacchi   Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
5*4d9fdb46SRobert Mustacchi   Portions Copyright 2011-2017 David Anderson.  All Rights Reserved.
6bc1f688bSRobert Mustacchi 
7*4d9fdb46SRobert Mustacchi   This program is free software; you can redistribute it
8*4d9fdb46SRobert Mustacchi   and/or modify it under the terms of version 2.1 of the
9*4d9fdb46SRobert Mustacchi   GNU Lesser General Public License as published by the Free
10*4d9fdb46SRobert Mustacchi   Software Foundation.
11bc1f688bSRobert Mustacchi 
12*4d9fdb46SRobert Mustacchi   This program is distributed in the hope that it would be
13*4d9fdb46SRobert Mustacchi   useful, but WITHOUT ANY WARRANTY; without even the implied
14*4d9fdb46SRobert Mustacchi   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15*4d9fdb46SRobert Mustacchi   PURPOSE.
16bc1f688bSRobert Mustacchi 
17*4d9fdb46SRobert Mustacchi   Further, this software is distributed without any warranty
18*4d9fdb46SRobert Mustacchi   that it is free of the rightful claim of any third person
19*4d9fdb46SRobert Mustacchi   regarding infringement or the like.  Any license provided
20*4d9fdb46SRobert Mustacchi   herein, whether implied or otherwise, applies only to this
21*4d9fdb46SRobert Mustacchi   software file.  Patent licenses, if any, provided herein
22*4d9fdb46SRobert Mustacchi   do not apply to combinations of this program with other
23*4d9fdb46SRobert Mustacchi   software, or any other product whatsoever.
24bc1f688bSRobert Mustacchi 
25*4d9fdb46SRobert Mustacchi   You should have received a copy of the GNU Lesser General
26*4d9fdb46SRobert Mustacchi   Public License along with this program; if not, write the
27*4d9fdb46SRobert Mustacchi   Free Software Foundation, Inc., 51 Franklin Street - Fifth
28*4d9fdb46SRobert Mustacchi   Floor, Boston MA 02110-1301, USA.
29bc1f688bSRobert Mustacchi 
30bc1f688bSRobert Mustacchi */
31bc1f688bSRobert Mustacchi 
32bc1f688bSRobert Mustacchi #include "config.h"
33bc1f688bSRobert Mustacchi #include "libdwarfdefs.h"
34bc1f688bSRobert Mustacchi #include <stdio.h>
35*4d9fdb46SRobert Mustacchi #ifdef HAVE_STDLIB_H
36*4d9fdb46SRobert Mustacchi #include <stdlib.h> /* for exit(), C89 malloc */
37*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDLIB_H */
38*4d9fdb46SRobert Mustacchi #ifdef HAVE_MALLOC_H
39*4d9fdb46SRobert Mustacchi /* Useful include for some Windows compilers. */
40*4d9fdb46SRobert Mustacchi #include <malloc.h>
41*4d9fdb46SRobert Mustacchi #endif /* HAVE_MALLOC_H */
42*4d9fdb46SRobert Mustacchi #ifdef HAVE_STDINT_H
43*4d9fdb46SRobert Mustacchi #include <stdint.h> /* For uintptr_t */
44*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDINT_H */
45bc1f688bSRobert Mustacchi #include <string.h>
46*4d9fdb46SRobert Mustacchi #include <stddef.h>
47bc1f688bSRobert Mustacchi #include "pro_incl.h"
48*4d9fdb46SRobert Mustacchi #include "dwarf.h"
49*4d9fdb46SRobert Mustacchi #include "libdwarf.h"
50*4d9fdb46SRobert Mustacchi #include "pro_opaque.h"
51*4d9fdb46SRobert Mustacchi #include "pro_error.h"
52*4d9fdb46SRobert Mustacchi #include "pro_util.h"
53*4d9fdb46SRobert Mustacchi #include "pro_alloc.h"
54bc1f688bSRobert Mustacchi #include "pro_die.h"
55*4d9fdb46SRobert Mustacchi #include "pro_section.h"
56*4d9fdb46SRobert Mustacchi #include "dwarf_tsearch.h"
57bc1f688bSRobert Mustacchi 
58bc1f688bSRobert Mustacchi #ifndef R_MIPS_NONE
59bc1f688bSRobert Mustacchi #define R_MIPS_NONE 0
60bc1f688bSRobert Mustacchi #endif
61bc1f688bSRobert Mustacchi 
62*4d9fdb46SRobert Mustacchi #define TRUE 1
63*4d9fdb46SRobert Mustacchi #define FALSE 0
64bc1f688bSRobert Mustacchi 
65*4d9fdb46SRobert Mustacchi /*  This function creates a new die.
66bc1f688bSRobert Mustacchi     tag: tag of the new die to be created
67bc1f688bSRobert Mustacchi     parent,child,left,right: specify neighbors of the new die. Only
68*4d9fdb46SRobert Mustacchi     one of these may be non-null */
69bc1f688bSRobert Mustacchi Dwarf_P_Die
dwarf_new_die(Dwarf_P_Debug dbg,Dwarf_Tag tag,Dwarf_P_Die parent,Dwarf_P_Die child,Dwarf_P_Die left,Dwarf_P_Die right,Dwarf_Error * error)70bc1f688bSRobert Mustacchi dwarf_new_die(Dwarf_P_Debug dbg,
71bc1f688bSRobert Mustacchi     Dwarf_Tag tag,
72bc1f688bSRobert Mustacchi     Dwarf_P_Die parent,
73bc1f688bSRobert Mustacchi     Dwarf_P_Die child,
74*4d9fdb46SRobert Mustacchi     Dwarf_P_Die left, Dwarf_P_Die right,
75*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
76*4d9fdb46SRobert Mustacchi {
77*4d9fdb46SRobert Mustacchi     Dwarf_P_Die created = 0;
78*4d9fdb46SRobert Mustacchi     int res = 0;
79*4d9fdb46SRobert Mustacchi 
80*4d9fdb46SRobert Mustacchi     res = dwarf_new_die_a(dbg,tag,parent,child,
81*4d9fdb46SRobert Mustacchi         left,right,&created,error);
82*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
83*4d9fdb46SRobert Mustacchi         return (Dwarf_P_Die)DW_DLV_BADADDR;
84*4d9fdb46SRobert Mustacchi     }
85*4d9fdb46SRobert Mustacchi     return created;
86*4d9fdb46SRobert Mustacchi }
87*4d9fdb46SRobert Mustacchi 
88*4d9fdb46SRobert Mustacchi /* New September 2016. Preferred as error checking
89*4d9fdb46SRobert Mustacchi    is easier, no need for ugly cast. */
90*4d9fdb46SRobert Mustacchi int
dwarf_new_die_a(Dwarf_P_Debug dbg,Dwarf_Tag tag,Dwarf_P_Die parent,Dwarf_P_Die child,Dwarf_P_Die left,Dwarf_P_Die right,Dwarf_P_Die * die_out,Dwarf_Error * error)91*4d9fdb46SRobert Mustacchi dwarf_new_die_a(Dwarf_P_Debug dbg,
92*4d9fdb46SRobert Mustacchi     Dwarf_Tag tag,
93*4d9fdb46SRobert Mustacchi     Dwarf_P_Die parent,
94*4d9fdb46SRobert Mustacchi     Dwarf_P_Die child,
95*4d9fdb46SRobert Mustacchi     Dwarf_P_Die left, Dwarf_P_Die right,
96*4d9fdb46SRobert Mustacchi     Dwarf_P_Die *die_out,
97*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
98bc1f688bSRobert Mustacchi {
99bc1f688bSRobert Mustacchi     Dwarf_P_Die ret_die = 0;
100*4d9fdb46SRobert Mustacchi     int res = 0;
101bc1f688bSRobert Mustacchi 
102*4d9fdb46SRobert Mustacchi     ret_die = (Dwarf_P_Die)
103bc1f688bSRobert Mustacchi         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Die_s));
104*4d9fdb46SRobert Mustacchi     if (ret_die == NULL) {
105bc1f688bSRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_ALLOC,
106*4d9fdb46SRobert Mustacchi             DW_DLV_ERROR);
107bc1f688bSRobert Mustacchi     }
108*4d9fdb46SRobert Mustacchi     ret_die->di_parent = NULL;
109*4d9fdb46SRobert Mustacchi     ret_die->di_left = NULL;
110*4d9fdb46SRobert Mustacchi     ret_die->di_right = NULL;
111*4d9fdb46SRobert Mustacchi     ret_die->di_child = NULL;
112*4d9fdb46SRobert Mustacchi     ret_die->di_last_child = NULL;
113*4d9fdb46SRobert Mustacchi     ret_die->di_tag = tag;
114*4d9fdb46SRobert Mustacchi     ret_die->di_dbg = dbg;
115*4d9fdb46SRobert Mustacchi     ret_die->di_marker = 0;
116*4d9fdb46SRobert Mustacchi     res = dwarf_die_link_a(ret_die, parent, child, left, right,
117*4d9fdb46SRobert Mustacchi         error);
118*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
119*4d9fdb46SRobert Mustacchi         _dwarf_p_dealloc(dbg,(Dwarf_Small *)ret_die);
120*4d9fdb46SRobert Mustacchi         ret_die = 0;
121*4d9fdb46SRobert Mustacchi     } else {
122*4d9fdb46SRobert Mustacchi         *die_out = ret_die;
123*4d9fdb46SRobert Mustacchi     }
124*4d9fdb46SRobert Mustacchi     return res;
125bc1f688bSRobert Mustacchi }
126bc1f688bSRobert Mustacchi 
127*4d9fdb46SRobert Mustacchi /*  This function links up a die to specified neighbors
128bc1f688bSRobert Mustacchi     parent,child,left,right: specify neighbors of the new die. Only
129bc1f688bSRobert Mustacchi     one of these may be non-null
130*4d9fdb46SRobert Mustacchi     This is the original version. Use dwarf_die_link_a()
131*4d9fdb46SRobert Mustacchi     instead as that function is easier to use (in checking for error).
132*4d9fdb46SRobert Mustacchi     */
133bc1f688bSRobert Mustacchi Dwarf_P_Die
dwarf_die_link(Dwarf_P_Die new_die,Dwarf_P_Die parent,Dwarf_P_Die child,Dwarf_P_Die left,Dwarf_P_Die right,Dwarf_Error * error)134bc1f688bSRobert Mustacchi dwarf_die_link(Dwarf_P_Die new_die,
135bc1f688bSRobert Mustacchi     Dwarf_P_Die parent,
136bc1f688bSRobert Mustacchi     Dwarf_P_Die child,
137bc1f688bSRobert Mustacchi     Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error)
138bc1f688bSRobert Mustacchi {
139*4d9fdb46SRobert Mustacchi     int res = 0;
140*4d9fdb46SRobert Mustacchi 
141*4d9fdb46SRobert Mustacchi     res = dwarf_die_link_a(new_die,parent,child,left,right,error);
142*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
143*4d9fdb46SRobert Mustacchi         return (Dwarf_P_Die)DW_DLV_BADADDR;
144*4d9fdb46SRobert Mustacchi     }
145*4d9fdb46SRobert Mustacchi     return new_die;
146*4d9fdb46SRobert Mustacchi }
147*4d9fdb46SRobert Mustacchi 
148*4d9fdb46SRobert Mustacchi /*  New September 2016.
149*4d9fdb46SRobert Mustacchi     Error return easier to deal with
150*4d9fdb46SRobert Mustacchi     than dwarf_die_link(). */
151*4d9fdb46SRobert Mustacchi int
dwarf_die_link_a(Dwarf_P_Die new_die,Dwarf_P_Die parent,Dwarf_P_Die child,Dwarf_P_Die left,Dwarf_P_Die right,Dwarf_Error * error)152*4d9fdb46SRobert Mustacchi dwarf_die_link_a(Dwarf_P_Die new_die,
153*4d9fdb46SRobert Mustacchi     Dwarf_P_Die parent,
154*4d9fdb46SRobert Mustacchi     Dwarf_P_Die child,
155*4d9fdb46SRobert Mustacchi     Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error)
156*4d9fdb46SRobert Mustacchi {
157bc1f688bSRobert Mustacchi     /* Count the # of non null neighbors. */
158bc1f688bSRobert Mustacchi     int n_nulls = 0;
159bc1f688bSRobert Mustacchi 
160bc1f688bSRobert Mustacchi     if (parent != NULL) {
161bc1f688bSRobert Mustacchi         n_nulls++;
162bc1f688bSRobert Mustacchi         if (new_die->di_parent != NULL) {
163bc1f688bSRobert Mustacchi             DWARF_P_DBG_ERROR(NULL, DW_DLE_LINK_LOOP,
164*4d9fdb46SRobert Mustacchi                 DW_DLV_ERROR);
165bc1f688bSRobert Mustacchi         }
166bc1f688bSRobert Mustacchi         new_die->di_parent = parent;
167bc1f688bSRobert Mustacchi         if (parent->di_child) {
168bc1f688bSRobert Mustacchi 
169bc1f688bSRobert Mustacchi             /*  di_last_child identifies the last sibling, the
170bc1f688bSRobert Mustacchi                 die we want to attach new_die to. */
171bc1f688bSRobert Mustacchi             /*  ASSERT: if di_child is set so is di_last_child. */
172bc1f688bSRobert Mustacchi             Dwarf_P_Die former_lastchild = parent->di_last_child;
173bc1f688bSRobert Mustacchi             parent->di_last_child = new_die;
174bc1f688bSRobert Mustacchi             /* Attach to  the new die to end of the sibling list. */
175bc1f688bSRobert Mustacchi             former_lastchild->di_right = new_die;
176bc1f688bSRobert Mustacchi             new_die->di_left = former_lastchild;
177bc1f688bSRobert Mustacchi         } else {
178bc1f688bSRobert Mustacchi             parent->di_child = new_die;
179bc1f688bSRobert Mustacchi             parent->di_last_child = new_die;
180bc1f688bSRobert Mustacchi         }
181bc1f688bSRobert Mustacchi     }
182bc1f688bSRobert Mustacchi     if (child != NULL) {
183bc1f688bSRobert Mustacchi         n_nulls++;
184bc1f688bSRobert Mustacchi         new_die->di_child = child;
185bc1f688bSRobert Mustacchi         new_die->di_last_child = child;
186bc1f688bSRobert Mustacchi         if (child->di_parent) {
187bc1f688bSRobert Mustacchi             DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS,
188*4d9fdb46SRobert Mustacchi                 DW_DLV_ERROR);
189bc1f688bSRobert Mustacchi         } else {
190bc1f688bSRobert Mustacchi             child->di_parent = new_die;
191bc1f688bSRobert Mustacchi         }
192bc1f688bSRobert Mustacchi     }
193bc1f688bSRobert Mustacchi     if (left != NULL) {
194bc1f688bSRobert Mustacchi         n_nulls++;
195bc1f688bSRobert Mustacchi         new_die->di_left = left;
196bc1f688bSRobert Mustacchi         if (left->di_right) {
197bc1f688bSRobert Mustacchi             /*  There's already a right sibling of left,
198bc1f688bSRobert Mustacchi                 insert the new die in the list. */
199bc1f688bSRobert Mustacchi             new_die->di_right = left->di_right;
200bc1f688bSRobert Mustacchi             left->di_right->di_left = new_die;
201bc1f688bSRobert Mustacchi         }
202bc1f688bSRobert Mustacchi         left->di_right = new_die;
203bc1f688bSRobert Mustacchi         if (new_die->di_parent) {
204bc1f688bSRobert Mustacchi             DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS,
205*4d9fdb46SRobert Mustacchi                 DW_DLV_ERROR);
206bc1f688bSRobert Mustacchi         } else {
207bc1f688bSRobert Mustacchi             new_die->di_parent = left->di_parent;
208bc1f688bSRobert Mustacchi         }
209bc1f688bSRobert Mustacchi     }
210bc1f688bSRobert Mustacchi     if (right != NULL) {
211bc1f688bSRobert Mustacchi         n_nulls++;
212bc1f688bSRobert Mustacchi         new_die->di_right = right;
213bc1f688bSRobert Mustacchi         if (right->di_left) {
214bc1f688bSRobert Mustacchi             /*  There is already a left sibling of the right die,
215bc1f688bSRobert Mustacchi                 insert the new die in the list.  */
216bc1f688bSRobert Mustacchi             new_die->di_left = right->di_left;
217bc1f688bSRobert Mustacchi             right->di_left->di_right = new_die;
218bc1f688bSRobert Mustacchi         }
219bc1f688bSRobert Mustacchi         right->di_left = new_die;
220bc1f688bSRobert Mustacchi         if (new_die->di_parent) {
221bc1f688bSRobert Mustacchi             DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS,
222*4d9fdb46SRobert Mustacchi                 DW_DLV_ERROR);
223bc1f688bSRobert Mustacchi         } else {
224bc1f688bSRobert Mustacchi             new_die->di_parent = right->di_parent;
225bc1f688bSRobert Mustacchi         }
226bc1f688bSRobert Mustacchi     }
227bc1f688bSRobert Mustacchi     if (n_nulls > 1) {
228bc1f688bSRobert Mustacchi         /* Multiple neighbors! error! */
229bc1f688bSRobert Mustacchi         DWARF_P_DBG_ERROR(NULL, DW_DLE_EXTRA_NEIGHBORS,
230*4d9fdb46SRobert Mustacchi             DW_DLV_ERROR);
231bc1f688bSRobert Mustacchi     }
232*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
233bc1f688bSRobert Mustacchi }
234bc1f688bSRobert Mustacchi 
235bc1f688bSRobert Mustacchi Dwarf_Unsigned
dwarf_add_die_marker(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_Unsigned marker,Dwarf_Error * error)236bc1f688bSRobert Mustacchi dwarf_add_die_marker(Dwarf_P_Debug dbg,
237bc1f688bSRobert Mustacchi     Dwarf_P_Die die,
238bc1f688bSRobert Mustacchi     Dwarf_Unsigned marker,
239*4d9fdb46SRobert Mustacchi     Dwarf_Error * error) {
240bc1f688bSRobert Mustacchi     if (die == NULL) {
241bc1f688bSRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT);
242bc1f688bSRobert Mustacchi     }
243bc1f688bSRobert Mustacchi     die->di_marker = marker;
244bc1f688bSRobert Mustacchi     return 0;
245bc1f688bSRobert Mustacchi }
246*4d9fdb46SRobert Mustacchi int
dwarf_add_die_marker_a(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_Unsigned marker,Dwarf_Error * error)247*4d9fdb46SRobert Mustacchi dwarf_add_die_marker_a(Dwarf_P_Debug dbg,
248*4d9fdb46SRobert Mustacchi     Dwarf_P_Die die,
249*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned marker,
250*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
251*4d9fdb46SRobert Mustacchi {
252*4d9fdb46SRobert Mustacchi     if (die == NULL) {
253*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL,
254*4d9fdb46SRobert Mustacchi             DW_DLV_ERROR);
255*4d9fdb46SRobert Mustacchi     }
256*4d9fdb46SRobert Mustacchi     die->di_marker = marker;
257*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
258*4d9fdb46SRobert Mustacchi }
259bc1f688bSRobert Mustacchi 
260bc1f688bSRobert Mustacchi 
261bc1f688bSRobert Mustacchi Dwarf_Unsigned
dwarf_get_die_marker(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_Unsigned * marker,Dwarf_Error * error)262bc1f688bSRobert Mustacchi dwarf_get_die_marker(Dwarf_P_Debug dbg,
263bc1f688bSRobert Mustacchi     Dwarf_P_Die die,
264bc1f688bSRobert Mustacchi     Dwarf_Unsigned * marker,
265bc1f688bSRobert Mustacchi     Dwarf_Error * error)
266bc1f688bSRobert Mustacchi {
267bc1f688bSRobert Mustacchi     if (die == NULL) {
268*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL,
269*4d9fdb46SRobert Mustacchi             DW_DLV_NOCOUNT);
270bc1f688bSRobert Mustacchi     }
271bc1f688bSRobert Mustacchi     *marker = die->di_marker;
272bc1f688bSRobert Mustacchi     return 0;
273bc1f688bSRobert Mustacchi }
274*4d9fdb46SRobert Mustacchi int
dwarf_get_die_marker_a(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_Unsigned * marker,Dwarf_Error * error)275*4d9fdb46SRobert Mustacchi dwarf_get_die_marker_a(Dwarf_P_Debug dbg,
276*4d9fdb46SRobert Mustacchi     Dwarf_P_Die die,
277*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * marker,
278*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
279*4d9fdb46SRobert Mustacchi {
280*4d9fdb46SRobert Mustacchi     if (die == NULL) {
281*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL,
282*4d9fdb46SRobert Mustacchi             DW_DLV_ERROR);
283*4d9fdb46SRobert Mustacchi     }
284*4d9fdb46SRobert Mustacchi     *marker = die->di_marker;
285*4d9fdb46SRobert Mustacchi     return DW_DLV_ERROR;
286*4d9fdb46SRobert Mustacchi }
287bc1f688bSRobert Mustacchi 
288bc1f688bSRobert Mustacchi 
289*4d9fdb46SRobert Mustacchi /*---------------------------------------------------------
290*4d9fdb46SRobert Mustacchi     This function adds a die to dbg struct. It should
291*4d9fdb46SRobert Mustacchi     be called using the root of all the dies.
292*4d9fdb46SRobert Mustacchi ---------------------------------------------------------*/
293*4d9fdb46SRobert Mustacchi /*  Original form of this call..
294*4d9fdb46SRobert Mustacchi     dwarf_add_die_to_debug_a() is preferred now. */
295bc1f688bSRobert Mustacchi Dwarf_Unsigned
dwarf_add_die_to_debug(Dwarf_P_Debug dbg,Dwarf_P_Die first_die,Dwarf_Error * error)296bc1f688bSRobert Mustacchi dwarf_add_die_to_debug(Dwarf_P_Debug dbg,
297bc1f688bSRobert Mustacchi     Dwarf_P_Die first_die, Dwarf_Error * error)
298bc1f688bSRobert Mustacchi {
299*4d9fdb46SRobert Mustacchi     int res = dwarf_add_die_to_debug_a(dbg,first_die,error);
300*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_ERROR) {
301*4d9fdb46SRobert Mustacchi         return DW_DLV_NOCOUNT;
302*4d9fdb46SRobert Mustacchi     }
303*4d9fdb46SRobert Mustacchi     return 0;
304*4d9fdb46SRobert Mustacchi }
305*4d9fdb46SRobert Mustacchi 
306*4d9fdb46SRobert Mustacchi /*  New September 2016. The new and preferred form. */
307*4d9fdb46SRobert Mustacchi int
dwarf_add_die_to_debug_a(Dwarf_P_Debug dbg,Dwarf_P_Die first_die,Dwarf_Error * error)308*4d9fdb46SRobert Mustacchi dwarf_add_die_to_debug_a(Dwarf_P_Debug dbg,
309*4d9fdb46SRobert Mustacchi     Dwarf_P_Die first_die, Dwarf_Error * error)
310*4d9fdb46SRobert Mustacchi {
311bc1f688bSRobert Mustacchi     if (first_die == NULL) {
312*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL,
313*4d9fdb46SRobert Mustacchi             DW_DLV_ERROR);
314bc1f688bSRobert Mustacchi     }
315bc1f688bSRobert Mustacchi     if (first_die->di_tag != DW_TAG_compile_unit) {
316*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_TAG,
317*4d9fdb46SRobert Mustacchi             DW_DLV_ERROR);
318bc1f688bSRobert Mustacchi     }
319bc1f688bSRobert Mustacchi     dbg->de_dies = first_die;
320*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
321bc1f688bSRobert Mustacchi }
322bc1f688bSRobert Mustacchi 
323bc1f688bSRobert Mustacchi int
_dwarf_pro_add_AT_stmt_list(Dwarf_P_Debug dbg,Dwarf_P_Die first_die,Dwarf_Error * error)324bc1f688bSRobert Mustacchi _dwarf_pro_add_AT_stmt_list(Dwarf_P_Debug dbg,
325bc1f688bSRobert Mustacchi     Dwarf_P_Die first_die, Dwarf_Error * error)
326bc1f688bSRobert Mustacchi {
327bc1f688bSRobert Mustacchi     Dwarf_P_Attribute new_attr;
328*4d9fdb46SRobert Mustacchi     int uwordb_size = dbg->de_dwarf_offset_size;
329bc1f688bSRobert Mustacchi 
330bc1f688bSRobert Mustacchi     /* Add AT_stmt_list attribute */
331bc1f688bSRobert Mustacchi     new_attr = (Dwarf_P_Attribute)
332*4d9fdb46SRobert Mustacchi         _dwarf_p_get_alloc(dbg,
333*4d9fdb46SRobert Mustacchi             sizeof(struct Dwarf_P_Attribute_s));
334bc1f688bSRobert Mustacchi     if (new_attr == NULL) {
335*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC,
336*4d9fdb46SRobert Mustacchi             DW_DLV_ERROR);
337bc1f688bSRobert Mustacchi     }
338bc1f688bSRobert Mustacchi 
339bc1f688bSRobert Mustacchi     new_attr->ar_attribute = DW_AT_stmt_list;
340*4d9fdb46SRobert Mustacchi     new_attr->ar_attribute_form =
341*4d9fdb46SRobert Mustacchi         dbg->de_ar_data_attribute_form;
342bc1f688bSRobert Mustacchi     new_attr->ar_rel_type = dbg->de_offset_reloc;
343bc1f688bSRobert Mustacchi 
344bc1f688bSRobert Mustacchi     new_attr->ar_nbytes = uwordb_size;
345bc1f688bSRobert Mustacchi     new_attr->ar_next = NULL;
346bc1f688bSRobert Mustacchi     new_attr->ar_reloc_len = uwordb_size;
347bc1f688bSRobert Mustacchi     new_attr->ar_data = (char *)
348bc1f688bSRobert Mustacchi         _dwarf_p_get_alloc(dbg, uwordb_size);
349bc1f688bSRobert Mustacchi     if (new_attr->ar_data == NULL) {
350*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(NULL,DW_DLE_ADDR_ALLOC,
351*4d9fdb46SRobert Mustacchi             DW_DLV_ERROR);
352bc1f688bSRobert Mustacchi     }
353bc1f688bSRobert Mustacchi     {
354bc1f688bSRobert Mustacchi         Dwarf_Unsigned du = 0;
355bc1f688bSRobert Mustacchi 
356bc1f688bSRobert Mustacchi         WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data,
357bc1f688bSRobert Mustacchi             (const void *) &du, sizeof(du), uwordb_size);
358bc1f688bSRobert Mustacchi     }
359bc1f688bSRobert Mustacchi 
360bc1f688bSRobert Mustacchi     _dwarf_pro_add_at_to_die(first_die, new_attr);
361*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
362bc1f688bSRobert Mustacchi }
363bc1f688bSRobert Mustacchi 
364*4d9fdb46SRobert Mustacchi static int
_dwarf_debug_str_compare_func(const void * l,const void * r)365*4d9fdb46SRobert Mustacchi _dwarf_debug_str_compare_func(const void *l,const void *r)
366bc1f688bSRobert Mustacchi {
367*4d9fdb46SRobert Mustacchi     const struct Dwarf_P_debug_str_entry_s*el = l;
368*4d9fdb46SRobert Mustacchi     const struct Dwarf_P_debug_str_entry_s*er = r;
369*4d9fdb46SRobert Mustacchi     char *lname =  0;
370*4d9fdb46SRobert Mustacchi     char *rname =  0;
371*4d9fdb46SRobert Mustacchi     int ir = 0;
372*4d9fdb46SRobert Mustacchi 
373*4d9fdb46SRobert Mustacchi     if (el->dse_has_table_offset) {
374*4d9fdb46SRobert Mustacchi         /*  When set the name is in the debug_str table. */
375*4d9fdb46SRobert Mustacchi         /*  ASSERT: dse_dbg->de_debug_str->ds_data
376*4d9fdb46SRobert Mustacchi             is non-zero.
377*4d9fdb46SRobert Mustacchi             ASSERT: dse_name NULL. */
378*4d9fdb46SRobert Mustacchi         lname = el->dse_dbg->de_debug_str->ds_data +
379*4d9fdb46SRobert Mustacchi             el->dse_table_offset;
380*4d9fdb46SRobert Mustacchi     } else {
381*4d9fdb46SRobert Mustacchi         /*  ASSERT: dse_name non-null */
382*4d9fdb46SRobert Mustacchi         lname = el->dse_name;
383*4d9fdb46SRobert Mustacchi     }
384*4d9fdb46SRobert Mustacchi     if (er->dse_has_table_offset) {
385*4d9fdb46SRobert Mustacchi         /*  When set the name is in the debug_str table. */
386*4d9fdb46SRobert Mustacchi         /*  ASSERT: dse_dbg->de_debug_str->ds_data
387*4d9fdb46SRobert Mustacchi             is non-zero.
388*4d9fdb46SRobert Mustacchi             ASSERT: dse_name NULL. */
389*4d9fdb46SRobert Mustacchi         rname = er->dse_dbg->de_debug_str->ds_data +
390*4d9fdb46SRobert Mustacchi             er->dse_table_offset;
391*4d9fdb46SRobert Mustacchi     } else {
392*4d9fdb46SRobert Mustacchi         /*  ASSERT: dse_name non-null */
393*4d9fdb46SRobert Mustacchi         rname = er->dse_name;
394*4d9fdb46SRobert Mustacchi     }
395*4d9fdb46SRobert Mustacchi     ir = strcmp(lname,rname);
396*4d9fdb46SRobert Mustacchi     return ir;
397*4d9fdb46SRobert Mustacchi }
398*4d9fdb46SRobert Mustacchi 
399*4d9fdb46SRobert Mustacchi static  void
debug_str_entry_free_func(void * m)400*4d9fdb46SRobert Mustacchi debug_str_entry_free_func(void *m)
401*4d9fdb46SRobert Mustacchi {
402*4d9fdb46SRobert Mustacchi     free(m);
403*4d9fdb46SRobert Mustacchi }
404*4d9fdb46SRobert Mustacchi 
405*4d9fdb46SRobert Mustacchi static int
make_debug_str_entry(Dwarf_P_Debug dbg,struct Dwarf_P_debug_str_entry_s ** mt_out,char * name,unsigned slen,unsigned char has_offset,Dwarf_Unsigned offset_in_table,Dwarf_Error * error)406*4d9fdb46SRobert Mustacchi make_debug_str_entry(Dwarf_P_Debug dbg,
407*4d9fdb46SRobert Mustacchi     struct Dwarf_P_debug_str_entry_s **mt_out,
408*4d9fdb46SRobert Mustacchi     char *name,
409*4d9fdb46SRobert Mustacchi     unsigned slen,
410*4d9fdb46SRobert Mustacchi     unsigned char has_offset,
411*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset_in_table,
412*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
413*4d9fdb46SRobert Mustacchi {
414*4d9fdb46SRobert Mustacchi     struct Dwarf_P_debug_str_entry_s *mt =
415*4d9fdb46SRobert Mustacchi         (struct  Dwarf_P_debug_str_entry_s *)calloc(
416*4d9fdb46SRobert Mustacchi         sizeof(struct Dwarf_P_debug_str_entry_s),1);
417*4d9fdb46SRobert Mustacchi     if (!mt) {
418*4d9fdb46SRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
419*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
420*4d9fdb46SRobert Mustacchi     }
421*4d9fdb46SRobert Mustacchi 
422*4d9fdb46SRobert Mustacchi     mt->dse_slen = slen;
423*4d9fdb46SRobert Mustacchi     mt->dse_table_offset = 0;
424*4d9fdb46SRobert Mustacchi     mt->dse_dbg = dbg;
425*4d9fdb46SRobert Mustacchi     if (has_offset) {
426*4d9fdb46SRobert Mustacchi         mt->dse_has_table_offset = TRUE;
427*4d9fdb46SRobert Mustacchi         mt->dse_table_offset = offset_in_table;
428*4d9fdb46SRobert Mustacchi         mt->dse_name = 0;
429*4d9fdb46SRobert Mustacchi     } else {
430*4d9fdb46SRobert Mustacchi         /* ASSERT: name != NULL */
431*4d9fdb46SRobert Mustacchi         mt->dse_has_table_offset = FALSE;
432*4d9fdb46SRobert Mustacchi         /* We just set dse_table_offset so it has
433*4d9fdb46SRobert Mustacchi             a known value, though nothing should refer
434*4d9fdb46SRobert Mustacchi             to dse_table_offset because
435*4d9fdb46SRobert Mustacchi             dse_has_table_offset is FALSE.*/
436*4d9fdb46SRobert Mustacchi         mt->dse_table_offset = 0;
437*4d9fdb46SRobert Mustacchi         mt->dse_name = name;
438*4d9fdb46SRobert Mustacchi     }
439*4d9fdb46SRobert Mustacchi     *mt_out = mt;
440*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
441*4d9fdb46SRobert Mustacchi }
442*4d9fdb46SRobert Mustacchi #define STRTAB_BASE_ALLOC_SIZE 2048
443*4d9fdb46SRobert Mustacchi static int
insert_debug_str_data_string(Dwarf_P_Debug dbg,char * name,unsigned slen,Dwarf_P_Section_Data sd,Dwarf_Unsigned * adding_at_offset,Dwarf_Error * error)444*4d9fdb46SRobert Mustacchi insert_debug_str_data_string(Dwarf_P_Debug dbg,
445*4d9fdb46SRobert Mustacchi     char *name,
446*4d9fdb46SRobert Mustacchi     unsigned slen,
447*4d9fdb46SRobert Mustacchi     Dwarf_P_Section_Data sd,
448*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned*adding_at_offset,
449*4d9fdb46SRobert Mustacchi     Dwarf_Error *  error)
450*4d9fdb46SRobert Mustacchi {
451*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned current_offset = 0;
452*4d9fdb46SRobert Mustacchi 
453*4d9fdb46SRobert Mustacchi     if (!sd->ds_data) {
454*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned initial_alloc = STRTAB_BASE_ALLOC_SIZE;
455*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned base_insert_offset = 0;
456*4d9fdb46SRobert Mustacchi 
457*4d9fdb46SRobert Mustacchi         /*  Inserting our first string.
458*4d9fdb46SRobert Mustacchi             The GNU linker refuses to commonize strings
459*4d9fdb46SRobert Mustacchi             if the section starts with a NUL byte,
460*4d9fdb46SRobert Mustacchi             so start with real string, using a
461*4d9fdb46SRobert Mustacchi             base_insert_offset of 0. */
462*4d9fdb46SRobert Mustacchi         if ( (slen + base_insert_offset) >= STRTAB_BASE_ALLOC_SIZE) {
463*4d9fdb46SRobert Mustacchi             initial_alloc = slen *2+ base_insert_offset;
464*4d9fdb46SRobert Mustacchi         }
465*4d9fdb46SRobert Mustacchi         if (initial_alloc < slen) {
466*4d9fdb46SRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_SIZE_WRAPAROUND);
467*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
468*4d9fdb46SRobert Mustacchi         }
469*4d9fdb46SRobert Mustacchi         sd->ds_data = calloc(1,initial_alloc);
470*4d9fdb46SRobert Mustacchi         if (!sd->ds_data) {
471*4d9fdb46SRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
472*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
473*4d9fdb46SRobert Mustacchi         }
474*4d9fdb46SRobert Mustacchi         sd->ds_orig_alloc = initial_alloc;
475*4d9fdb46SRobert Mustacchi         *adding_at_offset = base_insert_offset;
476*4d9fdb46SRobert Mustacchi         sd->ds_nbytes = slen + base_insert_offset;
477*4d9fdb46SRobert Mustacchi         strcpy(sd->ds_data+base_insert_offset,name);
478*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
479*4d9fdb46SRobert Mustacchi     }
480*4d9fdb46SRobert Mustacchi     current_offset = sd->ds_nbytes;
481*4d9fdb46SRobert Mustacchi     if ( (current_offset + slen) >= sd->ds_orig_alloc) {
482*4d9fdb46SRobert Mustacchi         unsigned updated_length = sd->ds_orig_alloc;
483*4d9fdb46SRobert Mustacchi         char *newbuf = 0;
484*4d9fdb46SRobert Mustacchi         if (slen > updated_length) {
485*4d9fdb46SRobert Mustacchi             /*  Very long string passed in. */
486*4d9fdb46SRobert Mustacchi             updated_length = slen *2;
487*4d9fdb46SRobert Mustacchi         } else {
488*4d9fdb46SRobert Mustacchi             updated_length = updated_length *2;
489*4d9fdb46SRobert Mustacchi         }
490*4d9fdb46SRobert Mustacchi         if (updated_length < sd->ds_orig_alloc) {
491*4d9fdb46SRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_SIZE_WRAPAROUND);
492*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
493*4d9fdb46SRobert Mustacchi         }
494*4d9fdb46SRobert Mustacchi         newbuf = calloc(1,updated_length);
495*4d9fdb46SRobert Mustacchi         if (!newbuf) {
496*4d9fdb46SRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
497*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
498*4d9fdb46SRobert Mustacchi         }
499*4d9fdb46SRobert Mustacchi         memcpy(newbuf,sd->ds_data,sd->ds_nbytes);
500*4d9fdb46SRobert Mustacchi         free(sd->ds_data);
501*4d9fdb46SRobert Mustacchi         sd->ds_data = newbuf;
502*4d9fdb46SRobert Mustacchi         sd->ds_orig_alloc = updated_length;
503*4d9fdb46SRobert Mustacchi         newbuf = 0;
504*4d9fdb46SRobert Mustacchi     }
505*4d9fdb46SRobert Mustacchi     strcpy(sd->ds_data + current_offset,name);
506*4d9fdb46SRobert Mustacchi     sd->ds_nbytes += slen;
507*4d9fdb46SRobert Mustacchi     *adding_at_offset = current_offset;
508*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
509*4d9fdb46SRobert Mustacchi }
510*4d9fdb46SRobert Mustacchi 
511*4d9fdb46SRobert Mustacchi /*  Find the string offset using the hash table,
512*4d9fdb46SRobert Mustacchi     and if not known, insert the new string. */
513*4d9fdb46SRobert Mustacchi int
_dwarf_insert_or_find_in_debug_str(Dwarf_P_Debug dbg,char * name,enum dwarf_which_hash whash,unsigned slen,Dwarf_Unsigned * offset_in_debug_str,Dwarf_Error * error)514*4d9fdb46SRobert Mustacchi _dwarf_insert_or_find_in_debug_str(Dwarf_P_Debug dbg,
515*4d9fdb46SRobert Mustacchi     char *name,
516*4d9fdb46SRobert Mustacchi     enum dwarf_which_hash whash,
517*4d9fdb46SRobert Mustacchi     unsigned slen, /* includes space for trailing NUL */
518*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *offset_in_debug_str,
519*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
520*4d9fdb46SRobert Mustacchi {
521*4d9fdb46SRobert Mustacchi     struct Dwarf_P_debug_str_entry_s *mt = 0;
522*4d9fdb46SRobert Mustacchi     struct Dwarf_P_debug_str_entry_s *mt2 = 0;
523*4d9fdb46SRobert Mustacchi     struct Dwarf_P_debug_str_entry_s *retval = 0;
524*4d9fdb46SRobert Mustacchi     struct Dwarf_P_debug_str_entry_s *re = 0;
525*4d9fdb46SRobert Mustacchi     int res = 0;
526*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned adding_at_offset = 0;
527*4d9fdb46SRobert Mustacchi     void **hashtab = 0;
528*4d9fdb46SRobert Mustacchi     Dwarf_P_Section_Data sd = 0;
529*4d9fdb46SRobert Mustacchi     struct Dwarf_P_Str_stats_s * stats =  0;
530*4d9fdb46SRobert Mustacchi 
531*4d9fdb46SRobert Mustacchi     switch (whash) {
532*4d9fdb46SRobert Mustacchi     case _dwarf_hash_debug_str:
533*4d9fdb46SRobert Mustacchi         hashtab =  &dbg->de_debug_str_hashtab;
534*4d9fdb46SRobert Mustacchi         sd =  dbg->de_debug_str;
535*4d9fdb46SRobert Mustacchi         stats = &dbg->de_stats.ps_strp;
536*4d9fdb46SRobert Mustacchi         break;
537*4d9fdb46SRobert Mustacchi     case _dwarf_hash_debug_line_str:
538*4d9fdb46SRobert Mustacchi         hashtab =  &dbg->de_debug_line_str_hashtab;
539*4d9fdb46SRobert Mustacchi         sd =  dbg->de_debug_line_str;
540*4d9fdb46SRobert Mustacchi         stats = &dbg->de_stats.ps_line_strp;
541*4d9fdb46SRobert Mustacchi         break;
542*4d9fdb46SRobert Mustacchi     case _dwarf_hash_debug_str_sup:
543*4d9fdb46SRobert Mustacchi     default:
544*4d9fdb46SRobert Mustacchi         /* Not supported or unknown. */
545*4d9fdb46SRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_STRING_HASHTAB_IDENTITY_ERROR);
546*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
547*4d9fdb46SRobert Mustacchi     }
548*4d9fdb46SRobert Mustacchi     res = make_debug_str_entry(dbg,&mt,name,
549*4d9fdb46SRobert Mustacchi         slen,FALSE, 0, error);
550*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
551*4d9fdb46SRobert Mustacchi         return res;
552*4d9fdb46SRobert Mustacchi     }
553*4d9fdb46SRobert Mustacchi     /*  We do a find as we do not want the string pointer passed in
554*4d9fdb46SRobert Mustacchi         to be in the hash table, we want a pointer into the
555*4d9fdb46SRobert Mustacchi         debug_str table in the hash table. */
556*4d9fdb46SRobert Mustacchi     retval = dwarf_tfind(mt,(void *const*)hashtab,
557*4d9fdb46SRobert Mustacchi         _dwarf_debug_str_compare_func);
558*4d9fdb46SRobert Mustacchi     if (retval) {
559*4d9fdb46SRobert Mustacchi 
560*4d9fdb46SRobert Mustacchi         stats->ps_strp_reused_count++;
561*4d9fdb46SRobert Mustacchi         stats->ps_strp_reused_len += slen;
562*4d9fdb46SRobert Mustacchi 
563*4d9fdb46SRobert Mustacchi         re = *(struct Dwarf_P_debug_str_entry_s **)retval;
564*4d9fdb46SRobert Mustacchi         *offset_in_debug_str = re->dse_table_offset;
565*4d9fdb46SRobert Mustacchi         debug_str_entry_free_func(mt);
566*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
567*4d9fdb46SRobert Mustacchi     }
568*4d9fdb46SRobert Mustacchi 
569*4d9fdb46SRobert Mustacchi     /*  We know the string is not in .debug_str data yet.
570*4d9fdb46SRobert Mustacchi         Insert it into the big string table and get that
571*4d9fdb46SRobert Mustacchi         offset. */
572*4d9fdb46SRobert Mustacchi 
573*4d9fdb46SRobert Mustacchi     debug_str_entry_free_func(mt);
574*4d9fdb46SRobert Mustacchi     mt = 0;
575*4d9fdb46SRobert Mustacchi     res = insert_debug_str_data_string(dbg,name,slen,sd,
576*4d9fdb46SRobert Mustacchi         &adding_at_offset, error);
577*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
578*4d9fdb46SRobert Mustacchi         return res;
579*4d9fdb46SRobert Mustacchi     }
580*4d9fdb46SRobert Mustacchi 
581*4d9fdb46SRobert Mustacchi     /*  The name is in the string table itself, so use that pointer
582*4d9fdb46SRobert Mustacchi         and offset for the string. */
583*4d9fdb46SRobert Mustacchi     res = make_debug_str_entry(dbg,&mt2, 0,
584*4d9fdb46SRobert Mustacchi         slen,TRUE,adding_at_offset,error);
585*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
586*4d9fdb46SRobert Mustacchi         return res;
587*4d9fdb46SRobert Mustacchi     }
588*4d9fdb46SRobert Mustacchi     retval = dwarf_tsearch(mt2,
589*4d9fdb46SRobert Mustacchi         (void *)hashtab,
590*4d9fdb46SRobert Mustacchi         _dwarf_debug_str_compare_func);
591*4d9fdb46SRobert Mustacchi     if (!retval) {
592*4d9fdb46SRobert Mustacchi         debug_str_entry_free_func(mt2);
593*4d9fdb46SRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
594*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
595*4d9fdb46SRobert Mustacchi     }
596*4d9fdb46SRobert Mustacchi 
597*4d9fdb46SRobert Mustacchi     /* This indirection is one of the surprises in using tsearch... */
598*4d9fdb46SRobert Mustacchi     re = *(struct Dwarf_P_debug_str_entry_s **)retval;
599*4d9fdb46SRobert Mustacchi     if (re != mt2) {
600*4d9fdb46SRobert Mustacchi         debug_str_entry_free_func(mt2);
601*4d9fdb46SRobert Mustacchi         /*  Found it in hash tab: illogical as the tsearch_find should
602*4d9fdb46SRobert Mustacchi             have found it. */
603*4d9fdb46SRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ILLOGICAL_TSEARCH);
604*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
605*4d9fdb46SRobert Mustacchi     }
606*4d9fdb46SRobert Mustacchi     stats->ps_strp_count_debug_str++;
607*4d9fdb46SRobert Mustacchi     stats->ps_strp_len_debug_str += slen;
608*4d9fdb46SRobert Mustacchi     /* we added it to hash, do not free mt2 (which == re). */
609*4d9fdb46SRobert Mustacchi     *offset_in_debug_str = re->dse_table_offset;
610*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
611*4d9fdb46SRobert Mustacchi }
612*4d9fdb46SRobert Mustacchi 
613*4d9fdb46SRobert Mustacchi /*  Returns DW_DLV_OK or DW_DLV_ERROR. */
_dwarf_pro_set_string_attr(Dwarf_P_Attribute new_attr,Dwarf_P_Debug dbg,char * name,Dwarf_Error * error)614*4d9fdb46SRobert Mustacchi int _dwarf_pro_set_string_attr(Dwarf_P_Attribute new_attr,
615*4d9fdb46SRobert Mustacchi     Dwarf_P_Debug dbg,
616*4d9fdb46SRobert Mustacchi     char *name,
617*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
618*4d9fdb46SRobert Mustacchi {
619*4d9fdb46SRobert Mustacchi     int form = dbg->de_debug_default_str_form;
620*4d9fdb46SRobert Mustacchi     unsigned slen = strlen(name)+1;
621*4d9fdb46SRobert Mustacchi 
622*4d9fdb46SRobert Mustacchi     if (form == DW_FORM_string ||
623*4d9fdb46SRobert Mustacchi         slen <= dbg->de_dwarf_offset_size) {
624*4d9fdb46SRobert Mustacchi         new_attr->ar_nbytes = slen;
625*4d9fdb46SRobert Mustacchi         new_attr->ar_next = 0;
626*4d9fdb46SRobert Mustacchi 
627*4d9fdb46SRobert Mustacchi         new_attr->ar_data =
628*4d9fdb46SRobert Mustacchi             (char *) _dwarf_p_get_alloc(dbg, slen);
629*4d9fdb46SRobert Mustacchi         if (new_attr->ar_data == NULL) {
630*4d9fdb46SRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
631*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
632*4d9fdb46SRobert Mustacchi         }
633*4d9fdb46SRobert Mustacchi         dbg->de_stats.ps_str_count++;
634*4d9fdb46SRobert Mustacchi         dbg->de_stats.ps_str_total_length += slen;
635*4d9fdb46SRobert Mustacchi 
636*4d9fdb46SRobert Mustacchi         strcpy(new_attr->ar_data, name);
637*4d9fdb46SRobert Mustacchi         new_attr->ar_attribute_form = DW_FORM_string;
638*4d9fdb46SRobert Mustacchi         new_attr->ar_rel_type = R_MIPS_NONE;
639*4d9fdb46SRobert Mustacchi         new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
640*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
641*4d9fdb46SRobert Mustacchi     }
642*4d9fdb46SRobert Mustacchi     if (form == DW_FORM_strp) {
643*4d9fdb46SRobert Mustacchi         int uwordb_size = dbg->de_dwarf_offset_size;
644*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned offset_in_debug_str = 0;
645*4d9fdb46SRobert Mustacchi         int res = 0;
646*4d9fdb46SRobert Mustacchi 
647*4d9fdb46SRobert Mustacchi         res = _dwarf_insert_or_find_in_debug_str(dbg,name,
648*4d9fdb46SRobert Mustacchi             _dwarf_hash_debug_str,slen,
649*4d9fdb46SRobert Mustacchi             &offset_in_debug_str,error);
650*4d9fdb46SRobert Mustacchi         if(res != DW_DLV_OK) {
651*4d9fdb46SRobert Mustacchi             return res;
652*4d9fdb46SRobert Mustacchi         }
653*4d9fdb46SRobert Mustacchi         new_attr->ar_attribute_form = form;
654*4d9fdb46SRobert Mustacchi         new_attr->ar_rel_type = dbg->de_offset_reloc;
655*4d9fdb46SRobert Mustacchi         new_attr->ar_nbytes = uwordb_size;
656*4d9fdb46SRobert Mustacchi         new_attr->ar_next = NULL;
657*4d9fdb46SRobert Mustacchi         new_attr->ar_reloc_len = uwordb_size;
658*4d9fdb46SRobert Mustacchi         /*  During transform to disk
659*4d9fdb46SRobert Mustacchi             a symbol index will be applied. */
660*4d9fdb46SRobert Mustacchi         new_attr->ar_data = (char *)
661*4d9fdb46SRobert Mustacchi             _dwarf_p_get_alloc(dbg, uwordb_size);
662*4d9fdb46SRobert Mustacchi         if (new_attr->ar_data == NULL) {
663*4d9fdb46SRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
664*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
665*4d9fdb46SRobert Mustacchi         }
666*4d9fdb46SRobert Mustacchi         {
667*4d9fdb46SRobert Mustacchi             Dwarf_Unsigned du = offset_in_debug_str;
668*4d9fdb46SRobert Mustacchi 
669*4d9fdb46SRobert Mustacchi             WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data,
670*4d9fdb46SRobert Mustacchi                 (const void *) &du, sizeof(du), uwordb_size);
671*4d9fdb46SRobert Mustacchi         }
672*4d9fdb46SRobert Mustacchi 
673*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
674*4d9fdb46SRobert Mustacchi     }
675*4d9fdb46SRobert Mustacchi     _dwarf_p_error(dbg, error, DW_DLE_BAD_STRING_FORM);
676*4d9fdb46SRobert Mustacchi     return DW_DLV_ERROR;
677*4d9fdb46SRobert Mustacchi 
678*4d9fdb46SRobert Mustacchi }
679*4d9fdb46SRobert Mustacchi 
680*4d9fdb46SRobert Mustacchi 
681*4d9fdb46SRobert Mustacchi /*-------------------------------------------------------------------
682*4d9fdb46SRobert Mustacchi     Add AT_name attribute to die
683*4d9fdb46SRobert Mustacchi ---------------------------------------------------------------------*/
684*4d9fdb46SRobert Mustacchi /*  Original function. dwarf_add_AT_name_a() is the
685*4d9fdb46SRobert Mustacchi     suggested alternative. */
686*4d9fdb46SRobert Mustacchi Dwarf_P_Attribute
dwarf_add_AT_name(Dwarf_P_Die die,char * name,Dwarf_Error * error)687*4d9fdb46SRobert Mustacchi dwarf_add_AT_name(Dwarf_P_Die die,
688*4d9fdb46SRobert Mustacchi     char *name,
689*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
690*4d9fdb46SRobert Mustacchi {
691*4d9fdb46SRobert Mustacchi     Dwarf_P_Attribute a = 0;
692*4d9fdb46SRobert Mustacchi     int res = 0;
693*4d9fdb46SRobert Mustacchi 
694*4d9fdb46SRobert Mustacchi     res = dwarf_add_AT_name_a(die, name,
695*4d9fdb46SRobert Mustacchi         &a, error);
696*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_ERROR) {
697*4d9fdb46SRobert Mustacchi         return (Dwarf_P_Attribute)(DW_DLV_BADADDR);
698*4d9fdb46SRobert Mustacchi     }
699*4d9fdb46SRobert Mustacchi     return a;
700*4d9fdb46SRobert Mustacchi }
701*4d9fdb46SRobert Mustacchi 
702*4d9fdb46SRobert Mustacchi /*   New December 2018.  */
703*4d9fdb46SRobert Mustacchi int
dwarf_add_AT_name_a(Dwarf_P_Die die,char * name,Dwarf_P_Attribute * newattr_out,Dwarf_Error * error)704*4d9fdb46SRobert Mustacchi dwarf_add_AT_name_a(Dwarf_P_Die die, char *name,
705*4d9fdb46SRobert Mustacchi     Dwarf_P_Attribute *newattr_out,
706*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
707*4d9fdb46SRobert Mustacchi {
708*4d9fdb46SRobert Mustacchi     Dwarf_P_Attribute new_attr = 0;
709*4d9fdb46SRobert Mustacchi     int res = 0;
710bc1f688bSRobert Mustacchi 
711bc1f688bSRobert Mustacchi     if (die == NULL) {
712bc1f688bSRobert Mustacchi         DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL,
713*4d9fdb46SRobert Mustacchi             DW_DLV_ERROR);
714bc1f688bSRobert Mustacchi     }
715bc1f688bSRobert Mustacchi     new_attr = (Dwarf_P_Attribute)
716*4d9fdb46SRobert Mustacchi         _dwarf_p_get_alloc(die->di_dbg,
717*4d9fdb46SRobert Mustacchi             sizeof(struct Dwarf_P_Attribute_s));
718bc1f688bSRobert Mustacchi     if (new_attr == NULL) {
719bc1f688bSRobert Mustacchi         DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC,
720*4d9fdb46SRobert Mustacchi             DW_DLV_ERROR);
721bc1f688bSRobert Mustacchi     }
722bc1f688bSRobert Mustacchi 
723bc1f688bSRobert Mustacchi     /* fill in the information */
724bc1f688bSRobert Mustacchi     new_attr->ar_attribute = DW_AT_name;
725*4d9fdb46SRobert Mustacchi     res = _dwarf_pro_set_string_attr(new_attr,die->di_dbg,name,error);
726*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
727*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
728bc1f688bSRobert Mustacchi     }
729bc1f688bSRobert Mustacchi 
730bc1f688bSRobert Mustacchi     /* add attribute to the die */
731bc1f688bSRobert Mustacchi     _dwarf_pro_add_at_to_die(die, new_attr);
732*4d9fdb46SRobert Mustacchi     *newattr_out = new_attr;
733*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
734bc1f688bSRobert Mustacchi }
735bc1f688bSRobert Mustacchi 
736bc1f688bSRobert Mustacchi 
737*4d9fdb46SRobert Mustacchi /*--------------------------------------------------------------------
738bc1f688bSRobert Mustacchi     Add AT_comp_dir attribute to die
739*4d9fdb46SRobert Mustacchi --------------------------------------------------------------------*/
740bc1f688bSRobert Mustacchi Dwarf_P_Attribute
dwarf_add_AT_comp_dir(Dwarf_P_Die ownerdie,char * current_working_directory,Dwarf_Error * error)741bc1f688bSRobert Mustacchi dwarf_add_AT_comp_dir(Dwarf_P_Die ownerdie,
742bc1f688bSRobert Mustacchi     char *current_working_directory,
743bc1f688bSRobert Mustacchi     Dwarf_Error * error)
744bc1f688bSRobert Mustacchi {
745*4d9fdb46SRobert Mustacchi     Dwarf_P_Attribute a = 0;
746*4d9fdb46SRobert Mustacchi     int res = 0;
747*4d9fdb46SRobert Mustacchi 
748*4d9fdb46SRobert Mustacchi     res = dwarf_add_AT_comp_dir_a(ownerdie,
749*4d9fdb46SRobert Mustacchi         current_working_directory,
750*4d9fdb46SRobert Mustacchi         &a, error);
751*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
752*4d9fdb46SRobert Mustacchi         return (Dwarf_P_Attribute)(DW_DLV_BADADDR);
753*4d9fdb46SRobert Mustacchi     }
754*4d9fdb46SRobert Mustacchi     return a;
755*4d9fdb46SRobert Mustacchi }
756*4d9fdb46SRobert Mustacchi 
757*4d9fdb46SRobert Mustacchi int
dwarf_add_AT_comp_dir_a(Dwarf_P_Die ownerdie,char * current_working_directory,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)758*4d9fdb46SRobert Mustacchi dwarf_add_AT_comp_dir_a(Dwarf_P_Die ownerdie,
759*4d9fdb46SRobert Mustacchi     char *current_working_directory,
760*4d9fdb46SRobert Mustacchi     Dwarf_P_Attribute *attr_out,
761*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
762*4d9fdb46SRobert Mustacchi {
763*4d9fdb46SRobert Mustacchi     Dwarf_P_Attribute new_attr = 0;
764*4d9fdb46SRobert Mustacchi     int res = 0;
765bc1f688bSRobert Mustacchi 
766bc1f688bSRobert Mustacchi     if (ownerdie == NULL) {
767bc1f688bSRobert Mustacchi         DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL,
768*4d9fdb46SRobert Mustacchi             DW_DLV_ERROR);
769bc1f688bSRobert Mustacchi     }
770bc1f688bSRobert Mustacchi     new_attr = (Dwarf_P_Attribute)
771bc1f688bSRobert Mustacchi         _dwarf_p_get_alloc(ownerdie->di_dbg,
772bc1f688bSRobert Mustacchi         sizeof(struct Dwarf_P_Attribute_s));
773bc1f688bSRobert Mustacchi     if (new_attr == NULL) {
774bc1f688bSRobert Mustacchi         DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC,
775*4d9fdb46SRobert Mustacchi             DW_DLV_ERROR);
776bc1f688bSRobert Mustacchi     }
777bc1f688bSRobert Mustacchi 
778bc1f688bSRobert Mustacchi     /* fill in the information */
779bc1f688bSRobert Mustacchi     new_attr->ar_attribute = DW_AT_comp_dir;
780*4d9fdb46SRobert Mustacchi     res = _dwarf_pro_set_string_attr(new_attr,ownerdie->di_dbg,
781*4d9fdb46SRobert Mustacchi         current_working_directory,error);
782*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
783*4d9fdb46SRobert Mustacchi         return res;
784bc1f688bSRobert Mustacchi     }
785bc1f688bSRobert Mustacchi 
786bc1f688bSRobert Mustacchi     /* add attribute to the die */
787bc1f688bSRobert Mustacchi     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
788*4d9fdb46SRobert Mustacchi     *attr_out = new_attr;
789*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
790bc1f688bSRobert Mustacchi }
791bc1f688bSRobert Mustacchi 
792*4d9fdb46SRobert Mustacchi 
793bc1f688bSRobert Mustacchi int
_dwarf_pro_add_AT_fde(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_Unsigned offset,Dwarf_Error * error)794bc1f688bSRobert Mustacchi _dwarf_pro_add_AT_fde(Dwarf_P_Debug dbg,
795bc1f688bSRobert Mustacchi     Dwarf_P_Die die,
796bc1f688bSRobert Mustacchi     Dwarf_Unsigned offset, Dwarf_Error * error)
797bc1f688bSRobert Mustacchi {
798bc1f688bSRobert Mustacchi     Dwarf_P_Attribute new_attr;
799*4d9fdb46SRobert Mustacchi     int uwordb_size = dbg->de_dwarf_offset_size;
800bc1f688bSRobert Mustacchi 
801bc1f688bSRobert Mustacchi     if (die == NULL) {
802*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, DW_DLV_ERROR);
803bc1f688bSRobert Mustacchi     }
804bc1f688bSRobert Mustacchi     new_attr = (Dwarf_P_Attribute)
805bc1f688bSRobert Mustacchi         _dwarf_p_get_alloc(dbg,sizeof(struct Dwarf_P_Attribute_s));
806bc1f688bSRobert Mustacchi     if (new_attr == NULL) {
807*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_ERROR);
808bc1f688bSRobert Mustacchi     }
809bc1f688bSRobert Mustacchi 
810bc1f688bSRobert Mustacchi     /* fill in the information */
811bc1f688bSRobert Mustacchi     new_attr->ar_attribute = DW_AT_MIPS_fde;
812*4d9fdb46SRobert Mustacchi     new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form;
813bc1f688bSRobert Mustacchi     new_attr->ar_rel_type = dbg->de_offset_reloc;
814bc1f688bSRobert Mustacchi     new_attr->ar_nbytes = uwordb_size;
815bc1f688bSRobert Mustacchi     new_attr->ar_next = NULL;
816bc1f688bSRobert Mustacchi     new_attr->ar_reloc_len = uwordb_size;
817bc1f688bSRobert Mustacchi     new_attr->ar_data = (char *)
818bc1f688bSRobert Mustacchi         _dwarf_p_get_alloc(dbg, uwordb_size);
819bc1f688bSRobert Mustacchi     if (new_attr->ar_data == NULL) {
820*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_ERROR);
821bc1f688bSRobert Mustacchi     }
822bc1f688bSRobert Mustacchi     {
823bc1f688bSRobert Mustacchi         Dwarf_Unsigned du = offset;
824bc1f688bSRobert Mustacchi 
825bc1f688bSRobert Mustacchi         WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data,
826bc1f688bSRobert Mustacchi             (const void *) &du, sizeof(du), uwordb_size);
827bc1f688bSRobert Mustacchi     }
828bc1f688bSRobert Mustacchi     _dwarf_pro_add_at_to_die(die, new_attr);
829*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
830bc1f688bSRobert Mustacchi }
831bc1f688bSRobert Mustacchi 
832*4d9fdb46SRobert Mustacchi /* Sept 2016: returns DW_DLV_OK or DW_DLV_ERROR */
833bc1f688bSRobert Mustacchi int
_dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_Unsigned offset,Dwarf_Error * error)834bc1f688bSRobert Mustacchi _dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg,
835bc1f688bSRobert Mustacchi     Dwarf_P_Die die,
836bc1f688bSRobert Mustacchi     Dwarf_Unsigned offset, Dwarf_Error * error)
837bc1f688bSRobert Mustacchi {
838bc1f688bSRobert Mustacchi     Dwarf_P_Attribute new_attr;
839*4d9fdb46SRobert Mustacchi     int uwordb_size = dbg->de_dwarf_offset_size;
840bc1f688bSRobert Mustacchi 
841bc1f688bSRobert Mustacchi     if (die == NULL) {
842*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, DW_DLV_ERROR);
843bc1f688bSRobert Mustacchi     }
844bc1f688bSRobert Mustacchi     new_attr = (Dwarf_P_Attribute)
845bc1f688bSRobert Mustacchi         _dwarf_p_get_alloc(dbg,sizeof(struct Dwarf_P_Attribute_s));
846bc1f688bSRobert Mustacchi     if (new_attr == NULL) {
847*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_ERROR);
848bc1f688bSRobert Mustacchi     }
849bc1f688bSRobert Mustacchi 
850bc1f688bSRobert Mustacchi     /* fill in the information */
851bc1f688bSRobert Mustacchi     new_attr->ar_attribute = DW_AT_macro_info;
852bc1f688bSRobert Mustacchi     new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form;
853bc1f688bSRobert Mustacchi     new_attr->ar_rel_type = dbg->de_offset_reloc;
854bc1f688bSRobert Mustacchi 
855bc1f688bSRobert Mustacchi     new_attr->ar_nbytes = uwordb_size;
856bc1f688bSRobert Mustacchi     new_attr->ar_next = NULL;
857bc1f688bSRobert Mustacchi     new_attr->ar_reloc_len = uwordb_size;
858bc1f688bSRobert Mustacchi     new_attr->ar_data = (char *)
859bc1f688bSRobert Mustacchi         _dwarf_p_get_alloc(dbg, uwordb_size);
860bc1f688bSRobert Mustacchi     if (new_attr->ar_data == NULL) {
861*4d9fdb46SRobert Mustacchi         DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_ERROR);
862bc1f688bSRobert Mustacchi     }
863bc1f688bSRobert Mustacchi     {
864bc1f688bSRobert Mustacchi         Dwarf_Unsigned du = offset;
865bc1f688bSRobert Mustacchi 
866bc1f688bSRobert Mustacchi         WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data,
867bc1f688bSRobert Mustacchi             (const void *) &du, sizeof(du), uwordb_size);
868bc1f688bSRobert Mustacchi     }
869bc1f688bSRobert Mustacchi 
870bc1f688bSRobert Mustacchi     _dwarf_pro_add_at_to_die(die, new_attr);
871bc1f688bSRobert Mustacchi 
872*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
873bc1f688bSRobert Mustacchi }
874bc1f688bSRobert Mustacchi 
875bc1f688bSRobert Mustacchi 
876*4d9fdb46SRobert Mustacchi /*  Updates the list of attributes on this Dwarf_P_Die
877*4d9fdb46SRobert Mustacchi */
878bc1f688bSRobert Mustacchi void
_dwarf_pro_add_at_to_die(Dwarf_P_Die die,Dwarf_P_Attribute attr)879bc1f688bSRobert Mustacchi _dwarf_pro_add_at_to_die(Dwarf_P_Die die, Dwarf_P_Attribute attr)
880bc1f688bSRobert Mustacchi {
881bc1f688bSRobert Mustacchi     if (die->di_last_attr) {
882*4d9fdb46SRobert Mustacchi         /* Inserts new attr at the end */
883bc1f688bSRobert Mustacchi         die->di_last_attr->ar_next = attr;
884bc1f688bSRobert Mustacchi         die->di_last_attr = attr;
885bc1f688bSRobert Mustacchi         die->di_n_attr++;
886bc1f688bSRobert Mustacchi     } else {
887bc1f688bSRobert Mustacchi         die->di_n_attr = 1;
888bc1f688bSRobert Mustacchi         die->di_attrs = die->di_last_attr = attr;
889bc1f688bSRobert Mustacchi     }
890bc1f688bSRobert Mustacchi }
891