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