2 * Copyright (c) 2007 John Birrell (jb@freebsd.org)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
32 #include "_libdwarf.h"
35 dwarf_attrval_find(Dwarf_Die die, Dwarf_Half attr)
39 STAILQ_FOREACH(av, &die->die_attrval, av_next) {
40 if (av->av_attrib == attr)
48 dwarf_attrval_add(Dwarf_Die die, Dwarf_AttrValue avref, Dwarf_AttrValue *avp, Dwarf_Error *error)
51 int ret = DWARF_E_NONE;
53 if ((av = malloc(sizeof(struct _Dwarf_AttrValue))) == NULL) {
54 DWARF_SET_ERROR(error, DWARF_E_MEMORY);
55 return DWARF_E_MEMORY;
58 memcpy(av, avref, sizeof(struct _Dwarf_AttrValue));
60 /* Add the attribute value to the list in the die. */
61 STAILQ_INSERT_TAIL(&die->die_attrval, av, av_next);
63 /* Save a pointer to the attribute name if this is one. */
64 if (av->av_attrib == DW_AT_name)
65 switch (av->av_form) {
67 die->die_name = av->u[1].s;
70 die->die_name = av->u[0].s;
83 dwarf_attrval_flag(Dwarf_Die die, uint64_t attr, Dwarf_Bool *valp, Dwarf_Error *err)
86 int ret = DWARF_E_NONE;
91 if (die == NULL || valp == NULL) {
92 DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
93 return DWARF_E_ARGUMENT;
98 if ((av = dwarf_attrval_find(die, attr)) == NULL) {
99 DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY);
100 ret = DWARF_E_NO_ENTRY;
102 switch (av->av_form) {
104 case DW_FORM_flag_present:
105 *valp = (Dwarf_Bool) av->u[0].u64;
108 printf("%s(%d): av->av_form '%s' (0x%lx) not handled\n",
109 __func__,__LINE__,get_form_desc(av->av_form),
110 (u_long) av->av_form);
111 DWARF_SET_ERROR(err, DWARF_E_BAD_FORM);
112 ret = DWARF_E_BAD_FORM;
120 dwarf_attrval_string(Dwarf_Die die, uint64_t attr, const char **strp, Dwarf_Error *err)
123 int ret = DWARF_E_NONE;
126 return DWARF_E_ERROR;
128 if (die == NULL || strp == NULL) {
129 DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
130 return DWARF_E_ARGUMENT;
135 if (attr == DW_AT_name)
136 *strp = die->die_name;
137 else if ((av = dwarf_attrval_find(die, attr)) == NULL) {
138 DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY);
139 ret = DWARF_E_NO_ENTRY;
141 switch (av->av_form) {
149 printf("%s(%d): av->av_form '%s' (0x%lx) not handled\n",
150 __func__,__LINE__,get_form_desc(av->av_form),
151 (u_long) av->av_form);
152 DWARF_SET_ERROR(err, DWARF_E_BAD_FORM);
153 ret = DWARF_E_BAD_FORM;
161 dwarf_attrval_signed(Dwarf_Die die, uint64_t attr, Dwarf_Signed *valp, Dwarf_Error *err)
164 int ret = DWARF_E_NONE;
167 return DWARF_E_ERROR;
169 if (die == NULL || valp == NULL) {
170 DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
171 return DWARF_E_ARGUMENT;
176 if ((av = dwarf_attrval_find(die, attr)) == NULL) {
177 DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY);
178 ret = DWARF_E_NO_ENTRY;
180 switch (av->av_form) {
183 *valp = av->u[0].s64;
186 printf("%s(%d): av->av_form '%s' (0x%lx) not handled\n",
187 __func__,__LINE__,get_form_desc(av->av_form),
188 (u_long) av->av_form);
189 DWARF_SET_ERROR(err, DWARF_E_BAD_FORM);
190 ret = DWARF_E_BAD_FORM;
198 dwarf_attrval_unsigned(Dwarf_Die die, uint64_t attr, Dwarf_Unsigned *valp, Dwarf_Error *err)
201 int ret = DWARF_E_NONE;
204 return DWARF_E_ERROR;
206 if (die == NULL || valp == NULL) {
207 DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
208 return DWARF_E_ARGUMENT;
213 if ((av = dwarf_attrval_find(die, attr)) == NULL && attr != DW_AT_type) {
214 DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY);
215 ret = DWARF_E_NO_ENTRY;
216 } else if (av == NULL && (av = dwarf_attrval_find(die,
217 DW_AT_abstract_origin)) != NULL) {
221 switch (av->av_form) {
230 case DW_FORM_ref_udata:
233 if ((die1 = dwarf_die_find(die, val)) == NULL ||
234 (av = dwarf_attrval_find(die1, attr)) == NULL) {
235 DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY);
236 ret = DWARF_E_NO_ENTRY;
240 printf("%s(%d): av->av_form '%s' (0x%lx) not handled\n",
241 __func__,__LINE__,get_form_desc(av->av_form),
242 (u_long) av->av_form);
243 DWARF_SET_ERROR(err, DWARF_E_BAD_FORM);
244 ret = DWARF_E_BAD_FORM;
248 if (ret == DWARF_E_NONE) {
249 switch (av->av_form) {
258 case DW_FORM_ref_udata:
259 *valp = av->u[0].u64;
262 printf("%s(%d): av->av_form '%s' (0x%lx) not handled\n",
263 __func__,__LINE__,get_form_desc(av->av_form),
264 (u_long) av->av_form);
265 DWARF_SET_ERROR(err, DWARF_E_BAD_FORM);
266 ret = DWARF_E_BAD_FORM;