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