]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/elftoolchain/libdwarf/dwarf_pro_attr.c
MFV r361938:
[FreeBSD/FreeBSD.git] / contrib / elftoolchain / libdwarf / dwarf_pro_attr.c
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }