1 /* $NetBSD: dwarf_form.c,v 1.2 2014/03/09 16:58:03 christos Exp $ */
4 * Copyright (c) 2007 John Birrell (jb@freebsd.org)
5 * Copyright (c) 2009,2010 Kai Wang
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include "_libdwarf.h"
32 __RCSID("$NetBSD: dwarf_form.c,v 1.2 2014/03/09 16:58:03 christos Exp $");
33 ELFTC_VCSID("Id: dwarf_form.c 2073 2011-10-27 03:30:47Z jkoshy ");
36 dwarf_hasform(Dwarf_Attribute at
, Dwarf_Half form
, Dwarf_Bool
*return_hasform
,
41 dbg
= at
!= NULL
? at
->at_die
->die_dbg
: NULL
;
43 if (at
== NULL
|| return_hasform
== NULL
) {
44 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ARGUMENT
);
45 return (DW_DLV_ERROR
);
48 *return_hasform
= (at
->at_form
== form
);
54 dwarf_whatform(Dwarf_Attribute at
, Dwarf_Half
*return_form
, Dwarf_Error
*error
)
58 dbg
= at
!= NULL
? at
->at_die
->die_dbg
: NULL
;
60 if (at
== NULL
|| return_form
== NULL
) {
61 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ARGUMENT
);
62 return (DW_DLV_ERROR
);
65 *return_form
= at
->at_form
;
71 dwarf_whatform_direct(Dwarf_Attribute at
, Dwarf_Half
*return_form
,
76 dbg
= at
!= NULL
? at
->at_die
->die_dbg
: NULL
;
78 if (at
== NULL
|| return_form
== NULL
) {
79 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ARGUMENT
);
80 return (DW_DLV_ERROR
);
84 *return_form
= DW_FORM_indirect
;
86 *return_form
= (Dwarf_Half
) at
->at_form
;
92 dwarf_whatattr(Dwarf_Attribute at
, Dwarf_Half
*return_attr
, Dwarf_Error
*error
)
96 dbg
= at
!= NULL
? at
->at_die
->die_dbg
: NULL
;
98 if (at
== NULL
|| return_attr
== NULL
) {
99 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ARGUMENT
);
100 return (DW_DLV_ERROR
);
103 *return_attr
= (Dwarf_Half
) at
->at_attrib
;
109 dwarf_formref(Dwarf_Attribute at
, Dwarf_Off
*return_offset
, Dwarf_Error
*error
)
114 dbg
= at
!= NULL
? at
->at_die
->die_dbg
: NULL
;
116 if (at
== NULL
|| return_offset
== NULL
) {
117 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ARGUMENT
);
118 return (DW_DLV_ERROR
);
121 switch (at
->at_form
) {
126 case DW_FORM_ref_udata
:
127 *return_offset
= (Dwarf_Off
) at
->u
[0].u64
;
131 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ATTR_FORM_BAD
);
139 dwarf_global_formref(Dwarf_Attribute at
, Dwarf_Off
*return_offset
,
145 dbg
= at
!= NULL
? at
->at_die
->die_dbg
: NULL
;
147 if (at
== NULL
|| return_offset
== NULL
) {
148 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ARGUMENT
);
149 return (DW_DLV_ERROR
);
152 switch (at
->at_form
) {
153 case DW_FORM_ref_addr
:
154 case DW_FORM_sec_offset
:
155 *return_offset
= (Dwarf_Off
) at
->u
[0].u64
;
162 case DW_FORM_ref_udata
:
163 *return_offset
= (Dwarf_Off
) at
->u
[0].u64
+
164 at
->at_die
->die_cu
->cu_offset
;
168 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ATTR_FORM_BAD
);
176 dwarf_formaddr(Dwarf_Attribute at
, Dwarf_Addr
*return_addr
, Dwarf_Error
*error
)
181 dbg
= at
!= NULL
? at
->at_die
->die_dbg
: NULL
;
183 if (at
== NULL
|| return_addr
== NULL
) {
184 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ARGUMENT
);
185 return (DW_DLV_ERROR
);
188 if (at
->at_form
== DW_FORM_addr
) {
189 *return_addr
= at
->u
[0].u64
;
192 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ATTR_FORM_BAD
);
200 dwarf_formflag(Dwarf_Attribute at
, Dwarf_Bool
*return_bool
, Dwarf_Error
*error
)
205 dbg
= at
!= NULL
? at
->at_die
->die_dbg
: NULL
;
207 if (at
== NULL
|| return_bool
== NULL
) {
208 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ARGUMENT
);
209 return (DW_DLV_ERROR
);
212 if (at
->at_form
== DW_FORM_flag
||
213 at
->at_form
== DW_FORM_flag_present
) {
214 *return_bool
= (Dwarf_Bool
) (!!at
->u
[0].u64
);
217 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ATTR_FORM_BAD
);
225 dwarf_formudata(Dwarf_Attribute at
, Dwarf_Unsigned
*return_uvalue
,
231 dbg
= at
!= NULL
? at
->at_die
->die_dbg
: NULL
;
233 if (at
== NULL
|| return_uvalue
== NULL
) {
234 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ARGUMENT
);
235 return (DW_DLV_ERROR
);
238 switch (at
->at_form
) {
244 *return_uvalue
= at
->u
[0].u64
;
248 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ATTR_FORM_BAD
);
256 dwarf_formsdata(Dwarf_Attribute at
, Dwarf_Signed
*return_svalue
,
262 dbg
= at
!= NULL
? at
->at_die
->die_dbg
: NULL
;
264 if (at
== NULL
|| return_svalue
== NULL
) {
265 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ARGUMENT
);
266 return (DW_DLV_ERROR
);
269 switch (at
->at_form
) {
271 *return_svalue
= (int8_t) at
->u
[0].s64
;
275 *return_svalue
= (int16_t) at
->u
[0].s64
;
279 *return_svalue
= (int32_t) at
->u
[0].s64
;
284 *return_svalue
= at
->u
[0].s64
;
288 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ATTR_FORM_BAD
);
296 dwarf_formblock(Dwarf_Attribute at
, Dwarf_Block
**return_block
,
302 dbg
= at
!= NULL
? at
->at_die
->die_dbg
: NULL
;
304 if (at
== NULL
|| return_block
== NULL
) {
305 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ARGUMENT
);
306 return (DW_DLV_ERROR
);
309 switch (at
->at_form
) {
314 *return_block
= &at
->at_block
;
318 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ATTR_FORM_BAD
);
326 dwarf_formsig8(Dwarf_Attribute at
, Dwarf_Sig8
*return_sig8
, Dwarf_Error
*error
)
330 dbg
= at
!= NULL
? at
->at_die
->die_dbg
: NULL
;
332 if (at
== NULL
|| return_sig8
== NULL
) {
333 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ARGUMENT
);
334 return (DW_DLV_ERROR
);
337 if (at
->at_form
!= DW_FORM_ref_sig8
) {
338 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ATTR_FORM_BAD
);
339 return (DW_DLV_ERROR
);
342 assert(at
->u
[0].u64
== 8);
343 memcpy(return_sig8
->signature
, at
->u
[1].u8p
, at
->u
[0].u64
);
349 dwarf_formexprloc(Dwarf_Attribute at
, Dwarf_Unsigned
*return_exprlen
,
350 Dwarf_Ptr
*return_expr
, Dwarf_Error
*error
)
355 dbg
= at
!= NULL
? at
->at_die
->die_dbg
: NULL
;
357 if (at
== NULL
|| return_exprlen
== NULL
|| return_expr
== NULL
) {
358 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ARGUMENT
);
359 return (DW_DLV_ERROR
);
362 if (at
->at_form
!= DW_FORM_exprloc
) {
363 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ATTR_FORM_BAD
);
364 return (DW_DLV_ERROR
);
367 *return_exprlen
= at
->u
[0].u64
;
368 *return_expr
= (void *) at
->u
[1].u8p
;
374 dwarf_formstring(Dwarf_Attribute at
, char **return_string
,
380 dbg
= at
!= NULL
? at
->at_die
->die_dbg
: NULL
;
382 if (at
== NULL
|| return_string
== NULL
) {
383 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ARGUMENT
);
384 return (DW_DLV_ERROR
);
387 switch (at
->at_form
) {
389 *return_string
= (char *) at
->u
[0].s
;
393 *return_string
= (char *) at
->u
[1].s
;
397 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ATTR_FORM_BAD
);
404 enum Dwarf_Form_Class
405 dwarf_get_form_class(Dwarf_Half dwversion
, Dwarf_Half attr
,
406 Dwarf_Half offset_size
, Dwarf_Half form
)
411 return (DW_FORM_CLASS_ADDRESS
);
416 return (DW_FORM_CLASS_BLOCK
);
419 return (DW_FORM_CLASS_STRING
);
421 case DW_FORM_flag_present
:
422 return (DW_FORM_CLASS_FLAG
);
423 case DW_FORM_ref_addr
:
424 case DW_FORM_ref_sig8
:
425 case DW_FORM_ref_udata
:
430 return (DW_FORM_CLASS_REFERENCE
);
431 case DW_FORM_exprloc
:
432 return (DW_FORM_CLASS_EXPRLOC
);
437 return (DW_FORM_CLASS_CONSTANT
);
441 return (DW_FORM_CLASS_CONSTANT
);
442 if (form
== DW_FORM_data4
&& offset_size
!= 4)
443 return (DW_FORM_CLASS_CONSTANT
);
444 if (form
== DW_FORM_data8
&& offset_size
!= 8)
445 return (DW_FORM_CLASS_CONSTANT
);
447 case DW_FORM_sec_offset
:
449 * DW_FORM_data4 and DW_FORM_data8 can be used as
450 * offset/pointer before DWARF4. Newly added
451 * DWARF4 form DW_FORM_sec_offset intents to replace
452 * DW_FORM_data{4,8} for this purpose. Anyway, to
453 * determine the actual class for these forms, we need
454 * to also look at the attribute number.
458 case DW_AT_string_length
:
459 case DW_AT_return_addr
:
460 case DW_AT_data_member_location
:
461 case DW_AT_frame_base
:
463 case DW_AT_static_link
:
464 case DW_AT_use_location
:
465 case DW_AT_vtable_elem_location
:
466 return (DW_FORM_CLASS_LOCLISTPTR
);
467 case DW_AT_stmt_list
:
468 return (DW_FORM_CLASS_LINEPTR
);
469 case DW_AT_start_scope
:
471 return (DW_FORM_CLASS_RANGELISTPTR
);
472 case DW_AT_macro_info
:
473 return (DW_FORM_CLASS_MACPTR
);
475 if (form
== DW_FORM_data4
|| form
== DW_FORM_data8
)
476 return (DW_FORM_CLASS_CONSTANT
);
478 return (DW_FORM_CLASS_UNKNOWN
);
481 return (DW_FORM_CLASS_UNKNOWN
);