xref: /titanic_50/usr/src/lib/libdwarf/common/pro_forms.c (revision f3e7f55e73a39377d55a030f124cc86b3b66a9cc)
1*f3e7f55eSRobert Mustacchi /*
2*f3e7f55eSRobert Mustacchi   Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
3*f3e7f55eSRobert Mustacchi   Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
4*f3e7f55eSRobert Mustacchi   Portions Copyright 2007-2010 David Anderson. All rights reserved.
5*f3e7f55eSRobert Mustacchi 
6*f3e7f55eSRobert Mustacchi   This program is free software; you can redistribute it and/or modify it
7*f3e7f55eSRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
8*f3e7f55eSRobert Mustacchi   as published by the Free Software Foundation.
9*f3e7f55eSRobert Mustacchi 
10*f3e7f55eSRobert Mustacchi   This program is distributed in the hope that it would be useful, but
11*f3e7f55eSRobert Mustacchi   WITHOUT ANY WARRANTY; without even the implied warranty of
12*f3e7f55eSRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13*f3e7f55eSRobert Mustacchi 
14*f3e7f55eSRobert Mustacchi   Further, this software is distributed without any warranty that it is
15*f3e7f55eSRobert Mustacchi   free of the rightful claim of any third person regarding infringement
16*f3e7f55eSRobert Mustacchi   or the like.  Any license provided herein, whether implied or
17*f3e7f55eSRobert Mustacchi   otherwise, applies only to this software file.  Patent licenses, if
18*f3e7f55eSRobert Mustacchi   any, provided herein do not apply to combinations of this program with
19*f3e7f55eSRobert Mustacchi   other software, or any other product whatsoever.
20*f3e7f55eSRobert Mustacchi 
21*f3e7f55eSRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
22*f3e7f55eSRobert Mustacchi   License along with this program; if not, write the Free Software
23*f3e7f55eSRobert Mustacchi   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24*f3e7f55eSRobert Mustacchi   USA.
25*f3e7f55eSRobert Mustacchi 
26*f3e7f55eSRobert Mustacchi   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
27*f3e7f55eSRobert Mustacchi   Mountain View, CA 94043, or:
28*f3e7f55eSRobert Mustacchi 
29*f3e7f55eSRobert Mustacchi   http://www.sgi.com
30*f3e7f55eSRobert Mustacchi 
31*f3e7f55eSRobert Mustacchi   For further information regarding this notice, see:
32*f3e7f55eSRobert Mustacchi 
33*f3e7f55eSRobert Mustacchi   http://oss.sgi.com/projects/GenInfo/NoticeExplan
34*f3e7f55eSRobert Mustacchi 
35*f3e7f55eSRobert Mustacchi */
36*f3e7f55eSRobert Mustacchi 
37*f3e7f55eSRobert Mustacchi 
38*f3e7f55eSRobert Mustacchi 
39*f3e7f55eSRobert Mustacchi #include "config.h"
40*f3e7f55eSRobert Mustacchi #include "libdwarfdefs.h"
41*f3e7f55eSRobert Mustacchi #include <stdio.h>
42*f3e7f55eSRobert Mustacchi #include <string.h>
43*f3e7f55eSRobert Mustacchi #include <limits.h>
44*f3e7f55eSRobert Mustacchi #include "pro_incl.h"
45*f3e7f55eSRobert Mustacchi #include "pro_expr.h"
46*f3e7f55eSRobert Mustacchi 
47*f3e7f55eSRobert Mustacchi #ifndef R_MIPS_NONE
48*f3e7f55eSRobert Mustacchi #define R_MIPS_NONE 0
49*f3e7f55eSRobert Mustacchi #endif
50*f3e7f55eSRobert Mustacchi 
51*f3e7f55eSRobert Mustacchi 
52*f3e7f55eSRobert Mustacchi     /* Indicates no relocation needed. */
53*f3e7f55eSRobert Mustacchi #define NO_ELF_SYM_INDEX        0
54*f3e7f55eSRobert Mustacchi 
55*f3e7f55eSRobert Mustacchi 
56*f3e7f55eSRobert Mustacchi /* adds an attribute to a die */
57*f3e7f55eSRobert Mustacchi extern void _dwarf_pro_add_at_to_die(Dwarf_P_Die die,
58*f3e7f55eSRobert Mustacchi                                      Dwarf_P_Attribute attr);
59*f3e7f55eSRobert Mustacchi 
60*f3e7f55eSRobert Mustacchi /*
61*f3e7f55eSRobert Mustacchi     This function adds an attribute whose value is
62*f3e7f55eSRobert Mustacchi     a target address to the given die.  The attribute
63*f3e7f55eSRobert Mustacchi     is given the name provided by attr.  The address
64*f3e7f55eSRobert Mustacchi     is given in pc_value.
65*f3e7f55eSRobert Mustacchi */
66*f3e7f55eSRobert Mustacchi 
67*f3e7f55eSRobert Mustacchi static Dwarf_P_Attribute
68*f3e7f55eSRobert Mustacchi local_add_AT_address(Dwarf_P_Debug dbg,
69*f3e7f55eSRobert Mustacchi                      Dwarf_P_Die ownerdie,
70*f3e7f55eSRobert Mustacchi                      Dwarf_Half attr,
71*f3e7f55eSRobert Mustacchi                      Dwarf_Signed form,
72*f3e7f55eSRobert Mustacchi                      Dwarf_Unsigned pc_value,
73*f3e7f55eSRobert Mustacchi                      Dwarf_Unsigned sym_index,
74*f3e7f55eSRobert Mustacchi                      Dwarf_Error * error);
75*f3e7f55eSRobert Mustacchi 
76*f3e7f55eSRobert Mustacchi /* old interface */
77*f3e7f55eSRobert Mustacchi Dwarf_P_Attribute
dwarf_add_AT_targ_address(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Unsigned pc_value,Dwarf_Signed sym_index,Dwarf_Error * error)78*f3e7f55eSRobert Mustacchi dwarf_add_AT_targ_address(Dwarf_P_Debug dbg,
79*f3e7f55eSRobert Mustacchi                           Dwarf_P_Die ownerdie,
80*f3e7f55eSRobert Mustacchi                           Dwarf_Half attr,
81*f3e7f55eSRobert Mustacchi                           Dwarf_Unsigned pc_value,
82*f3e7f55eSRobert Mustacchi                           Dwarf_Signed sym_index, Dwarf_Error * error)
83*f3e7f55eSRobert Mustacchi {
84*f3e7f55eSRobert Mustacchi     return
85*f3e7f55eSRobert Mustacchi         dwarf_add_AT_targ_address_b(dbg,
86*f3e7f55eSRobert Mustacchi                                     ownerdie,
87*f3e7f55eSRobert Mustacchi                                     attr,
88*f3e7f55eSRobert Mustacchi                                     pc_value,
89*f3e7f55eSRobert Mustacchi                                     (Dwarf_Unsigned) sym_index, error);
90*f3e7f55eSRobert Mustacchi }
91*f3e7f55eSRobert Mustacchi 
92*f3e7f55eSRobert Mustacchi /* New interface, replacing dwarf_add_AT_targ_address.
93*f3e7f55eSRobert Mustacchi    Essentially just makes sym_index a Dwarf_Unsigned
94*f3e7f55eSRobert Mustacchi    so for symbolic relocations it can be a full address.
95*f3e7f55eSRobert Mustacchi */
96*f3e7f55eSRobert Mustacchi Dwarf_P_Attribute
dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Unsigned pc_value,Dwarf_Unsigned sym_index,Dwarf_Error * error)97*f3e7f55eSRobert Mustacchi dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg,
98*f3e7f55eSRobert Mustacchi                             Dwarf_P_Die ownerdie,
99*f3e7f55eSRobert Mustacchi                             Dwarf_Half attr,
100*f3e7f55eSRobert Mustacchi                             Dwarf_Unsigned pc_value,
101*f3e7f55eSRobert Mustacchi                             Dwarf_Unsigned sym_index,
102*f3e7f55eSRobert Mustacchi                             Dwarf_Error * error)
103*f3e7f55eSRobert Mustacchi {
104*f3e7f55eSRobert Mustacchi     switch (attr) {
105*f3e7f55eSRobert Mustacchi     case DW_AT_low_pc:
106*f3e7f55eSRobert Mustacchi     case DW_AT_high_pc:
107*f3e7f55eSRobert Mustacchi 
108*f3e7f55eSRobert Mustacchi     /* added to support location lists */
109*f3e7f55eSRobert Mustacchi     /* no way to check that this is a loclist-style address though */
110*f3e7f55eSRobert Mustacchi     case DW_AT_location:
111*f3e7f55eSRobert Mustacchi     case DW_AT_string_length:
112*f3e7f55eSRobert Mustacchi     case DW_AT_return_addr:
113*f3e7f55eSRobert Mustacchi     case DW_AT_frame_base:
114*f3e7f55eSRobert Mustacchi     case DW_AT_segment:
115*f3e7f55eSRobert Mustacchi     case DW_AT_static_link:
116*f3e7f55eSRobert Mustacchi     case DW_AT_use_location:
117*f3e7f55eSRobert Mustacchi     case DW_AT_vtable_elem_location:
118*f3e7f55eSRobert Mustacchi     case DW_AT_const_value: /* Gcc can generate this as address. */
119*f3e7f55eSRobert Mustacchi     case DW_AT_entry_pc:
120*f3e7f55eSRobert Mustacchi         break;
121*f3e7f55eSRobert Mustacchi     default:
122*f3e7f55eSRobert Mustacchi         if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
123*f3e7f55eSRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
124*f3e7f55eSRobert Mustacchi             return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
125*f3e7f55eSRobert Mustacchi         }
126*f3e7f55eSRobert Mustacchi         break;
127*f3e7f55eSRobert Mustacchi     }
128*f3e7f55eSRobert Mustacchi 
129*f3e7f55eSRobert Mustacchi     return local_add_AT_address(dbg, ownerdie, attr, DW_FORM_addr,
130*f3e7f55eSRobert Mustacchi                                 pc_value, sym_index, error);
131*f3e7f55eSRobert Mustacchi }
132*f3e7f55eSRobert Mustacchi 
133*f3e7f55eSRobert Mustacchi Dwarf_P_Attribute
dwarf_add_AT_ref_address(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Unsigned pc_value,Dwarf_Unsigned sym_index,Dwarf_Error * error)134*f3e7f55eSRobert Mustacchi dwarf_add_AT_ref_address(Dwarf_P_Debug dbg,
135*f3e7f55eSRobert Mustacchi                          Dwarf_P_Die ownerdie,
136*f3e7f55eSRobert Mustacchi                          Dwarf_Half attr,
137*f3e7f55eSRobert Mustacchi                          Dwarf_Unsigned pc_value,
138*f3e7f55eSRobert Mustacchi                          Dwarf_Unsigned sym_index,
139*f3e7f55eSRobert Mustacchi                          Dwarf_Error * error)
140*f3e7f55eSRobert Mustacchi {
141*f3e7f55eSRobert Mustacchi     switch (attr) {
142*f3e7f55eSRobert Mustacchi     case DW_AT_type:
143*f3e7f55eSRobert Mustacchi     case DW_AT_import:
144*f3e7f55eSRobert Mustacchi         break;
145*f3e7f55eSRobert Mustacchi 
146*f3e7f55eSRobert Mustacchi     default:
147*f3e7f55eSRobert Mustacchi         if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
148*f3e7f55eSRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
149*f3e7f55eSRobert Mustacchi             return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
150*f3e7f55eSRobert Mustacchi         }
151*f3e7f55eSRobert Mustacchi         break;
152*f3e7f55eSRobert Mustacchi     }
153*f3e7f55eSRobert Mustacchi 
154*f3e7f55eSRobert Mustacchi     return local_add_AT_address(dbg, ownerdie, attr, DW_FORM_ref_addr,
155*f3e7f55eSRobert Mustacchi                                 pc_value, sym_index, error);
156*f3e7f55eSRobert Mustacchi }
157*f3e7f55eSRobert Mustacchi 
158*f3e7f55eSRobert Mustacchi 
159*f3e7f55eSRobert Mustacchi /* Make sure attribute types are checked before entering here. */
160*f3e7f55eSRobert Mustacchi static Dwarf_P_Attribute
local_add_AT_address(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Signed form,Dwarf_Unsigned pc_value,Dwarf_Unsigned sym_index,Dwarf_Error * error)161*f3e7f55eSRobert Mustacchi local_add_AT_address(Dwarf_P_Debug dbg,
162*f3e7f55eSRobert Mustacchi                      Dwarf_P_Die ownerdie,
163*f3e7f55eSRobert Mustacchi                      Dwarf_Half attr,
164*f3e7f55eSRobert Mustacchi                      Dwarf_Signed form,
165*f3e7f55eSRobert Mustacchi                      Dwarf_Unsigned pc_value,
166*f3e7f55eSRobert Mustacchi                      Dwarf_Unsigned sym_index,
167*f3e7f55eSRobert Mustacchi                      Dwarf_Error * error)
168*f3e7f55eSRobert Mustacchi {
169*f3e7f55eSRobert Mustacchi     Dwarf_P_Attribute new_attr;
170*f3e7f55eSRobert Mustacchi     int upointer_size = dbg->de_pointer_size;
171*f3e7f55eSRobert Mustacchi 
172*f3e7f55eSRobert Mustacchi     if (dbg == NULL) {
173*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
174*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
175*f3e7f55eSRobert Mustacchi     }
176*f3e7f55eSRobert Mustacchi 
177*f3e7f55eSRobert Mustacchi     if (ownerdie == NULL) {
178*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
179*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
180*f3e7f55eSRobert Mustacchi     }
181*f3e7f55eSRobert Mustacchi 
182*f3e7f55eSRobert Mustacchi     /* attribute types have already been checked */
183*f3e7f55eSRobert Mustacchi     /* switch (attr) { ... } */
184*f3e7f55eSRobert Mustacchi 
185*f3e7f55eSRobert Mustacchi     new_attr = (Dwarf_P_Attribute)
186*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
187*f3e7f55eSRobert Mustacchi     if (new_attr == NULL) {
188*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
189*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
190*f3e7f55eSRobert Mustacchi     }
191*f3e7f55eSRobert Mustacchi 
192*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute = attr;
193*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute_form = form;
194*f3e7f55eSRobert Mustacchi     new_attr->ar_nbytes = upointer_size;
195*f3e7f55eSRobert Mustacchi     new_attr->ar_rel_symidx = sym_index;
196*f3e7f55eSRobert Mustacchi     new_attr->ar_reloc_len = upointer_size;
197*f3e7f55eSRobert Mustacchi     new_attr->ar_next = 0;
198*f3e7f55eSRobert Mustacchi     if (sym_index != NO_ELF_SYM_INDEX)
199*f3e7f55eSRobert Mustacchi         new_attr->ar_rel_type = dbg->de_ptr_reloc;
200*f3e7f55eSRobert Mustacchi     else
201*f3e7f55eSRobert Mustacchi         new_attr->ar_rel_type = R_MIPS_NONE;
202*f3e7f55eSRobert Mustacchi 
203*f3e7f55eSRobert Mustacchi     new_attr->ar_data = (char *)
204*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(dbg, upointer_size);
205*f3e7f55eSRobert Mustacchi     if (new_attr->ar_data == NULL) {
206*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
207*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
208*f3e7f55eSRobert Mustacchi     }
209*f3e7f55eSRobert Mustacchi     WRITE_UNALIGNED(dbg, new_attr->ar_data,
210*f3e7f55eSRobert Mustacchi                     (const void *) &pc_value,
211*f3e7f55eSRobert Mustacchi                     sizeof(pc_value), upointer_size);
212*f3e7f55eSRobert Mustacchi 
213*f3e7f55eSRobert Mustacchi     /* add attribute to the die */
214*f3e7f55eSRobert Mustacchi     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
215*f3e7f55eSRobert Mustacchi     return new_attr;
216*f3e7f55eSRobert Mustacchi }
217*f3e7f55eSRobert Mustacchi 
218*f3e7f55eSRobert Mustacchi /*
219*f3e7f55eSRobert Mustacchi  * Functions to compress and uncompress data from normal
220*f3e7f55eSRobert Mustacchi  * arrays of integral types into arrays of LEB128 numbers.
221*f3e7f55eSRobert Mustacchi  * Extend these functions as needed to handle wider input
222*f3e7f55eSRobert Mustacchi  * variety.  Return values should be freed with _dwarf_p_dealloc
223*f3e7f55eSRobert Mustacchi  * after they aren't needed any more.
224*f3e7f55eSRobert Mustacchi  */
225*f3e7f55eSRobert Mustacchi 
226*f3e7f55eSRobert Mustacchi /* return value points to an array of LEB number */
227*f3e7f55eSRobert Mustacchi 
228*f3e7f55eSRobert Mustacchi void *
dwarf_compress_integer_block(Dwarf_P_Debug dbg,Dwarf_Bool unit_is_signed,Dwarf_Small unit_length_in_bits,void * input_block,Dwarf_Unsigned input_length_in_units,Dwarf_Unsigned * output_length_in_bytes_ptr,Dwarf_Error * error)229*f3e7f55eSRobert Mustacchi dwarf_compress_integer_block(
230*f3e7f55eSRobert Mustacchi     Dwarf_P_Debug    dbg,
231*f3e7f55eSRobert Mustacchi     Dwarf_Bool       unit_is_signed,
232*f3e7f55eSRobert Mustacchi     Dwarf_Small      unit_length_in_bits,
233*f3e7f55eSRobert Mustacchi     void*            input_block,
234*f3e7f55eSRobert Mustacchi     Dwarf_Unsigned   input_length_in_units,
235*f3e7f55eSRobert Mustacchi     Dwarf_Unsigned*  output_length_in_bytes_ptr,
236*f3e7f55eSRobert Mustacchi     Dwarf_Error*     error
237*f3e7f55eSRobert Mustacchi )
238*f3e7f55eSRobert Mustacchi {
239*f3e7f55eSRobert Mustacchi     Dwarf_Unsigned output_length_in_bytes = 0;
240*f3e7f55eSRobert Mustacchi     char * output_block = 0;
241*f3e7f55eSRobert Mustacchi     char encode_buffer[ENCODE_SPACE_NEEDED];
242*f3e7f55eSRobert Mustacchi     int i = 0;
243*f3e7f55eSRobert Mustacchi     char * ptr = 0;
244*f3e7f55eSRobert Mustacchi     int remain = 0;
245*f3e7f55eSRobert Mustacchi     int result = 0;
246*f3e7f55eSRobert Mustacchi 
247*f3e7f55eSRobert Mustacchi     if (dbg == NULL) {
248*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
249*f3e7f55eSRobert Mustacchi         return((void *)DW_DLV_BADADDR);
250*f3e7f55eSRobert Mustacchi     }
251*f3e7f55eSRobert Mustacchi 
252*f3e7f55eSRobert Mustacchi     if (unit_is_signed == false ||
253*f3e7f55eSRobert Mustacchi         unit_length_in_bits != 32 ||
254*f3e7f55eSRobert Mustacchi         input_block == NULL ||
255*f3e7f55eSRobert Mustacchi         input_length_in_units == 0 ||
256*f3e7f55eSRobert Mustacchi         output_length_in_bytes_ptr == NULL) {
257*f3e7f55eSRobert Mustacchi 
258*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_BADBITC);
259*f3e7f55eSRobert Mustacchi         return ((void *) DW_DLV_BADADDR);
260*f3e7f55eSRobert Mustacchi     }
261*f3e7f55eSRobert Mustacchi 
262*f3e7f55eSRobert Mustacchi     /* At this point we assume the format is: signed 32 bit */
263*f3e7f55eSRobert Mustacchi 
264*f3e7f55eSRobert Mustacchi     /* first compress everything to find the total size. */
265*f3e7f55eSRobert Mustacchi 
266*f3e7f55eSRobert Mustacchi     output_length_in_bytes = 0;
267*f3e7f55eSRobert Mustacchi     for (i=0; i<input_length_in_units; i++) {
268*f3e7f55eSRobert Mustacchi         int unit_encoded_size;
269*f3e7f55eSRobert Mustacchi         Dwarf_sfixed unit; /* this is fixed at signed-32-bits */
270*f3e7f55eSRobert Mustacchi 
271*f3e7f55eSRobert Mustacchi         unit = ((Dwarf_sfixed*)input_block)[i];
272*f3e7f55eSRobert Mustacchi 
273*f3e7f55eSRobert Mustacchi         result = _dwarf_pro_encode_signed_leb128_nm(unit, &unit_encoded_size,
274*f3e7f55eSRobert Mustacchi                                              encode_buffer,sizeof(encode_buffer));
275*f3e7f55eSRobert Mustacchi         if (result !=  DW_DLV_OK) {
276*f3e7f55eSRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
277*f3e7f55eSRobert Mustacchi             return((Dwarf_P_Attribute)DW_DLV_BADADDR);
278*f3e7f55eSRobert Mustacchi         }
279*f3e7f55eSRobert Mustacchi         output_length_in_bytes += unit_encoded_size;
280*f3e7f55eSRobert Mustacchi     }
281*f3e7f55eSRobert Mustacchi 
282*f3e7f55eSRobert Mustacchi 
283*f3e7f55eSRobert Mustacchi     /* then alloc */
284*f3e7f55eSRobert Mustacchi 
285*f3e7f55eSRobert Mustacchi     output_block = (void *)
286*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(dbg, output_length_in_bytes);
287*f3e7f55eSRobert Mustacchi     if (output_block == NULL) {
288*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
289*f3e7f55eSRobert Mustacchi         return((void*)DW_DLV_BADADDR);
290*f3e7f55eSRobert Mustacchi     }
291*f3e7f55eSRobert Mustacchi 
292*f3e7f55eSRobert Mustacchi     /* then compress again and copy into new buffer */
293*f3e7f55eSRobert Mustacchi 
294*f3e7f55eSRobert Mustacchi     ptr = output_block;
295*f3e7f55eSRobert Mustacchi     remain = output_length_in_bytes;
296*f3e7f55eSRobert Mustacchi     for (i=0; i<input_length_in_units; i++) {
297*f3e7f55eSRobert Mustacchi         int unit_encoded_size;
298*f3e7f55eSRobert Mustacchi         Dwarf_sfixed unit; /* this is fixed at signed-32-bits */
299*f3e7f55eSRobert Mustacchi 
300*f3e7f55eSRobert Mustacchi         unit = ((Dwarf_sfixed*)input_block)[i];
301*f3e7f55eSRobert Mustacchi 
302*f3e7f55eSRobert Mustacchi         result = _dwarf_pro_encode_signed_leb128_nm(unit, &unit_encoded_size,
303*f3e7f55eSRobert Mustacchi                                              ptr, remain);
304*f3e7f55eSRobert Mustacchi         if (result !=  DW_DLV_OK) {
305*f3e7f55eSRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
306*f3e7f55eSRobert Mustacchi             return((Dwarf_P_Attribute)DW_DLV_BADADDR);
307*f3e7f55eSRobert Mustacchi         }
308*f3e7f55eSRobert Mustacchi         remain -= unit_encoded_size;
309*f3e7f55eSRobert Mustacchi         ptr += unit_encoded_size;
310*f3e7f55eSRobert Mustacchi     }
311*f3e7f55eSRobert Mustacchi 
312*f3e7f55eSRobert Mustacchi     if (remain != 0) {
313*f3e7f55eSRobert Mustacchi         _dwarf_p_dealloc(dbg, (unsigned char *)output_block);
314*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
315*f3e7f55eSRobert Mustacchi         return((Dwarf_P_Attribute)DW_DLV_BADADDR);
316*f3e7f55eSRobert Mustacchi     }
317*f3e7f55eSRobert Mustacchi 
318*f3e7f55eSRobert Mustacchi     *output_length_in_bytes_ptr = output_length_in_bytes;
319*f3e7f55eSRobert Mustacchi     return (void*) output_block;
320*f3e7f55eSRobert Mustacchi 
321*f3e7f55eSRobert Mustacchi }
322*f3e7f55eSRobert Mustacchi 
323*f3e7f55eSRobert Mustacchi void
dwarf_dealloc_compressed_block(Dwarf_P_Debug dbg,void * space)324*f3e7f55eSRobert Mustacchi dwarf_dealloc_compressed_block(Dwarf_P_Debug dbg, void * space)
325*f3e7f55eSRobert Mustacchi {
326*f3e7f55eSRobert Mustacchi     _dwarf_p_dealloc(dbg, space);
327*f3e7f55eSRobert Mustacchi }
328*f3e7f55eSRobert Mustacchi 
329*f3e7f55eSRobert Mustacchi /* This is very similar to targ_address but results in a different FORM */
330*f3e7f55eSRobert Mustacchi /* dbg->de_ar_data_attribute_form is data4 or data8
331*f3e7f55eSRobert Mustacchi    and dwarf4 changes the definition for such on DW_AT_high_pc.
332*f3e7f55eSRobert Mustacchi    DWARF 3: the FORM here has no defined meaning for dwarf3.
333*f3e7f55eSRobert Mustacchi    DWARF 4: the FORM here means that for DW_AT_high_pc the value
334*f3e7f55eSRobert Mustacchi             is not a high address but is instead an offset
335*f3e7f55eSRobert Mustacchi             from a (separate) DW_AT_low_pc.
336*f3e7f55eSRobert Mustacchi    The intent for DWARF4 is that this is not a relocated
337*f3e7f55eSRobert Mustacchi    address at all.  Instead a simple offset.
338*f3e7f55eSRobert Mustacchi    But this should NOT be called for a simple non-relocated offset.
339*f3e7f55eSRobert Mustacchi    So do not call this with an attr of DW_AT_high_pc.
340*f3e7f55eSRobert Mustacchi    Use dwarf_add_AT_unsigned_const() (for example) instead of
341*f3e7f55eSRobert Mustacchi    dwarf_add_AT_dataref when the value is a simple offset .
342*f3e7f55eSRobert Mustacchi */
343*f3e7f55eSRobert Mustacchi Dwarf_P_Attribute
dwarf_add_AT_dataref(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Unsigned pc_value,Dwarf_Unsigned sym_index,Dwarf_Error * error)344*f3e7f55eSRobert Mustacchi dwarf_add_AT_dataref(
345*f3e7f55eSRobert Mustacchi     Dwarf_P_Debug dbg,
346*f3e7f55eSRobert Mustacchi     Dwarf_P_Die ownerdie,
347*f3e7f55eSRobert Mustacchi     Dwarf_Half attr,
348*f3e7f55eSRobert Mustacchi     Dwarf_Unsigned pc_value,
349*f3e7f55eSRobert Mustacchi     Dwarf_Unsigned sym_index,
350*f3e7f55eSRobert Mustacchi     Dwarf_Error * error)
351*f3e7f55eSRobert Mustacchi {
352*f3e7f55eSRobert Mustacchi     /* TODO: Add checking here */
353*f3e7f55eSRobert Mustacchi     return local_add_AT_address(dbg, ownerdie, attr,
354*f3e7f55eSRobert Mustacchi                                 dbg->de_ar_data_attribute_form,
355*f3e7f55eSRobert Mustacchi                                 pc_value,
356*f3e7f55eSRobert Mustacchi                                 sym_index,
357*f3e7f55eSRobert Mustacchi                                 error);
358*f3e7f55eSRobert Mustacchi }
359*f3e7f55eSRobert Mustacchi 
360*f3e7f55eSRobert Mustacchi 
361*f3e7f55eSRobert Mustacchi 
362*f3e7f55eSRobert Mustacchi Dwarf_P_Attribute
dwarf_add_AT_block(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Small * block_data,Dwarf_Unsigned block_size,Dwarf_Error * error)363*f3e7f55eSRobert Mustacchi dwarf_add_AT_block(
364*f3e7f55eSRobert Mustacchi     Dwarf_P_Debug       dbg,
365*f3e7f55eSRobert Mustacchi     Dwarf_P_Die         ownerdie,
366*f3e7f55eSRobert Mustacchi     Dwarf_Half          attr,
367*f3e7f55eSRobert Mustacchi     Dwarf_Small         *block_data,
368*f3e7f55eSRobert Mustacchi     Dwarf_Unsigned      block_size,
369*f3e7f55eSRobert Mustacchi     Dwarf_Error         *error
370*f3e7f55eSRobert Mustacchi )
371*f3e7f55eSRobert Mustacchi {
372*f3e7f55eSRobert Mustacchi     Dwarf_P_Attribute   new_attr;
373*f3e7f55eSRobert Mustacchi     int result;
374*f3e7f55eSRobert Mustacchi     char encode_buffer[ENCODE_SPACE_NEEDED];
375*f3e7f55eSRobert Mustacchi     int len_size;
376*f3e7f55eSRobert Mustacchi     char * attrdata;
377*f3e7f55eSRobert Mustacchi 
378*f3e7f55eSRobert Mustacchi     if (dbg == NULL) {
379*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
380*f3e7f55eSRobert Mustacchi         return((Dwarf_P_Attribute)DW_DLV_BADADDR);
381*f3e7f55eSRobert Mustacchi     }
382*f3e7f55eSRobert Mustacchi 
383*f3e7f55eSRobert Mustacchi     if (ownerdie == NULL) {
384*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
385*f3e7f55eSRobert Mustacchi         return((Dwarf_P_Attribute)DW_DLV_BADADDR);
386*f3e7f55eSRobert Mustacchi     }
387*f3e7f55eSRobert Mustacchi 
388*f3e7f55eSRobert Mustacchi     /* I don't mess with block1, block2, block4, not worth the effort */
389*f3e7f55eSRobert Mustacchi 
390*f3e7f55eSRobert Mustacchi     /* So, encode the length into LEB128 */
391*f3e7f55eSRobert Mustacchi     result = _dwarf_pro_encode_leb128_nm(block_size, &len_size,
392*f3e7f55eSRobert Mustacchi                                          encode_buffer,sizeof(encode_buffer));
393*f3e7f55eSRobert Mustacchi     if (result !=  DW_DLV_OK) {
394*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
395*f3e7f55eSRobert Mustacchi         return((Dwarf_P_Attribute)DW_DLV_BADADDR);
396*f3e7f55eSRobert Mustacchi     }
397*f3e7f55eSRobert Mustacchi 
398*f3e7f55eSRobert Mustacchi     /* Allocate the new attribute */
399*f3e7f55eSRobert Mustacchi     new_attr = (Dwarf_P_Attribute)
400*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
401*f3e7f55eSRobert Mustacchi     if (new_attr == NULL) {
402*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
403*f3e7f55eSRobert Mustacchi         return((Dwarf_P_Attribute)DW_DLV_BADADDR);
404*f3e7f55eSRobert Mustacchi     }
405*f3e7f55eSRobert Mustacchi 
406*f3e7f55eSRobert Mustacchi     /* Fill in the attribute */
407*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute = attr;
408*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute_form = DW_FORM_block;
409*f3e7f55eSRobert Mustacchi     new_attr->ar_nbytes = len_size + block_size;
410*f3e7f55eSRobert Mustacchi     new_attr->ar_next = 0;
411*f3e7f55eSRobert Mustacchi 
412*f3e7f55eSRobert Mustacchi     new_attr->ar_data = attrdata = (char *)
413*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(dbg, len_size + block_size);
414*f3e7f55eSRobert Mustacchi     if (new_attr->ar_data == NULL) {
415*f3e7f55eSRobert Mustacchi         /* free the block we got earlier */
416*f3e7f55eSRobert Mustacchi         _dwarf_p_dealloc(dbg, (unsigned char *) new_attr);
417*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
418*f3e7f55eSRobert Mustacchi         return((Dwarf_P_Attribute)DW_DLV_BADADDR);
419*f3e7f55eSRobert Mustacchi     }
420*f3e7f55eSRobert Mustacchi 
421*f3e7f55eSRobert Mustacchi     /* write length and data to attribute data buffer */
422*f3e7f55eSRobert Mustacchi     memcpy(attrdata, encode_buffer, len_size);
423*f3e7f55eSRobert Mustacchi     attrdata += len_size;
424*f3e7f55eSRobert Mustacchi     memcpy(attrdata, block_data, block_size);
425*f3e7f55eSRobert Mustacchi 
426*f3e7f55eSRobert Mustacchi     /* add attribute to the die */
427*f3e7f55eSRobert Mustacchi     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
428*f3e7f55eSRobert Mustacchi 
429*f3e7f55eSRobert Mustacchi     return new_attr;
430*f3e7f55eSRobert Mustacchi }
431*f3e7f55eSRobert Mustacchi 
432*f3e7f55eSRobert Mustacchi 
433*f3e7f55eSRobert Mustacchi /*
434*f3e7f55eSRobert Mustacchi     This function adds attributes whose value
435*f3e7f55eSRobert Mustacchi     is an unsigned constant.  It determines the
436*f3e7f55eSRobert Mustacchi     size of the value field from the value of
437*f3e7f55eSRobert Mustacchi     the constant.
438*f3e7f55eSRobert Mustacchi */
439*f3e7f55eSRobert Mustacchi Dwarf_P_Attribute
dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Unsigned value,Dwarf_Error * error)440*f3e7f55eSRobert Mustacchi dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg,
441*f3e7f55eSRobert Mustacchi                             Dwarf_P_Die ownerdie,
442*f3e7f55eSRobert Mustacchi                             Dwarf_Half attr,
443*f3e7f55eSRobert Mustacchi                             Dwarf_Unsigned value, Dwarf_Error * error)
444*f3e7f55eSRobert Mustacchi {
445*f3e7f55eSRobert Mustacchi     Dwarf_P_Attribute new_attr;
446*f3e7f55eSRobert Mustacchi     Dwarf_Half attr_form;
447*f3e7f55eSRobert Mustacchi     Dwarf_Small size;
448*f3e7f55eSRobert Mustacchi 
449*f3e7f55eSRobert Mustacchi     if (dbg == NULL) {
450*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
451*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
452*f3e7f55eSRobert Mustacchi     }
453*f3e7f55eSRobert Mustacchi 
454*f3e7f55eSRobert Mustacchi     if (ownerdie == NULL) {
455*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
456*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
457*f3e7f55eSRobert Mustacchi     }
458*f3e7f55eSRobert Mustacchi 
459*f3e7f55eSRobert Mustacchi     switch (attr) {
460*f3e7f55eSRobert Mustacchi     case DW_AT_ordering:
461*f3e7f55eSRobert Mustacchi     case DW_AT_byte_size:
462*f3e7f55eSRobert Mustacchi     case DW_AT_bit_offset:
463*f3e7f55eSRobert Mustacchi     case DW_AT_bit_size:
464*f3e7f55eSRobert Mustacchi     case DW_AT_inline:
465*f3e7f55eSRobert Mustacchi     case DW_AT_language:
466*f3e7f55eSRobert Mustacchi     case DW_AT_visibility:
467*f3e7f55eSRobert Mustacchi     case DW_AT_virtuality:
468*f3e7f55eSRobert Mustacchi     case DW_AT_accessibility:
469*f3e7f55eSRobert Mustacchi     case DW_AT_address_class:
470*f3e7f55eSRobert Mustacchi     case DW_AT_calling_convention:
471*f3e7f55eSRobert Mustacchi     case DW_AT_encoding:
472*f3e7f55eSRobert Mustacchi     case DW_AT_identifier_case:
473*f3e7f55eSRobert Mustacchi     case DW_AT_MIPS_loop_unroll_factor:
474*f3e7f55eSRobert Mustacchi     case DW_AT_MIPS_software_pipeline_depth:
475*f3e7f55eSRobert Mustacchi         break;
476*f3e7f55eSRobert Mustacchi 
477*f3e7f55eSRobert Mustacchi     case DW_AT_decl_column:
478*f3e7f55eSRobert Mustacchi     case DW_AT_decl_file:
479*f3e7f55eSRobert Mustacchi     case DW_AT_decl_line:
480*f3e7f55eSRobert Mustacchi     case DW_AT_const_value:
481*f3e7f55eSRobert Mustacchi     case DW_AT_start_scope:
482*f3e7f55eSRobert Mustacchi     case DW_AT_stride_size:
483*f3e7f55eSRobert Mustacchi     case DW_AT_count:
484*f3e7f55eSRobert Mustacchi     case DW_AT_associated:
485*f3e7f55eSRobert Mustacchi     case DW_AT_allocated:
486*f3e7f55eSRobert Mustacchi     case DW_AT_upper_bound:
487*f3e7f55eSRobert Mustacchi     case DW_AT_lower_bound:
488*f3e7f55eSRobert Mustacchi     case DW_AT_call_file:
489*f3e7f55eSRobert Mustacchi     case DW_AT_call_line:
490*f3e7f55eSRobert Mustacchi         break;
491*f3e7f55eSRobert Mustacchi 
492*f3e7f55eSRobert Mustacchi         default: {
493*f3e7f55eSRobert Mustacchi                  if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
494*f3e7f55eSRobert Mustacchi                      _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
495*f3e7f55eSRobert Mustacchi                      return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
496*f3e7f55eSRobert Mustacchi                }
497*f3e7f55eSRobert Mustacchi                break;
498*f3e7f55eSRobert Mustacchi             }
499*f3e7f55eSRobert Mustacchi         }
500*f3e7f55eSRobert Mustacchi 
501*f3e7f55eSRobert Mustacchi     /*
502*f3e7f55eSRobert Mustacchi        Compute the number of bytes needed to hold constant. */
503*f3e7f55eSRobert Mustacchi     if (value <= UCHAR_MAX) {
504*f3e7f55eSRobert Mustacchi         attr_form = DW_FORM_data1;
505*f3e7f55eSRobert Mustacchi         size = 1;
506*f3e7f55eSRobert Mustacchi     } else if (value <= USHRT_MAX) {
507*f3e7f55eSRobert Mustacchi         attr_form = DW_FORM_data2;
508*f3e7f55eSRobert Mustacchi         size = 2;
509*f3e7f55eSRobert Mustacchi     } else if (value <= UINT_MAX) {
510*f3e7f55eSRobert Mustacchi         attr_form = DW_FORM_data4;
511*f3e7f55eSRobert Mustacchi         size = 4;
512*f3e7f55eSRobert Mustacchi     } else {
513*f3e7f55eSRobert Mustacchi         attr_form = DW_FORM_data8;
514*f3e7f55eSRobert Mustacchi         size = 8;
515*f3e7f55eSRobert Mustacchi     }
516*f3e7f55eSRobert Mustacchi 
517*f3e7f55eSRobert Mustacchi     new_attr = (Dwarf_P_Attribute)
518*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
519*f3e7f55eSRobert Mustacchi     if (new_attr == NULL) {
520*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
521*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
522*f3e7f55eSRobert Mustacchi     }
523*f3e7f55eSRobert Mustacchi 
524*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute = attr;
525*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute_form = attr_form;
526*f3e7f55eSRobert Mustacchi     new_attr->ar_rel_type = R_MIPS_NONE;
527*f3e7f55eSRobert Mustacchi     new_attr->ar_reloc_len = 0; /* irrelevant: unused with R_MIPS_NONE */
528*f3e7f55eSRobert Mustacchi     new_attr->ar_nbytes = size;
529*f3e7f55eSRobert Mustacchi     new_attr->ar_next = 0;
530*f3e7f55eSRobert Mustacchi 
531*f3e7f55eSRobert Mustacchi     new_attr->ar_data = (char *)
532*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(dbg, size);
533*f3e7f55eSRobert Mustacchi     if (new_attr->ar_data == NULL) {
534*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
535*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
536*f3e7f55eSRobert Mustacchi     }
537*f3e7f55eSRobert Mustacchi     WRITE_UNALIGNED(dbg, new_attr->ar_data,
538*f3e7f55eSRobert Mustacchi                     (const void *) &value, sizeof(value), size);
539*f3e7f55eSRobert Mustacchi 
540*f3e7f55eSRobert Mustacchi     /* add attribute to the die */
541*f3e7f55eSRobert Mustacchi     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
542*f3e7f55eSRobert Mustacchi     return new_attr;
543*f3e7f55eSRobert Mustacchi }
544*f3e7f55eSRobert Mustacchi 
545*f3e7f55eSRobert Mustacchi 
546*f3e7f55eSRobert Mustacchi /*
547*f3e7f55eSRobert Mustacchi     This function adds attributes whose value
548*f3e7f55eSRobert Mustacchi     is an signed constant.  It determines the
549*f3e7f55eSRobert Mustacchi     size of the value field from the value of
550*f3e7f55eSRobert Mustacchi     the constant.
551*f3e7f55eSRobert Mustacchi */
552*f3e7f55eSRobert Mustacchi Dwarf_P_Attribute
dwarf_add_AT_signed_const(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Signed value,Dwarf_Error * error)553*f3e7f55eSRobert Mustacchi dwarf_add_AT_signed_const(Dwarf_P_Debug dbg,
554*f3e7f55eSRobert Mustacchi                           Dwarf_P_Die ownerdie,
555*f3e7f55eSRobert Mustacchi                           Dwarf_Half attr,
556*f3e7f55eSRobert Mustacchi                           Dwarf_Signed value, Dwarf_Error * error)
557*f3e7f55eSRobert Mustacchi {
558*f3e7f55eSRobert Mustacchi     Dwarf_P_Attribute new_attr;
559*f3e7f55eSRobert Mustacchi     Dwarf_Half attr_form;
560*f3e7f55eSRobert Mustacchi     Dwarf_Small size;
561*f3e7f55eSRobert Mustacchi 
562*f3e7f55eSRobert Mustacchi     if (dbg == NULL) {
563*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
564*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
565*f3e7f55eSRobert Mustacchi     }
566*f3e7f55eSRobert Mustacchi 
567*f3e7f55eSRobert Mustacchi     if (ownerdie == NULL) {
568*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
569*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
570*f3e7f55eSRobert Mustacchi     }
571*f3e7f55eSRobert Mustacchi 
572*f3e7f55eSRobert Mustacchi     switch (attr) {
573*f3e7f55eSRobert Mustacchi     case DW_AT_lower_bound:
574*f3e7f55eSRobert Mustacchi     case DW_AT_upper_bound:
575*f3e7f55eSRobert Mustacchi     case DW_AT_const_value:
576*f3e7f55eSRobert Mustacchi     case DW_AT_bit_offset:
577*f3e7f55eSRobert Mustacchi     case DW_AT_bit_size:
578*f3e7f55eSRobert Mustacchi     case DW_AT_byte_size:
579*f3e7f55eSRobert Mustacchi     case DW_AT_count:
580*f3e7f55eSRobert Mustacchi     case DW_AT_byte_stride:
581*f3e7f55eSRobert Mustacchi     case DW_AT_bit_stride:
582*f3e7f55eSRobert Mustacchi     case DW_AT_allocated:
583*f3e7f55eSRobert Mustacchi     case DW_AT_associated:
584*f3e7f55eSRobert Mustacchi         break;
585*f3e7f55eSRobert Mustacchi 
586*f3e7f55eSRobert Mustacchi     default:{
587*f3e7f55eSRobert Mustacchi                 if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
588*f3e7f55eSRobert Mustacchi                      _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
589*f3e7f55eSRobert Mustacchi                      return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
590*f3e7f55eSRobert Mustacchi                 }
591*f3e7f55eSRobert Mustacchi         }
592*f3e7f55eSRobert Mustacchi         break;
593*f3e7f55eSRobert Mustacchi     }
594*f3e7f55eSRobert Mustacchi 
595*f3e7f55eSRobert Mustacchi     /*
596*f3e7f55eSRobert Mustacchi        Compute the number of bytes needed to hold constant. */
597*f3e7f55eSRobert Mustacchi     if (value >= SCHAR_MIN && value <= SCHAR_MAX) {
598*f3e7f55eSRobert Mustacchi         attr_form = DW_FORM_data1;
599*f3e7f55eSRobert Mustacchi         size = 1;
600*f3e7f55eSRobert Mustacchi     } else if (value >= SHRT_MIN && value <= SHRT_MAX) {
601*f3e7f55eSRobert Mustacchi         attr_form = DW_FORM_data2;
602*f3e7f55eSRobert Mustacchi         size = 2;
603*f3e7f55eSRobert Mustacchi     } else if (value >= INT_MIN && value <= INT_MAX) {
604*f3e7f55eSRobert Mustacchi         attr_form = DW_FORM_data4;
605*f3e7f55eSRobert Mustacchi         size = 4;
606*f3e7f55eSRobert Mustacchi     } else {
607*f3e7f55eSRobert Mustacchi         attr_form = DW_FORM_data8;
608*f3e7f55eSRobert Mustacchi         size = 8;
609*f3e7f55eSRobert Mustacchi     }
610*f3e7f55eSRobert Mustacchi 
611*f3e7f55eSRobert Mustacchi     new_attr = (Dwarf_P_Attribute)
612*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
613*f3e7f55eSRobert Mustacchi     if (new_attr == NULL) {
614*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
615*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
616*f3e7f55eSRobert Mustacchi     }
617*f3e7f55eSRobert Mustacchi 
618*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute = attr;
619*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute_form = attr_form;
620*f3e7f55eSRobert Mustacchi     new_attr->ar_rel_type = R_MIPS_NONE;
621*f3e7f55eSRobert Mustacchi     new_attr->ar_reloc_len = 0; /* irrelevant: unused with R_MIPS_NONE */
622*f3e7f55eSRobert Mustacchi     new_attr->ar_nbytes = size;
623*f3e7f55eSRobert Mustacchi     new_attr->ar_next = 0;
624*f3e7f55eSRobert Mustacchi 
625*f3e7f55eSRobert Mustacchi     new_attr->ar_data = (char *)
626*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(dbg, size);
627*f3e7f55eSRobert Mustacchi     if (new_attr->ar_data == NULL) {
628*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
629*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
630*f3e7f55eSRobert Mustacchi     }
631*f3e7f55eSRobert Mustacchi     WRITE_UNALIGNED(dbg, new_attr->ar_data,
632*f3e7f55eSRobert Mustacchi                     (const void *) &value, sizeof(value), size);
633*f3e7f55eSRobert Mustacchi 
634*f3e7f55eSRobert Mustacchi     /* add attribute to the die */
635*f3e7f55eSRobert Mustacchi     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
636*f3e7f55eSRobert Mustacchi     return new_attr;
637*f3e7f55eSRobert Mustacchi }
638*f3e7f55eSRobert Mustacchi 
639*f3e7f55eSRobert Mustacchi 
640*f3e7f55eSRobert Mustacchi /*
641*f3e7f55eSRobert Mustacchi     This function adds attributes whose value
642*f3e7f55eSRobert Mustacchi     is a location expression.
643*f3e7f55eSRobert Mustacchi */
644*f3e7f55eSRobert Mustacchi Dwarf_P_Attribute
dwarf_add_AT_location_expr(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_P_Expr loc_expr,Dwarf_Error * error)645*f3e7f55eSRobert Mustacchi dwarf_add_AT_location_expr(Dwarf_P_Debug dbg,
646*f3e7f55eSRobert Mustacchi                            Dwarf_P_Die ownerdie,
647*f3e7f55eSRobert Mustacchi                            Dwarf_Half attr,
648*f3e7f55eSRobert Mustacchi                            Dwarf_P_Expr loc_expr, Dwarf_Error * error)
649*f3e7f55eSRobert Mustacchi {
650*f3e7f55eSRobert Mustacchi     char encode_buffer[ENCODE_SPACE_NEEDED];
651*f3e7f55eSRobert Mustacchi     int res;
652*f3e7f55eSRobert Mustacchi     Dwarf_P_Attribute new_attr;
653*f3e7f55eSRobert Mustacchi     Dwarf_Half attr_form;
654*f3e7f55eSRobert Mustacchi     char *len_str = 0;
655*f3e7f55eSRobert Mustacchi     int len_size;
656*f3e7f55eSRobert Mustacchi     int block_size;
657*f3e7f55eSRobert Mustacchi     char *block_dest_ptr;
658*f3e7f55eSRobert Mustacchi     int do_len_as_int = 0;
659*f3e7f55eSRobert Mustacchi 
660*f3e7f55eSRobert Mustacchi     if (dbg == NULL) {
661*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
662*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
663*f3e7f55eSRobert Mustacchi     }
664*f3e7f55eSRobert Mustacchi 
665*f3e7f55eSRobert Mustacchi     if (ownerdie == NULL) {
666*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
667*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
668*f3e7f55eSRobert Mustacchi     }
669*f3e7f55eSRobert Mustacchi 
670*f3e7f55eSRobert Mustacchi     if (loc_expr == NULL) {
671*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_EXPR_NULL);
672*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
673*f3e7f55eSRobert Mustacchi     }
674*f3e7f55eSRobert Mustacchi 
675*f3e7f55eSRobert Mustacchi     if (loc_expr->ex_dbg != dbg) {
676*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
677*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
678*f3e7f55eSRobert Mustacchi     }
679*f3e7f55eSRobert Mustacchi     block_size = loc_expr->ex_next_byte_offset;
680*f3e7f55eSRobert Mustacchi 
681*f3e7f55eSRobert Mustacchi     switch (attr) {
682*f3e7f55eSRobert Mustacchi     case DW_AT_location:
683*f3e7f55eSRobert Mustacchi     case DW_AT_string_length:
684*f3e7f55eSRobert Mustacchi     case DW_AT_const_value:
685*f3e7f55eSRobert Mustacchi     case DW_AT_use_location:
686*f3e7f55eSRobert Mustacchi     case DW_AT_return_addr:
687*f3e7f55eSRobert Mustacchi     case DW_AT_data_member_location:
688*f3e7f55eSRobert Mustacchi     case DW_AT_frame_base:
689*f3e7f55eSRobert Mustacchi     case DW_AT_static_link:
690*f3e7f55eSRobert Mustacchi     case DW_AT_vtable_elem_location:
691*f3e7f55eSRobert Mustacchi     case DW_AT_lower_bound:
692*f3e7f55eSRobert Mustacchi     case DW_AT_upper_bound:
693*f3e7f55eSRobert Mustacchi     case DW_AT_count:
694*f3e7f55eSRobert Mustacchi     case DW_AT_associated:
695*f3e7f55eSRobert Mustacchi     case DW_AT_allocated:
696*f3e7f55eSRobert Mustacchi     case DW_AT_data_location:
697*f3e7f55eSRobert Mustacchi     case DW_AT_byte_stride:
698*f3e7f55eSRobert Mustacchi     case DW_AT_bit_stride:
699*f3e7f55eSRobert Mustacchi     case DW_AT_byte_size:
700*f3e7f55eSRobert Mustacchi     case DW_AT_bit_size:
701*f3e7f55eSRobert Mustacchi     break;
702*f3e7f55eSRobert Mustacchi 
703*f3e7f55eSRobert Mustacchi     default:
704*f3e7f55eSRobert Mustacchi         if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
705*f3e7f55eSRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
706*f3e7f55eSRobert Mustacchi             return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
707*f3e7f55eSRobert Mustacchi         }
708*f3e7f55eSRobert Mustacchi     break;
709*f3e7f55eSRobert Mustacchi     }
710*f3e7f55eSRobert Mustacchi 
711*f3e7f55eSRobert Mustacchi     /*
712*f3e7f55eSRobert Mustacchi        Compute the number of bytes needed to hold constant. */
713*f3e7f55eSRobert Mustacchi     if (block_size <= UCHAR_MAX) {
714*f3e7f55eSRobert Mustacchi         attr_form = DW_FORM_block1;
715*f3e7f55eSRobert Mustacchi         len_size = 1;
716*f3e7f55eSRobert Mustacchi         do_len_as_int = 1;
717*f3e7f55eSRobert Mustacchi     } else if (block_size <= USHRT_MAX) {
718*f3e7f55eSRobert Mustacchi         attr_form = DW_FORM_block2;
719*f3e7f55eSRobert Mustacchi         len_size = 2;
720*f3e7f55eSRobert Mustacchi         do_len_as_int = 1;
721*f3e7f55eSRobert Mustacchi     } else if (block_size <= UINT_MAX) {
722*f3e7f55eSRobert Mustacchi         attr_form = DW_FORM_block4;
723*f3e7f55eSRobert Mustacchi         len_size = 4;
724*f3e7f55eSRobert Mustacchi         do_len_as_int = 1;
725*f3e7f55eSRobert Mustacchi     } else {
726*f3e7f55eSRobert Mustacchi         attr_form = DW_FORM_block;
727*f3e7f55eSRobert Mustacchi         res = _dwarf_pro_encode_leb128_nm(block_size, &len_size,
728*f3e7f55eSRobert Mustacchi                                           encode_buffer,
729*f3e7f55eSRobert Mustacchi                                           sizeof(encode_buffer));
730*f3e7f55eSRobert Mustacchi         if (res != DW_DLV_OK) {
731*f3e7f55eSRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
732*f3e7f55eSRobert Mustacchi             return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
733*f3e7f55eSRobert Mustacchi         }
734*f3e7f55eSRobert Mustacchi         len_str = (char *) encode_buffer;
735*f3e7f55eSRobert Mustacchi     }
736*f3e7f55eSRobert Mustacchi 
737*f3e7f55eSRobert Mustacchi     new_attr = (Dwarf_P_Attribute)
738*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
739*f3e7f55eSRobert Mustacchi     if (new_attr == NULL) {
740*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
741*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
742*f3e7f55eSRobert Mustacchi     }
743*f3e7f55eSRobert Mustacchi 
744*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute = attr;
745*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute_form = attr_form;
746*f3e7f55eSRobert Mustacchi     new_attr->ar_reloc_len = dbg->de_pointer_size;
747*f3e7f55eSRobert Mustacchi     if (loc_expr->ex_reloc_sym_index != NO_ELF_SYM_INDEX) {
748*f3e7f55eSRobert Mustacchi         new_attr->ar_rel_type = dbg->de_ptr_reloc;
749*f3e7f55eSRobert Mustacchi     } else {
750*f3e7f55eSRobert Mustacchi         new_attr->ar_rel_type = R_MIPS_NONE;
751*f3e7f55eSRobert Mustacchi     }
752*f3e7f55eSRobert Mustacchi     new_attr->ar_rel_symidx = loc_expr->ex_reloc_sym_index;
753*f3e7f55eSRobert Mustacchi     new_attr->ar_rel_offset =
754*f3e7f55eSRobert Mustacchi         (Dwarf_Word) loc_expr->ex_reloc_offset + len_size;
755*f3e7f55eSRobert Mustacchi 
756*f3e7f55eSRobert Mustacchi     new_attr->ar_nbytes = block_size + len_size;
757*f3e7f55eSRobert Mustacchi 
758*f3e7f55eSRobert Mustacchi     new_attr->ar_next = 0;
759*f3e7f55eSRobert Mustacchi     new_attr->ar_data = block_dest_ptr =
760*f3e7f55eSRobert Mustacchi         (char *) _dwarf_p_get_alloc(dbg, block_size + len_size);
761*f3e7f55eSRobert Mustacchi     if (new_attr->ar_data == NULL) {
762*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
763*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
764*f3e7f55eSRobert Mustacchi     }
765*f3e7f55eSRobert Mustacchi 
766*f3e7f55eSRobert Mustacchi     if (do_len_as_int) {
767*f3e7f55eSRobert Mustacchi         WRITE_UNALIGNED(dbg, block_dest_ptr, (const void *) &block_size,
768*f3e7f55eSRobert Mustacchi                         sizeof(block_size), len_size);
769*f3e7f55eSRobert Mustacchi     } else {
770*f3e7f55eSRobert Mustacchi         /* Is uleb number form, DW_FORM_block. See above. */
771*f3e7f55eSRobert Mustacchi         memcpy(block_dest_ptr, len_str, len_size);
772*f3e7f55eSRobert Mustacchi     }
773*f3e7f55eSRobert Mustacchi     block_dest_ptr += len_size;
774*f3e7f55eSRobert Mustacchi     memcpy(block_dest_ptr, &(loc_expr->ex_byte_stream[0]), block_size);
775*f3e7f55eSRobert Mustacchi 
776*f3e7f55eSRobert Mustacchi     /* add attribute to the die */
777*f3e7f55eSRobert Mustacchi     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
778*f3e7f55eSRobert Mustacchi     return new_attr;
779*f3e7f55eSRobert Mustacchi }
780*f3e7f55eSRobert Mustacchi 
781*f3e7f55eSRobert Mustacchi 
782*f3e7f55eSRobert Mustacchi /*
783*f3e7f55eSRobert Mustacchi     This function adds attributes of reference class.
784*f3e7f55eSRobert Mustacchi     The references here are local CU references,
785*f3e7f55eSRobert Mustacchi     not DW_FORM_ref_addr.
786*f3e7f55eSRobert Mustacchi     The offset field is 4 bytes for 32-bit objects,
787*f3e7f55eSRobert Mustacchi     and 8-bytes for 64-bit objects.  Otherdie is the
788*f3e7f55eSRobert Mustacchi     that is referenced by ownerdie.
789*f3e7f55eSRobert Mustacchi 
790*f3e7f55eSRobert Mustacchi     For reference attributes, the ar_data and ar_nbytes
791*f3e7f55eSRobert Mustacchi     are not needed.  Instead, the ar_ref_die points to
792*f3e7f55eSRobert Mustacchi     the other die, and its di_offset value is used as
793*f3e7f55eSRobert Mustacchi     the reference value.
794*f3e7f55eSRobert Mustacchi */
795*f3e7f55eSRobert Mustacchi Dwarf_P_Attribute
dwarf_add_AT_reference(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_P_Die otherdie,Dwarf_Error * error)796*f3e7f55eSRobert Mustacchi dwarf_add_AT_reference(Dwarf_P_Debug dbg,
797*f3e7f55eSRobert Mustacchi                        Dwarf_P_Die ownerdie,
798*f3e7f55eSRobert Mustacchi                        Dwarf_Half attr,
799*f3e7f55eSRobert Mustacchi                        Dwarf_P_Die otherdie, Dwarf_Error * error)
800*f3e7f55eSRobert Mustacchi {
801*f3e7f55eSRobert Mustacchi     Dwarf_P_Attribute new_attr;
802*f3e7f55eSRobert Mustacchi 
803*f3e7f55eSRobert Mustacchi     if (dbg == NULL) {
804*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
805*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
806*f3e7f55eSRobert Mustacchi     }
807*f3e7f55eSRobert Mustacchi 
808*f3e7f55eSRobert Mustacchi     if (ownerdie == NULL) {
809*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
810*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
811*f3e7f55eSRobert Mustacchi     }
812*f3e7f55eSRobert Mustacchi 
813*f3e7f55eSRobert Mustacchi     if (otherdie == NULL) {
814*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
815*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
816*f3e7f55eSRobert Mustacchi     }
817*f3e7f55eSRobert Mustacchi 
818*f3e7f55eSRobert Mustacchi     switch (attr) {
819*f3e7f55eSRobert Mustacchi     case DW_AT_specification:
820*f3e7f55eSRobert Mustacchi     case DW_AT_discr:
821*f3e7f55eSRobert Mustacchi     case DW_AT_common_reference:
822*f3e7f55eSRobert Mustacchi     case DW_AT_import:
823*f3e7f55eSRobert Mustacchi     case DW_AT_containing_type:
824*f3e7f55eSRobert Mustacchi     case DW_AT_default_value:
825*f3e7f55eSRobert Mustacchi     case DW_AT_abstract_origin:
826*f3e7f55eSRobert Mustacchi     case DW_AT_friend:
827*f3e7f55eSRobert Mustacchi     case DW_AT_priority:
828*f3e7f55eSRobert Mustacchi     case DW_AT_type:
829*f3e7f55eSRobert Mustacchi     case DW_AT_lower_bound:
830*f3e7f55eSRobert Mustacchi     case DW_AT_upper_bound:
831*f3e7f55eSRobert Mustacchi     case DW_AT_count:
832*f3e7f55eSRobert Mustacchi     case DW_AT_associated:
833*f3e7f55eSRobert Mustacchi     case DW_AT_allocated:
834*f3e7f55eSRobert Mustacchi     case DW_AT_bit_offset:
835*f3e7f55eSRobert Mustacchi     case DW_AT_bit_size:
836*f3e7f55eSRobert Mustacchi     case DW_AT_byte_size:
837*f3e7f55eSRobert Mustacchi     case DW_AT_sibling:
838*f3e7f55eSRobert Mustacchi     case DW_AT_bit_stride:
839*f3e7f55eSRobert Mustacchi     case DW_AT_byte_stride:
840*f3e7f55eSRobert Mustacchi     case DW_AT_namelist_item:
841*f3e7f55eSRobert Mustacchi         break;
842*f3e7f55eSRobert Mustacchi 
843*f3e7f55eSRobert Mustacchi     default:
844*f3e7f55eSRobert Mustacchi         if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
845*f3e7f55eSRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
846*f3e7f55eSRobert Mustacchi             return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
847*f3e7f55eSRobert Mustacchi         }
848*f3e7f55eSRobert Mustacchi         break;
849*f3e7f55eSRobert Mustacchi     }
850*f3e7f55eSRobert Mustacchi 
851*f3e7f55eSRobert Mustacchi     new_attr = (Dwarf_P_Attribute)
852*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
853*f3e7f55eSRobert Mustacchi     if (new_attr == NULL) {
854*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
855*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
856*f3e7f55eSRobert Mustacchi     }
857*f3e7f55eSRobert Mustacchi 
858*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute = attr;
859*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute_form = dbg->de_ar_ref_attr_form;
860*f3e7f55eSRobert Mustacchi     new_attr->ar_nbytes = dbg->de_offset_size;
861*f3e7f55eSRobert Mustacchi     new_attr->ar_reloc_len = dbg->de_offset_size;
862*f3e7f55eSRobert Mustacchi     new_attr->ar_ref_die = otherdie;
863*f3e7f55eSRobert Mustacchi     new_attr->ar_rel_type = R_MIPS_NONE;
864*f3e7f55eSRobert Mustacchi     new_attr->ar_next = 0;
865*f3e7f55eSRobert Mustacchi 
866*f3e7f55eSRobert Mustacchi     /* add attribute to the die */
867*f3e7f55eSRobert Mustacchi     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
868*f3e7f55eSRobert Mustacchi     return new_attr;
869*f3e7f55eSRobert Mustacchi }
870*f3e7f55eSRobert Mustacchi 
871*f3e7f55eSRobert Mustacchi 
872*f3e7f55eSRobert Mustacchi /*
873*f3e7f55eSRobert Mustacchi     This function adds attributes of the flag class.
874*f3e7f55eSRobert Mustacchi */
875*f3e7f55eSRobert Mustacchi Dwarf_P_Attribute
dwarf_add_AT_flag(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Small flag,Dwarf_Error * error)876*f3e7f55eSRobert Mustacchi dwarf_add_AT_flag(Dwarf_P_Debug dbg,
877*f3e7f55eSRobert Mustacchi                   Dwarf_P_Die ownerdie,
878*f3e7f55eSRobert Mustacchi                   Dwarf_Half attr,
879*f3e7f55eSRobert Mustacchi                   Dwarf_Small flag, Dwarf_Error * error)
880*f3e7f55eSRobert Mustacchi {
881*f3e7f55eSRobert Mustacchi     Dwarf_P_Attribute new_attr;
882*f3e7f55eSRobert Mustacchi 
883*f3e7f55eSRobert Mustacchi     if (dbg == NULL) {
884*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
885*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
886*f3e7f55eSRobert Mustacchi     }
887*f3e7f55eSRobert Mustacchi 
888*f3e7f55eSRobert Mustacchi     if (ownerdie == NULL) {
889*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
890*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
891*f3e7f55eSRobert Mustacchi     }
892*f3e7f55eSRobert Mustacchi 
893*f3e7f55eSRobert Mustacchi #if 0
894*f3e7f55eSRobert Mustacchi     switch (attr) {
895*f3e7f55eSRobert Mustacchi     case DW_AT_is_optional:
896*f3e7f55eSRobert Mustacchi     case DW_AT_artificial:
897*f3e7f55eSRobert Mustacchi     case DW_AT_declaration:
898*f3e7f55eSRobert Mustacchi     case DW_AT_external:
899*f3e7f55eSRobert Mustacchi     case DW_AT_prototyped:
900*f3e7f55eSRobert Mustacchi     case DW_AT_variable_parameter:
901*f3e7f55eSRobert Mustacchi         break;
902*f3e7f55eSRobert Mustacchi 
903*f3e7f55eSRobert Mustacchi         default:
904*f3e7f55eSRobert Mustacchi             if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
905*f3e7f55eSRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
906*f3e7f55eSRobert Mustacchi             return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
907*f3e7f55eSRobert Mustacchi         }
908*f3e7f55eSRobert Mustacchi             break;
909*f3e7f55eSRobert Mustacchi     }
910*f3e7f55eSRobert Mustacchi #endif
911*f3e7f55eSRobert Mustacchi 
912*f3e7f55eSRobert Mustacchi     new_attr = (Dwarf_P_Attribute)
913*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
914*f3e7f55eSRobert Mustacchi     if (new_attr == NULL) {
915*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
916*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
917*f3e7f55eSRobert Mustacchi     }
918*f3e7f55eSRobert Mustacchi 
919*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute = attr;
920*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute_form = DW_FORM_flag;
921*f3e7f55eSRobert Mustacchi     new_attr->ar_nbytes = 1;
922*f3e7f55eSRobert Mustacchi     new_attr->ar_reloc_len = 0; /* not used */
923*f3e7f55eSRobert Mustacchi     new_attr->ar_rel_type = R_MIPS_NONE;
924*f3e7f55eSRobert Mustacchi     new_attr->ar_next = 0;
925*f3e7f55eSRobert Mustacchi 
926*f3e7f55eSRobert Mustacchi     new_attr->ar_data = (char *)
927*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(dbg, 1);
928*f3e7f55eSRobert Mustacchi     if (new_attr->ar_data == NULL) {
929*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
930*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
931*f3e7f55eSRobert Mustacchi     }
932*f3e7f55eSRobert Mustacchi     memcpy(new_attr->ar_data, &flag, 1);
933*f3e7f55eSRobert Mustacchi 
934*f3e7f55eSRobert Mustacchi     /* add attribute to the die */
935*f3e7f55eSRobert Mustacchi     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
936*f3e7f55eSRobert Mustacchi     return new_attr;
937*f3e7f55eSRobert Mustacchi }
938*f3e7f55eSRobert Mustacchi 
939*f3e7f55eSRobert Mustacchi 
940*f3e7f55eSRobert Mustacchi /*
941*f3e7f55eSRobert Mustacchi     This function adds values of attributes
942*f3e7f55eSRobert Mustacchi     belonging to the string class.
943*f3e7f55eSRobert Mustacchi */
944*f3e7f55eSRobert Mustacchi Dwarf_P_Attribute
dwarf_add_AT_string(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,char * string,Dwarf_Error * error)945*f3e7f55eSRobert Mustacchi dwarf_add_AT_string(Dwarf_P_Debug dbg,
946*f3e7f55eSRobert Mustacchi                     Dwarf_P_Die ownerdie,
947*f3e7f55eSRobert Mustacchi                     Dwarf_Half attr, char *string, Dwarf_Error * error)
948*f3e7f55eSRobert Mustacchi {
949*f3e7f55eSRobert Mustacchi     Dwarf_P_Attribute new_attr;
950*f3e7f55eSRobert Mustacchi 
951*f3e7f55eSRobert Mustacchi     if (dbg == NULL) {
952*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
953*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
954*f3e7f55eSRobert Mustacchi     }
955*f3e7f55eSRobert Mustacchi 
956*f3e7f55eSRobert Mustacchi     if (ownerdie == NULL) {
957*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
958*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
959*f3e7f55eSRobert Mustacchi     }
960*f3e7f55eSRobert Mustacchi 
961*f3e7f55eSRobert Mustacchi     new_attr = (Dwarf_P_Attribute)
962*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
963*f3e7f55eSRobert Mustacchi     if (new_attr == NULL) {
964*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
965*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
966*f3e7f55eSRobert Mustacchi     }
967*f3e7f55eSRobert Mustacchi 
968*f3e7f55eSRobert Mustacchi     switch (attr) {
969*f3e7f55eSRobert Mustacchi     case DW_AT_name:
970*f3e7f55eSRobert Mustacchi     case DW_AT_comp_dir:
971*f3e7f55eSRobert Mustacchi     case DW_AT_const_value:
972*f3e7f55eSRobert Mustacchi     case DW_AT_producer:
973*f3e7f55eSRobert Mustacchi         break;
974*f3e7f55eSRobert Mustacchi 
975*f3e7f55eSRobert Mustacchi         default:
976*f3e7f55eSRobert Mustacchi             if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
977*f3e7f55eSRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
978*f3e7f55eSRobert Mustacchi             return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
979*f3e7f55eSRobert Mustacchi         }
980*f3e7f55eSRobert Mustacchi             break;
981*f3e7f55eSRobert Mustacchi     }
982*f3e7f55eSRobert Mustacchi 
983*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute = attr;
984*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute_form = DW_FORM_string;
985*f3e7f55eSRobert Mustacchi     new_attr->ar_nbytes = strlen(string) + 1;
986*f3e7f55eSRobert Mustacchi     new_attr->ar_next = 0;
987*f3e7f55eSRobert Mustacchi 
988*f3e7f55eSRobert Mustacchi     new_attr->ar_data =
989*f3e7f55eSRobert Mustacchi         (char *) _dwarf_p_get_alloc(dbg, strlen(string)+1);
990*f3e7f55eSRobert Mustacchi     if (new_attr->ar_data == NULL) {
991*f3e7f55eSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
992*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
993*f3e7f55eSRobert Mustacchi     }
994*f3e7f55eSRobert Mustacchi 
995*f3e7f55eSRobert Mustacchi     strcpy(new_attr->ar_data, string);
996*f3e7f55eSRobert Mustacchi     new_attr->ar_rel_type = R_MIPS_NONE;
997*f3e7f55eSRobert Mustacchi     new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
998*f3e7f55eSRobert Mustacchi 
999*f3e7f55eSRobert Mustacchi     /* add attribute to the die */
1000*f3e7f55eSRobert Mustacchi     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1001*f3e7f55eSRobert Mustacchi     return new_attr;
1002*f3e7f55eSRobert Mustacchi }
1003*f3e7f55eSRobert Mustacchi 
1004*f3e7f55eSRobert Mustacchi 
1005*f3e7f55eSRobert Mustacchi Dwarf_P_Attribute
dwarf_add_AT_const_value_string(Dwarf_P_Die ownerdie,char * string_value,Dwarf_Error * error)1006*f3e7f55eSRobert Mustacchi dwarf_add_AT_const_value_string(Dwarf_P_Die ownerdie,
1007*f3e7f55eSRobert Mustacchi                                 char *string_value, Dwarf_Error * error)
1008*f3e7f55eSRobert Mustacchi {
1009*f3e7f55eSRobert Mustacchi     Dwarf_P_Attribute new_attr;
1010*f3e7f55eSRobert Mustacchi 
1011*f3e7f55eSRobert Mustacchi     if (ownerdie == NULL) {
1012*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
1013*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1014*f3e7f55eSRobert Mustacchi     }
1015*f3e7f55eSRobert Mustacchi 
1016*f3e7f55eSRobert Mustacchi     new_attr = (Dwarf_P_Attribute)
1017*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
1018*f3e7f55eSRobert Mustacchi     if (new_attr == NULL) {
1019*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1020*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1021*f3e7f55eSRobert Mustacchi     }
1022*f3e7f55eSRobert Mustacchi 
1023*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute = DW_AT_const_value;
1024*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute_form = DW_FORM_string;
1025*f3e7f55eSRobert Mustacchi     new_attr->ar_nbytes = strlen(string_value) + 1;
1026*f3e7f55eSRobert Mustacchi     new_attr->ar_next = 0;
1027*f3e7f55eSRobert Mustacchi 
1028*f3e7f55eSRobert Mustacchi     new_attr->ar_data =
1029*f3e7f55eSRobert Mustacchi         (char *) _dwarf_p_get_alloc(ownerdie->di_dbg, strlen(string_value)+1);
1030*f3e7f55eSRobert Mustacchi     if (new_attr->ar_data == NULL) {
1031*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1032*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1033*f3e7f55eSRobert Mustacchi     }
1034*f3e7f55eSRobert Mustacchi 
1035*f3e7f55eSRobert Mustacchi     strcpy(new_attr->ar_data, string_value);
1036*f3e7f55eSRobert Mustacchi     new_attr->ar_rel_type = R_MIPS_NONE;
1037*f3e7f55eSRobert Mustacchi     new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
1038*f3e7f55eSRobert Mustacchi 
1039*f3e7f55eSRobert Mustacchi     /* add attribute to the die */
1040*f3e7f55eSRobert Mustacchi     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1041*f3e7f55eSRobert Mustacchi     return new_attr;
1042*f3e7f55eSRobert Mustacchi }
1043*f3e7f55eSRobert Mustacchi 
1044*f3e7f55eSRobert Mustacchi 
1045*f3e7f55eSRobert Mustacchi Dwarf_P_Attribute
dwarf_add_AT_producer(Dwarf_P_Die ownerdie,char * producer_string,Dwarf_Error * error)1046*f3e7f55eSRobert Mustacchi dwarf_add_AT_producer(Dwarf_P_Die ownerdie,
1047*f3e7f55eSRobert Mustacchi                       char *producer_string, Dwarf_Error * error)
1048*f3e7f55eSRobert Mustacchi {
1049*f3e7f55eSRobert Mustacchi     Dwarf_P_Attribute new_attr;
1050*f3e7f55eSRobert Mustacchi 
1051*f3e7f55eSRobert Mustacchi     if (ownerdie == NULL) {
1052*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
1053*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1054*f3e7f55eSRobert Mustacchi     }
1055*f3e7f55eSRobert Mustacchi 
1056*f3e7f55eSRobert Mustacchi     new_attr = (Dwarf_P_Attribute)
1057*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
1058*f3e7f55eSRobert Mustacchi     if (new_attr == NULL) {
1059*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1060*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1061*f3e7f55eSRobert Mustacchi     }
1062*f3e7f55eSRobert Mustacchi 
1063*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute = DW_AT_producer;
1064*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute_form = DW_FORM_string;
1065*f3e7f55eSRobert Mustacchi     new_attr->ar_nbytes = strlen(producer_string) + 1;
1066*f3e7f55eSRobert Mustacchi     new_attr->ar_next = 0;
1067*f3e7f55eSRobert Mustacchi 
1068*f3e7f55eSRobert Mustacchi     new_attr->ar_data =
1069*f3e7f55eSRobert Mustacchi         (char *) _dwarf_p_get_alloc(ownerdie->di_dbg, strlen(producer_string)+1);
1070*f3e7f55eSRobert Mustacchi     if (new_attr->ar_data == NULL) {
1071*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1072*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1073*f3e7f55eSRobert Mustacchi     }
1074*f3e7f55eSRobert Mustacchi 
1075*f3e7f55eSRobert Mustacchi     strcpy(new_attr->ar_data, producer_string);
1076*f3e7f55eSRobert Mustacchi     new_attr->ar_rel_type = R_MIPS_NONE;
1077*f3e7f55eSRobert Mustacchi     new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
1078*f3e7f55eSRobert Mustacchi 
1079*f3e7f55eSRobert Mustacchi     /* add attribute to the die */
1080*f3e7f55eSRobert Mustacchi     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1081*f3e7f55eSRobert Mustacchi     return new_attr;
1082*f3e7f55eSRobert Mustacchi }
1083*f3e7f55eSRobert Mustacchi 
1084*f3e7f55eSRobert Mustacchi 
1085*f3e7f55eSRobert Mustacchi Dwarf_P_Attribute
dwarf_add_AT_const_value_signedint(Dwarf_P_Die ownerdie,Dwarf_Signed signed_value,Dwarf_Error * error)1086*f3e7f55eSRobert Mustacchi dwarf_add_AT_const_value_signedint(Dwarf_P_Die ownerdie,
1087*f3e7f55eSRobert Mustacchi                                    Dwarf_Signed signed_value,
1088*f3e7f55eSRobert Mustacchi                                    Dwarf_Error * error)
1089*f3e7f55eSRobert Mustacchi {
1090*f3e7f55eSRobert Mustacchi     Dwarf_P_Attribute new_attr;
1091*f3e7f55eSRobert Mustacchi     int leb_size;
1092*f3e7f55eSRobert Mustacchi     char encode_buffer[ENCODE_SPACE_NEEDED];
1093*f3e7f55eSRobert Mustacchi     int res;
1094*f3e7f55eSRobert Mustacchi 
1095*f3e7f55eSRobert Mustacchi     if (ownerdie == NULL) {
1096*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
1097*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1098*f3e7f55eSRobert Mustacchi     }
1099*f3e7f55eSRobert Mustacchi 
1100*f3e7f55eSRobert Mustacchi     new_attr = (Dwarf_P_Attribute)
1101*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
1102*f3e7f55eSRobert Mustacchi     if (new_attr == NULL) {
1103*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1104*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1105*f3e7f55eSRobert Mustacchi     }
1106*f3e7f55eSRobert Mustacchi 
1107*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute = DW_AT_const_value;
1108*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute_form = DW_FORM_sdata;
1109*f3e7f55eSRobert Mustacchi     new_attr->ar_rel_type = R_MIPS_NONE;
1110*f3e7f55eSRobert Mustacchi     new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
1111*f3e7f55eSRobert Mustacchi     new_attr->ar_next = 0;
1112*f3e7f55eSRobert Mustacchi 
1113*f3e7f55eSRobert Mustacchi     res = _dwarf_pro_encode_signed_leb128_nm(signed_value, &leb_size,
1114*f3e7f55eSRobert Mustacchi                                              encode_buffer,
1115*f3e7f55eSRobert Mustacchi                                              sizeof(encode_buffer));
1116*f3e7f55eSRobert Mustacchi     if (res != DW_DLV_OK) {
1117*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1118*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1119*f3e7f55eSRobert Mustacchi     }
1120*f3e7f55eSRobert Mustacchi     new_attr->ar_data = (char *)
1121*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(ownerdie->di_dbg, leb_size);
1122*f3e7f55eSRobert Mustacchi     if (new_attr->ar_data == NULL) {
1123*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1124*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1125*f3e7f55eSRobert Mustacchi     }
1126*f3e7f55eSRobert Mustacchi     memcpy(new_attr->ar_data, encode_buffer, leb_size);
1127*f3e7f55eSRobert Mustacchi     new_attr->ar_nbytes = leb_size;
1128*f3e7f55eSRobert Mustacchi 
1129*f3e7f55eSRobert Mustacchi     /* add attribute to the die */
1130*f3e7f55eSRobert Mustacchi     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1131*f3e7f55eSRobert Mustacchi     return new_attr;
1132*f3e7f55eSRobert Mustacchi }
1133*f3e7f55eSRobert Mustacchi 
1134*f3e7f55eSRobert Mustacchi 
1135*f3e7f55eSRobert Mustacchi Dwarf_P_Attribute
dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die ownerdie,Dwarf_Unsigned unsigned_value,Dwarf_Error * error)1136*f3e7f55eSRobert Mustacchi dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die ownerdie,
1137*f3e7f55eSRobert Mustacchi                                      Dwarf_Unsigned unsigned_value,
1138*f3e7f55eSRobert Mustacchi                                      Dwarf_Error * error)
1139*f3e7f55eSRobert Mustacchi {
1140*f3e7f55eSRobert Mustacchi     Dwarf_P_Attribute new_attr;
1141*f3e7f55eSRobert Mustacchi     int leb_size;
1142*f3e7f55eSRobert Mustacchi     char encode_buffer[ENCODE_SPACE_NEEDED];
1143*f3e7f55eSRobert Mustacchi     int res;
1144*f3e7f55eSRobert Mustacchi 
1145*f3e7f55eSRobert Mustacchi     if (ownerdie == NULL) {
1146*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
1147*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1148*f3e7f55eSRobert Mustacchi     }
1149*f3e7f55eSRobert Mustacchi 
1150*f3e7f55eSRobert Mustacchi     new_attr = (Dwarf_P_Attribute)
1151*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
1152*f3e7f55eSRobert Mustacchi     if (new_attr == NULL) {
1153*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1154*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1155*f3e7f55eSRobert Mustacchi     }
1156*f3e7f55eSRobert Mustacchi 
1157*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute = DW_AT_const_value;
1158*f3e7f55eSRobert Mustacchi     new_attr->ar_attribute_form = DW_FORM_udata;
1159*f3e7f55eSRobert Mustacchi     new_attr->ar_rel_type = R_MIPS_NONE;
1160*f3e7f55eSRobert Mustacchi     new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
1161*f3e7f55eSRobert Mustacchi     new_attr->ar_next = 0;
1162*f3e7f55eSRobert Mustacchi 
1163*f3e7f55eSRobert Mustacchi     res = _dwarf_pro_encode_leb128_nm(unsigned_value, &leb_size,
1164*f3e7f55eSRobert Mustacchi                                       encode_buffer,
1165*f3e7f55eSRobert Mustacchi                                       sizeof(encode_buffer));
1166*f3e7f55eSRobert Mustacchi     if (res != DW_DLV_OK) {
1167*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1168*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1169*f3e7f55eSRobert Mustacchi     }
1170*f3e7f55eSRobert Mustacchi     new_attr->ar_data = (char *)
1171*f3e7f55eSRobert Mustacchi         _dwarf_p_get_alloc(ownerdie->di_dbg, leb_size);
1172*f3e7f55eSRobert Mustacchi     if (new_attr->ar_data == NULL) {
1173*f3e7f55eSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1174*f3e7f55eSRobert Mustacchi         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1175*f3e7f55eSRobert Mustacchi     }
1176*f3e7f55eSRobert Mustacchi     memcpy(new_attr->ar_data, encode_buffer, leb_size);
1177*f3e7f55eSRobert Mustacchi     new_attr->ar_nbytes = leb_size;
1178*f3e7f55eSRobert Mustacchi 
1179*f3e7f55eSRobert Mustacchi     /* add attribute to the die */
1180*f3e7f55eSRobert Mustacchi     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1181*f3e7f55eSRobert Mustacchi     return new_attr;
1182*f3e7f55eSRobert Mustacchi }
1183