1 /*-
2 * Copyright (c) 2007 John Birrell (jb@freebsd.org)
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_attrval.c 3159 2015-02-15 21:43:27Z emaste $");
30
31 int
dwarf_attrval_flag(Dwarf_Die die,Dwarf_Half attr,Dwarf_Bool * valp,Dwarf_Error * err)32 dwarf_attrval_flag(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *valp, Dwarf_Error *err)
33 {
34 Dwarf_Attribute at;
35 Dwarf_Debug dbg;
36
37 dbg = die != NULL ? die->die_dbg : NULL;
38
39 if (die == NULL || valp == NULL) {
40 DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT);
41 return (DW_DLV_ERROR);
42 }
43
44 *valp = 0;
45
46 if ((at = _dwarf_attr_find(die, attr)) == NULL) {
47 DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
48 return (DW_DLV_NO_ENTRY);
49 }
50
51 switch (at->at_form) {
52 case DW_FORM_flag:
53 case DW_FORM_flag_present:
54 *valp = (Dwarf_Bool) (!!at->u[0].u64);
55 break;
56 default:
57 DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD);
58 return (DW_DLV_ERROR);
59 }
60
61 return (DW_DLV_OK);
62 }
63
64 int
dwarf_attrval_string(Dwarf_Die die,Dwarf_Half attr,const char ** strp,Dwarf_Error * err)65 dwarf_attrval_string(Dwarf_Die die, Dwarf_Half attr, const char **strp, Dwarf_Error *err)
66 {
67 Dwarf_Attribute at;
68 Dwarf_Debug dbg;
69
70 dbg = die != NULL ? die->die_dbg : NULL;
71
72 if (die == NULL || strp == NULL) {
73 DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT);
74 return (DW_DLV_ERROR);
75 }
76
77 *strp = NULL;
78
79 if ((at = _dwarf_attr_find(die, attr)) == NULL) {
80 DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
81 return (DW_DLV_NO_ENTRY);
82 }
83
84 switch (at->at_form) {
85 case DW_FORM_strp:
86 *strp = at->u[1].s;
87 break;
88 case DW_FORM_string:
89 *strp = at->u[0].s;
90 break;
91 default:
92 DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD);
93 return (DW_DLV_ERROR);
94 }
95
96 return (DW_DLV_OK);
97 }
98
99 int
dwarf_attrval_signed(Dwarf_Die die,Dwarf_Half attr,Dwarf_Signed * valp,Dwarf_Error * err)100 dwarf_attrval_signed(Dwarf_Die die, Dwarf_Half attr, Dwarf_Signed *valp, Dwarf_Error *err)
101 {
102 Dwarf_Attribute at;
103 Dwarf_Debug dbg;
104
105 dbg = die != NULL ? die->die_dbg : NULL;
106
107 if (die == NULL || valp == NULL) {
108 DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT);
109 return (DW_DLV_ERROR);
110 }
111
112 *valp = 0;
113
114 if ((at = _dwarf_attr_find(die, attr)) == NULL) {
115 DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
116 return (DW_DLV_NO_ENTRY);
117 }
118
119 switch (at->at_form) {
120 case DW_FORM_data1:
121 *valp = (int8_t) at->u[0].s64;
122 break;
123 case DW_FORM_data2:
124 *valp = (int16_t) at->u[0].s64;
125 break;
126 case DW_FORM_data4:
127 *valp = (int32_t) at->u[0].s64;
128 break;
129 case DW_FORM_data8:
130 case DW_FORM_sdata:
131 *valp = at->u[0].s64;
132 break;
133 default:
134 DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD);
135 return (DW_DLV_ERROR);
136 }
137
138 return (DW_DLV_OK);
139 }
140
141 int
dwarf_attrval_unsigned(Dwarf_Die die,Dwarf_Half attr,Dwarf_Unsigned * valp,Dwarf_Error * err)142 dwarf_attrval_unsigned(Dwarf_Die die, Dwarf_Half attr, Dwarf_Unsigned *valp, Dwarf_Error *err)
143 {
144 Dwarf_Attribute at;
145 Dwarf_Die die1;
146 Dwarf_Unsigned val;
147 Dwarf_Debug dbg;
148
149 dbg = die != NULL ? die->die_dbg : NULL;
150
151 if (die == NULL || valp == NULL) {
152 DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT);
153 return (DW_DLV_ERROR);
154 }
155
156 *valp = 0;
157
158 if ((at = _dwarf_attr_find(die, attr)) == NULL && attr != DW_AT_type) {
159 DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
160 return (DW_DLV_NO_ENTRY);
161 }
162
163 die1 = NULL;
164 if (at == NULL &&
165 (at = _dwarf_attr_find(die, DW_AT_abstract_origin)) != NULL) {
166 switch (at->at_form) {
167 case DW_FORM_ref1:
168 case DW_FORM_ref2:
169 case DW_FORM_ref4:
170 case DW_FORM_ref8:
171 case DW_FORM_ref_udata:
172 val = at->u[0].u64;
173 if ((die1 = _dwarf_die_find(die, val)) == NULL ||
174 (at = _dwarf_attr_find(die1, attr)) == NULL) {
175 if (die1 != NULL)
176 dwarf_dealloc(dbg, die1, DW_DLA_DIE);
177 DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
178 return (DW_DLV_NO_ENTRY);
179 }
180 break;
181 default:
182 DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD);
183 return (DW_DLV_ERROR);
184 }
185 }
186
187 switch (at->at_form) {
188 case DW_FORM_addr:
189 case DW_FORM_data1:
190 case DW_FORM_data2:
191 case DW_FORM_data4:
192 case DW_FORM_data8:
193 case DW_FORM_udata:
194 case DW_FORM_ref1:
195 case DW_FORM_ref2:
196 case DW_FORM_ref4:
197 case DW_FORM_ref8:
198 case DW_FORM_ref_udata:
199 *valp = at->u[0].u64;
200 break;
201 default:
202 if (die1 != NULL)
203 dwarf_dealloc(dbg, die1, DW_DLA_DIE);
204 DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD);
205 return (DW_DLV_ERROR);
206 }
207
208 if (die1 != NULL)
209 dwarf_dealloc(dbg, die1, DW_DLA_DIE);
210
211 return (DW_DLV_OK);
212 }
213