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