1 /*-
2 * Copyright (c) 2009 Kai Wang
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27 #include "_libdwarf.h"
28
29 ELFTC_VCSID("$Id: dwarf_pro_attr.c 2074 2011-10-27 03:34:33Z jkoshy $");
30
31 Dwarf_P_Attribute
dwarf_add_AT_location_expr(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_Half attr,Dwarf_P_Expr loc_expr,Dwarf_Error * error)32 dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
33 Dwarf_P_Expr loc_expr, Dwarf_Error *error)
34 {
35 Dwarf_Attribute at;
36
37 if (dbg == NULL || die == NULL || loc_expr == NULL) {
38 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
39 return (DW_DLV_BADADDR);
40 }
41
42 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE)
43 return (DW_DLV_BADADDR);
44
45 at->at_die = die;
46 at->at_attrib = attr;
47 at->at_expr = loc_expr;
48
49 if (_dwarf_expr_into_block(loc_expr, error) != DW_DLE_NONE) {
50 free(at);
51 return (DW_DLV_BADADDR);
52 }
53 at->u[0].u64 = loc_expr->pe_length;
54 at->u[1].u8p = loc_expr->pe_block;
55 if (loc_expr->pe_length <= UCHAR_MAX)
56 at->at_form = DW_FORM_block1;
57 else if (loc_expr->pe_length <= USHRT_MAX)
58 at->at_form = DW_FORM_block2;
59 else if (loc_expr->pe_length <= UINT_MAX)
60 at->at_form = DW_FORM_block4;
61 else
62 at->at_form = DW_FORM_block;
63
64 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next);
65
66 return (at);
67 }
68
69 Dwarf_P_Attribute
dwarf_add_AT_name(Dwarf_P_Die die,char * name,Dwarf_Error * error)70 dwarf_add_AT_name(Dwarf_P_Die die, char *name, Dwarf_Error *error)
71 {
72 Dwarf_Attribute at;
73
74 if (_dwarf_add_string_attr(die, &at, DW_AT_name, name, error) !=
75 DW_DLE_NONE)
76 return (DW_DLV_BADADDR);
77
78 return (at);
79 }
80
81 Dwarf_P_Attribute
dwarf_add_AT_comp_dir(Dwarf_P_Die die,char * dir,Dwarf_Error * error)82 dwarf_add_AT_comp_dir(Dwarf_P_Die die, char *dir, Dwarf_Error *error)
83 {
84 Dwarf_Attribute at;
85
86 if (_dwarf_add_string_attr(die, &at, DW_AT_comp_dir, dir, error) !=
87 DW_DLE_NONE)
88 return (DW_DLV_BADADDR);
89
90 return (at);
91 }
92
93 Dwarf_P_Attribute
dwarf_add_AT_producer(Dwarf_P_Die die,char * producer,Dwarf_Error * error)94 dwarf_add_AT_producer(Dwarf_P_Die die, char *producer, Dwarf_Error *error)
95 {
96 Dwarf_Attribute at;
97
98 if (_dwarf_add_string_attr(die, &at, DW_AT_producer, producer, error) !=
99 DW_DLE_NONE)
100 return (DW_DLV_BADADDR);
101
102 return (at);
103 }
104
105 Dwarf_P_Attribute
dwarf_add_AT_const_value_signedint(Dwarf_P_Die die,Dwarf_Signed value,Dwarf_Error * error)106 dwarf_add_AT_const_value_signedint(Dwarf_P_Die die, Dwarf_Signed value,
107 Dwarf_Error *error)
108 {
109 Dwarf_Attribute at;
110 Dwarf_Debug dbg;
111
112 dbg = die != NULL ? die->die_dbg : NULL;
113
114 if (die == NULL) {
115 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
116 return (DW_DLV_BADADDR);
117 }
118
119 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE)
120 return (DW_DLV_BADADDR);
121
122 at->at_die = die;
123 at->at_attrib = DW_AT_const_value;
124 at->at_form = DW_FORM_sdata;
125 at->u[0].s64 = value;
126
127 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next);
128
129 return (at);
130 }
131
132 Dwarf_P_Attribute
dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die die,Dwarf_Unsigned value,Dwarf_Error * error)133 dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die die, Dwarf_Unsigned value,
134 Dwarf_Error *error)
135 {
136 Dwarf_Attribute at;
137 Dwarf_Debug dbg;
138
139 dbg = die != NULL ? die->die_dbg : NULL;
140
141 if (die == NULL) {
142 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
143 return (DW_DLV_BADADDR);
144 }
145
146 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE)
147 return (DW_DLV_BADADDR);
148
149 at->at_die = die;
150 at->at_attrib = DW_AT_const_value;
151 at->at_form = DW_FORM_udata;
152 at->u[0].u64 = value;
153
154 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next);
155
156 return (at);
157 }
158
159 Dwarf_P_Attribute
dwarf_add_AT_const_value_string(Dwarf_P_Die die,char * string,Dwarf_Error * error)160 dwarf_add_AT_const_value_string(Dwarf_P_Die die, char *string,
161 Dwarf_Error *error)
162 {
163 Dwarf_Attribute at;
164
165 if (_dwarf_add_string_attr(die, &at, DW_AT_const_value, string,
166 error) != DW_DLE_NONE)
167 return (DW_DLV_BADADDR);
168
169 return (at);
170 }
171
172 Dwarf_P_Attribute
dwarf_add_AT_targ_address(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_Half attr,Dwarf_Unsigned pc_value,Dwarf_Signed sym_index,Dwarf_Error * error)173 dwarf_add_AT_targ_address(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
174 Dwarf_Unsigned pc_value, Dwarf_Signed sym_index, Dwarf_Error *error)
175 {
176
177 return (dwarf_add_AT_targ_address_b(dbg, die, attr, pc_value, sym_index,
178 error));
179 }
180
181 Dwarf_P_Attribute
dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_Half attr,Dwarf_Unsigned pc_value,Dwarf_Unsigned sym_index,Dwarf_Error * error)182 dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
183 Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error)
184 {
185 Dwarf_Attribute at;
186
187 if (dbg == NULL || die == NULL) {
188 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
189 return (DW_DLV_BADADDR);
190 }
191
192 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE)
193 return (DW_DLV_BADADDR);
194
195 at->at_die = die;
196 at->at_attrib = attr;
197 at->at_form = DW_FORM_addr;
198 at->at_relsym = sym_index;
199 at->u[0].u64 = pc_value;
200
201 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next);
202
203 return (at);
204 }
205
206 Dwarf_P_Attribute
dwarf_add_AT_dataref(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_Half attr,Dwarf_Unsigned pc_value,Dwarf_Unsigned sym_index,Dwarf_Error * error)207 dwarf_add_AT_dataref(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
208 Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error)
209 {
210 Dwarf_Attribute at;
211 int ret;
212
213 if (dbg == NULL || die == NULL) {
214 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
215 return (DW_DLV_BADADDR);
216 }
217
218 ret = _dwarf_add_AT_dataref(dbg, die, attr, pc_value, sym_index,
219 NULL, &at, error);
220 if (ret != DW_DLE_NONE)
221 return (DW_DLV_BADADDR);
222
223 return (at);
224
225 }
226
227 Dwarf_P_Attribute
dwarf_add_AT_ref_address(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_Half attr,Dwarf_Unsigned pc_value,Dwarf_Unsigned sym_index,Dwarf_Error * error)228 dwarf_add_AT_ref_address(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
229 Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error)
230 {
231 Dwarf_Attribute at;
232
233 if (dbg == NULL || die == NULL) {
234 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
235 return (DW_DLV_BADADDR);
236 }
237
238 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE)
239 return (DW_DLV_BADADDR);
240
241 at->at_die = die;
242 at->at_attrib = attr;
243 at->at_form = DW_FORM_ref_addr;
244 at->at_relsym = sym_index;
245 at->u[0].u64 = pc_value;
246
247 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next);
248
249 return (at);
250 }
251
252 Dwarf_P_Attribute
dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_Half attr,Dwarf_Unsigned value,Dwarf_Error * error)253 dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
254 Dwarf_Unsigned value, Dwarf_Error *error)
255 {
256 Dwarf_Attribute at;
257
258 if (dbg == NULL || die == NULL) {
259 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
260 return (DW_DLV_BADADDR);
261 }
262
263 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE)
264 return (DW_DLV_BADADDR);
265
266 at->at_die = die;
267 at->at_attrib = attr;
268 at->u[0].u64 = value;
269
270 if (value <= UCHAR_MAX)
271 at->at_form = DW_FORM_data1;
272 else if (value <= USHRT_MAX)
273 at->at_form = DW_FORM_data2;
274 else if (value <= UINT_MAX)
275 at->at_form = DW_FORM_data4;
276 else
277 at->at_form = DW_FORM_data8;
278
279 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next);
280
281 return (at);
282 }
283
284 Dwarf_P_Attribute
dwarf_add_AT_signed_const(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_Half attr,Dwarf_Signed value,Dwarf_Error * error)285 dwarf_add_AT_signed_const(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
286 Dwarf_Signed value, Dwarf_Error *error)
287 {
288 Dwarf_Attribute at;
289
290 if (dbg == NULL || die == NULL) {
291 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
292 return (DW_DLV_BADADDR);
293 }
294
295 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE)
296 return (DW_DLV_BADADDR);
297
298 at->at_die = die;
299 at->at_attrib = attr;
300 at->u[0].u64 = value;
301
302 if (value >= SCHAR_MIN && value <= SCHAR_MAX)
303 at->at_form = DW_FORM_data1;
304 else if (value >= SHRT_MIN && value <= SHRT_MAX)
305 at->at_form = DW_FORM_data2;
306 else if (value >= INT_MIN && value <= INT_MAX)
307 at->at_form = DW_FORM_data4;
308 else
309 at->at_form = DW_FORM_data8;
310
311 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next);
312
313 return (at);
314 }
315
316 Dwarf_P_Attribute
dwarf_add_AT_reference(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_Half attr,Dwarf_P_Die ref_die,Dwarf_Error * error)317 dwarf_add_AT_reference(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
318 Dwarf_P_Die ref_die, Dwarf_Error *error)
319 {
320 Dwarf_Attribute at;
321
322 if (dbg == NULL || die == NULL) {
323 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
324 return (DW_DLV_BADADDR);
325 }
326
327 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE)
328 return (DW_DLV_BADADDR);
329
330 at->at_die = die;
331 at->at_attrib = attr;
332 if (dbg->dbg_offset_size == 4)
333 at->at_form = DW_FORM_ref4;
334 else
335 at->at_form = DW_FORM_ref8;
336
337 at->at_refdie = ref_die;
338
339 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next);
340
341 return (at);
342 }
343
344 Dwarf_P_Attribute
dwarf_add_AT_flag(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_Half attr,Dwarf_Small flag,Dwarf_Error * error)345 dwarf_add_AT_flag(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
346 Dwarf_Small flag, Dwarf_Error *error)
347 {
348 Dwarf_Attribute at;
349
350 if (dbg == NULL || die == NULL) {
351 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
352 return (DW_DLV_BADADDR);
353 }
354
355 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE)
356 return (DW_DLV_BADADDR);
357
358 at->at_die = die;
359 at->at_attrib = attr;
360 at->at_form = DW_FORM_flag;
361 at->u[0].u64 = flag ? 1 : 0;
362
363 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next);
364
365 return (at);
366 }
367
368 Dwarf_P_Attribute
dwarf_add_AT_string(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_Half attr,char * string,Dwarf_Error * error)369 dwarf_add_AT_string(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
370 char *string, Dwarf_Error *error)
371 {
372 Dwarf_Attribute at;
373
374 if (dbg == NULL || die == NULL) {
375 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
376 return (DW_DLV_BADADDR);
377 }
378
379 /* XXX Add DW_FORM_string style string instead? */
380
381 if (_dwarf_add_string_attr(die, &at, attr, string, error) !=
382 DW_DLE_NONE)
383 return (DW_DLV_BADADDR);
384
385 return (at);
386 }
387