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