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
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*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
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*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
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*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
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*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 *
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*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
dwarf_dealloc_compressed_block(Dwarf_P_Debug dbg,void * space)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
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*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
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*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
dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Unsigned value,Dwarf_Error * error)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
dwarf_add_AT_signed_const(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Signed value,Dwarf_Error * error)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
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*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
dwarf_add_AT_reference(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_P_Die otherdie,Dwarf_Error * error)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
dwarf_add_AT_flag(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Small flag,Dwarf_Error * error)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
dwarf_add_AT_string(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,char * string,Dwarf_Error * error)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
dwarf_add_AT_const_value_string(Dwarf_P_Die ownerdie,char * string_value,Dwarf_Error * error)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
dwarf_add_AT_producer(Dwarf_P_Die ownerdie,char * producer_string,Dwarf_Error * error)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
dwarf_add_AT_const_value_signedint(Dwarf_P_Die ownerdie,Dwarf_Signed signed_value,Dwarf_Error * error)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
dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die ownerdie,Dwarf_Unsigned unsigned_value,Dwarf_Error * error)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