]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/elftoolchain/libdwarf/dwarf_form.c
libelftc: add RISC-V bfd targets
[FreeBSD/FreeBSD.git] / contrib / elftoolchain / libdwarf / dwarf_form.c
1 /*-
2  * Copyright (c) 2007 John Birrell (jb@freebsd.org)
3  * Copyright (c) 2009,2010 Kai Wang
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27
28 #include "_libdwarf.h"
29
30 ELFTC_VCSID("$Id: dwarf_form.c 2073 2011-10-27 03:30:47Z jkoshy $");
31
32 int
33 dwarf_hasform(Dwarf_Attribute at, Dwarf_Half form, Dwarf_Bool *return_hasform,
34     Dwarf_Error *error)
35 {
36         Dwarf_Debug dbg;
37
38         dbg = at != NULL ? at->at_die->die_dbg : NULL;
39
40         if (at == NULL || return_hasform == NULL) {
41                 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
42                 return (DW_DLV_ERROR);
43         }
44
45         *return_hasform = (at->at_form == form);
46
47         return (DW_DLV_OK);
48 }
49
50 int
51 dwarf_whatform(Dwarf_Attribute at, Dwarf_Half *return_form, Dwarf_Error *error)
52 {
53         Dwarf_Debug dbg;
54
55         dbg = at != NULL ? at->at_die->die_dbg : NULL;
56
57         if (at == NULL || return_form == NULL) {
58                 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
59                 return (DW_DLV_ERROR);
60         }
61
62         *return_form = at->at_form;
63
64         return (DW_DLV_OK);
65 }
66
67 int
68 dwarf_whatform_direct(Dwarf_Attribute at, Dwarf_Half *return_form,
69     Dwarf_Error *error)
70 {
71         Dwarf_Debug dbg;
72
73         dbg = at != NULL ? at->at_die->die_dbg : NULL;
74
75         if (at == NULL || return_form == NULL) {
76                 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
77                 return (DW_DLV_ERROR);
78         }
79
80         if (at->at_indirect)
81                 *return_form = DW_FORM_indirect;
82         else
83                 *return_form = (Dwarf_Half) at->at_form;
84
85         return (DW_DLV_OK);
86 }
87
88 int
89 dwarf_whatattr(Dwarf_Attribute at, Dwarf_Half *return_attr, Dwarf_Error *error)
90 {
91         Dwarf_Debug dbg;
92
93         dbg = at != NULL ? at->at_die->die_dbg : NULL;
94
95         if (at == NULL || return_attr == NULL) {
96                 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
97                 return (DW_DLV_ERROR);
98         }
99
100         *return_attr = (Dwarf_Half) at->at_attrib;
101
102         return (DW_DLV_OK);
103 }
104
105 int
106 dwarf_formref(Dwarf_Attribute at, Dwarf_Off *return_offset, Dwarf_Error *error)
107 {
108         int ret;
109         Dwarf_Debug dbg;
110
111         dbg = at != NULL ? at->at_die->die_dbg : NULL;
112
113         if (at == NULL || return_offset == NULL) {
114                 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
115                 return (DW_DLV_ERROR);
116         }
117
118         switch (at->at_form) {
119         case DW_FORM_ref1:
120         case DW_FORM_ref2:
121         case DW_FORM_ref4:
122         case DW_FORM_ref8:
123         case DW_FORM_ref_udata:
124                 *return_offset = (Dwarf_Off) at->u[0].u64;
125                 ret = DW_DLV_OK;
126                 break;
127         default:
128                 DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
129                 ret = DW_DLV_ERROR;
130         }
131
132         return (ret);
133 }
134
135 int
136 dwarf_global_formref(Dwarf_Attribute at, Dwarf_Off *return_offset,
137     Dwarf_Error *error)
138 {
139         int ret;
140         Dwarf_Debug dbg;
141
142         dbg = at != NULL ? at->at_die->die_dbg : NULL;
143
144         if (at == NULL || return_offset == NULL) {
145                 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
146                 return (DW_DLV_ERROR);
147         }
148
149         switch (at->at_form) {
150         case DW_FORM_ref_addr:
151         case DW_FORM_sec_offset:
152                 *return_offset = (Dwarf_Off) at->u[0].u64;
153                 ret = DW_DLV_OK;
154                 break;
155         case DW_FORM_ref1:
156         case DW_FORM_ref2:
157         case DW_FORM_ref4:
158         case DW_FORM_ref8:
159         case DW_FORM_ref_udata:
160                 *return_offset = (Dwarf_Off) at->u[0].u64 +
161                         at->at_die->die_cu->cu_offset;
162                 ret = DW_DLV_OK;
163                 break;
164         default:
165                 DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
166                 ret = DW_DLV_ERROR;
167         }
168
169         return (ret);
170 }
171
172 int
173 dwarf_formaddr(Dwarf_Attribute at, Dwarf_Addr *return_addr, Dwarf_Error *error)
174 {
175         int ret;
176         Dwarf_Debug dbg;
177
178         dbg = at != NULL ? at->at_die->die_dbg : NULL;
179
180         if (at == NULL || return_addr == NULL) {
181                 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
182                 return (DW_DLV_ERROR);
183         }
184
185         if (at->at_form == DW_FORM_addr) {
186                 *return_addr = at->u[0].u64;
187                 ret = DW_DLV_OK;
188         } else {
189                 DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
190                 ret = DW_DLV_ERROR;
191         }
192
193         return (ret);
194 }
195
196 int
197 dwarf_formflag(Dwarf_Attribute at, Dwarf_Bool *return_bool, Dwarf_Error *error)
198 {
199         int ret;
200         Dwarf_Debug dbg;
201
202         dbg = at != NULL ? at->at_die->die_dbg : NULL;
203
204         if (at == NULL || return_bool == NULL) {
205                 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
206                 return (DW_DLV_ERROR);
207         }
208
209         if (at->at_form == DW_FORM_flag ||
210             at->at_form == DW_FORM_flag_present) {
211                 *return_bool = (Dwarf_Bool) (!!at->u[0].u64);
212                 ret = DW_DLV_OK;
213         } else {
214                 DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
215                 ret = DW_DLV_ERROR;
216         }
217
218         return (ret);
219 }
220
221 int
222 dwarf_formudata(Dwarf_Attribute at, Dwarf_Unsigned *return_uvalue,
223     Dwarf_Error *error)
224 {
225         int ret;
226         Dwarf_Debug dbg;
227
228         dbg = at != NULL ? at->at_die->die_dbg : NULL;
229
230         if (at == NULL || return_uvalue == NULL) {
231                 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
232                 return (DW_DLV_ERROR);
233         }
234
235         switch (at->at_form) {
236         case DW_FORM_data1:
237         case DW_FORM_data2:
238         case DW_FORM_data4:
239         case DW_FORM_data8:
240         case DW_FORM_udata:
241                 *return_uvalue = at->u[0].u64;
242                 ret = DW_DLV_OK;
243                 break;
244         default:
245                 DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
246                 ret = DW_DLV_ERROR;
247         }
248
249         return (ret);
250 }
251
252 int
253 dwarf_formsdata(Dwarf_Attribute at, Dwarf_Signed *return_svalue,
254     Dwarf_Error *error)
255 {
256         int ret;
257         Dwarf_Debug dbg;
258
259         dbg = at != NULL ? at->at_die->die_dbg : NULL;
260
261         if (at == NULL || return_svalue == NULL) {
262                 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
263                 return (DW_DLV_ERROR);
264         }
265
266         switch (at->at_form) {
267         case DW_FORM_data1:
268                 *return_svalue = (int8_t) at->u[0].s64;
269                 ret = DW_DLV_OK;
270                 break;
271         case DW_FORM_data2:
272                 *return_svalue = (int16_t) at->u[0].s64;
273                 ret = DW_DLV_OK;
274                 break;
275         case DW_FORM_data4:
276                 *return_svalue = (int32_t) at->u[0].s64;
277                 ret = DW_DLV_OK;
278                 break;
279         case DW_FORM_data8:
280         case DW_FORM_sdata:
281                 *return_svalue = at->u[0].s64;
282                 ret = DW_DLV_OK;
283                 break;
284         default:
285                 DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
286                 ret = DW_DLV_ERROR;
287         }
288
289         return (ret);
290 }
291
292 int
293 dwarf_formblock(Dwarf_Attribute at, Dwarf_Block **return_block,
294     Dwarf_Error *error)
295 {
296         int ret;
297         Dwarf_Debug dbg;
298
299         dbg = at != NULL ? at->at_die->die_dbg : NULL;
300
301         if (at == NULL || return_block == NULL) {
302                 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
303                 return (DW_DLV_ERROR);
304         }
305
306         switch (at->at_form) {
307         case DW_FORM_block:
308         case DW_FORM_block1:
309         case DW_FORM_block2:
310         case DW_FORM_block4:
311                 *return_block = &at->at_block;
312                 ret = DW_DLV_OK;
313                 break;
314         default:
315                 DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
316                 ret = DW_DLV_ERROR;
317         }
318
319         return (ret);
320 }
321
322 int
323 dwarf_formsig8(Dwarf_Attribute at, Dwarf_Sig8 *return_sig8, Dwarf_Error *error)
324 {
325         Dwarf_Debug dbg;
326
327         dbg = at != NULL ? at->at_die->die_dbg : NULL;
328
329         if (at == NULL || return_sig8 == NULL) {
330                 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
331                 return (DW_DLV_ERROR);
332         }
333         
334         if (at->at_form != DW_FORM_ref_sig8) {
335                 DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
336                 return (DW_DLV_ERROR);
337         }
338
339         assert(at->u[0].u64 == 8);
340         memcpy(return_sig8->signature, at->u[1].u8p, at->u[0].u64);
341
342         return (DW_DLV_OK);
343 }
344
345 int
346 dwarf_formexprloc(Dwarf_Attribute at, Dwarf_Unsigned *return_exprlen,
347     Dwarf_Ptr *return_expr, Dwarf_Error *error)
348 {
349
350         Dwarf_Debug dbg;
351
352         dbg = at != NULL ? at->at_die->die_dbg : NULL;
353
354         if (at == NULL || return_exprlen == NULL || return_expr == NULL) {
355                 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
356                 return (DW_DLV_ERROR);
357         }
358
359         if (at->at_form != DW_FORM_exprloc) {
360                 DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
361                 return (DW_DLV_ERROR);
362         }
363
364         *return_exprlen = at->u[0].u64;
365         *return_expr = (void *) at->u[1].u8p;
366
367         return (DW_DLV_OK);
368 }
369
370 int
371 dwarf_formstring(Dwarf_Attribute at, char **return_string,
372     Dwarf_Error *error)
373 {
374         int ret;
375         Dwarf_Debug dbg;
376
377         dbg = at != NULL ? at->at_die->die_dbg : NULL;
378
379         if (at == NULL || return_string == NULL) {
380                 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
381                 return (DW_DLV_ERROR);
382         }
383
384         switch (at->at_form) {
385         case DW_FORM_string:
386                 *return_string = (char *) at->u[0].s;
387                 ret = DW_DLV_OK;
388                 break;
389         case DW_FORM_strp:
390                 *return_string = (char *) at->u[1].s;
391                 ret = DW_DLV_OK;
392                 break;
393         default:
394                 DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
395                 ret = DW_DLV_ERROR;
396         }
397
398         return (ret);
399 }
400
401 enum Dwarf_Form_Class
402 dwarf_get_form_class(Dwarf_Half dwversion, Dwarf_Half attr,
403     Dwarf_Half offset_size, Dwarf_Half form)
404 {
405
406         switch (form) {
407         case DW_FORM_addr:
408                 return (DW_FORM_CLASS_ADDRESS);
409         case DW_FORM_block:
410         case DW_FORM_block1:
411         case DW_FORM_block2:
412         case DW_FORM_block4:
413                 return (DW_FORM_CLASS_BLOCK);
414         case DW_FORM_string:
415         case DW_FORM_strp:
416                 return (DW_FORM_CLASS_STRING);
417         case DW_FORM_flag:
418         case DW_FORM_flag_present:
419                 return (DW_FORM_CLASS_FLAG);
420         case DW_FORM_ref_addr:
421         case DW_FORM_ref_sig8:
422         case DW_FORM_ref_udata:
423         case DW_FORM_ref1:
424         case DW_FORM_ref2:
425         case DW_FORM_ref4:
426         case DW_FORM_ref8:
427                 return (DW_FORM_CLASS_REFERENCE);
428         case DW_FORM_exprloc:
429                 return (DW_FORM_CLASS_EXPRLOC);
430         case DW_FORM_data1:
431         case DW_FORM_data2:
432         case DW_FORM_sdata:
433         case DW_FORM_udata:
434                 return (DW_FORM_CLASS_CONSTANT);
435         case DW_FORM_data4:
436         case DW_FORM_data8:
437                 if (dwversion > 3)
438                         return (DW_FORM_CLASS_CONSTANT);
439                 if (form == DW_FORM_data4 && offset_size != 4)
440                         return (DW_FORM_CLASS_CONSTANT);
441                 if (form == DW_FORM_data8 && offset_size != 8)
442                         return (DW_FORM_CLASS_CONSTANT);
443                 /* FALLTHROUGH */
444         case DW_FORM_sec_offset:
445                 /*
446                  * DW_FORM_data4 and DW_FORM_data8 can be used as
447                  * offset/pointer before DWARF4. Newly added
448                  * DWARF4 form DW_FORM_sec_offset intents to replace
449                  * DW_FORM_data{4,8} for this purpose. Anyway, to
450                  * determine the actual class for these forms, we need
451                  * to also look at the attribute number.
452                  */
453                 switch (attr) {
454                 case DW_AT_location:
455                 case DW_AT_string_length:
456                 case DW_AT_return_addr:
457                 case DW_AT_data_member_location:
458                 case DW_AT_frame_base:
459                 case DW_AT_segment:
460                 case DW_AT_static_link:
461                 case DW_AT_use_location:
462                 case DW_AT_vtable_elem_location:
463                         return (DW_FORM_CLASS_LOCLISTPTR);
464                 case DW_AT_stmt_list:
465                         return (DW_FORM_CLASS_LINEPTR);
466                 case DW_AT_start_scope:
467                 case DW_AT_ranges:
468                         return (DW_FORM_CLASS_RANGELISTPTR);
469                 case DW_AT_macro_info:
470                         return (DW_FORM_CLASS_MACPTR);
471                 default:
472                         if (form == DW_FORM_data4 || form == DW_FORM_data8)
473                                 return (DW_FORM_CLASS_CONSTANT);
474                         else
475                                 return (DW_FORM_CLASS_UNKNOWN);
476                 }
477         default:
478                 return (DW_FORM_CLASS_UNKNOWN);
479         }
480 }