xref: /minix3/external/bsd/elftoolchain/dist/libdwarf/dwarf_form.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1 /*	$NetBSD: dwarf_form.c,v 1.2 2014/03/09 16:58:03 christos Exp $	*/
2 
3 /*-
4  * Copyright (c) 2007 John Birrell (jb@freebsd.org)
5  * Copyright (c) 2009,2010 Kai Wang
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
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.
16  *
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
27  * SUCH DAMAGE.
28  */
29 
30 #include "_libdwarf.h"
31 
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 ");
34 
35 int
dwarf_hasform(Dwarf_Attribute at,Dwarf_Half form,Dwarf_Bool * return_hasform,Dwarf_Error * error)36 dwarf_hasform(Dwarf_Attribute at, Dwarf_Half form, Dwarf_Bool *return_hasform,
37     Dwarf_Error *error)
38 {
39 	Dwarf_Debug dbg;
40 
41 	dbg = at != NULL ? at->at_die->die_dbg : NULL;
42 
43 	if (at == NULL || return_hasform == NULL) {
44 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
45 		return (DW_DLV_ERROR);
46 	}
47 
48 	*return_hasform = (at->at_form == form);
49 
50 	return (DW_DLV_OK);
51 }
52 
53 int
dwarf_whatform(Dwarf_Attribute at,Dwarf_Half * return_form,Dwarf_Error * error)54 dwarf_whatform(Dwarf_Attribute at, Dwarf_Half *return_form, Dwarf_Error *error)
55 {
56 	Dwarf_Debug dbg;
57 
58 	dbg = at != NULL ? at->at_die->die_dbg : NULL;
59 
60 	if (at == NULL || return_form == NULL) {
61 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
62 		return (DW_DLV_ERROR);
63 	}
64 
65 	*return_form = at->at_form;
66 
67 	return (DW_DLV_OK);
68 }
69 
70 int
dwarf_whatform_direct(Dwarf_Attribute at,Dwarf_Half * return_form,Dwarf_Error * error)71 dwarf_whatform_direct(Dwarf_Attribute at, Dwarf_Half *return_form,
72     Dwarf_Error *error)
73 {
74 	Dwarf_Debug dbg;
75 
76 	dbg = at != NULL ? at->at_die->die_dbg : NULL;
77 
78 	if (at == NULL || return_form == NULL) {
79 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
80 		return (DW_DLV_ERROR);
81 	}
82 
83 	if (at->at_indirect)
84 		*return_form = DW_FORM_indirect;
85 	else
86 		*return_form = (Dwarf_Half) at->at_form;
87 
88 	return (DW_DLV_OK);
89 }
90 
91 int
dwarf_whatattr(Dwarf_Attribute at,Dwarf_Half * return_attr,Dwarf_Error * error)92 dwarf_whatattr(Dwarf_Attribute at, Dwarf_Half *return_attr, Dwarf_Error *error)
93 {
94 	Dwarf_Debug dbg;
95 
96 	dbg = at != NULL ? at->at_die->die_dbg : NULL;
97 
98 	if (at == NULL || return_attr == NULL) {
99 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
100 		return (DW_DLV_ERROR);
101 	}
102 
103 	*return_attr = (Dwarf_Half) at->at_attrib;
104 
105 	return (DW_DLV_OK);
106 }
107 
108 int
dwarf_formref(Dwarf_Attribute at,Dwarf_Off * return_offset,Dwarf_Error * error)109 dwarf_formref(Dwarf_Attribute at, Dwarf_Off *return_offset, Dwarf_Error *error)
110 {
111 	int ret;
112 	Dwarf_Debug dbg;
113 
114 	dbg = at != NULL ? at->at_die->die_dbg : NULL;
115 
116 	if (at == NULL || return_offset == NULL) {
117 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
118 		return (DW_DLV_ERROR);
119 	}
120 
121 	switch (at->at_form) {
122 	case DW_FORM_ref1:
123 	case DW_FORM_ref2:
124 	case DW_FORM_ref4:
125 	case DW_FORM_ref8:
126 	case DW_FORM_ref_udata:
127 		*return_offset = (Dwarf_Off) at->u[0].u64;
128 		ret = DW_DLV_OK;
129 		break;
130 	default:
131 		DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
132 		ret = DW_DLV_ERROR;
133 	}
134 
135 	return (ret);
136 }
137 
138 int
dwarf_global_formref(Dwarf_Attribute at,Dwarf_Off * return_offset,Dwarf_Error * error)139 dwarf_global_formref(Dwarf_Attribute at, Dwarf_Off *return_offset,
140     Dwarf_Error *error)
141 {
142 	int ret;
143 	Dwarf_Debug dbg;
144 
145 	dbg = at != NULL ? at->at_die->die_dbg : NULL;
146 
147 	if (at == NULL || return_offset == NULL) {
148 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
149 		return (DW_DLV_ERROR);
150 	}
151 
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;
156 		ret = DW_DLV_OK;
157 		break;
158 	case DW_FORM_ref1:
159 	case DW_FORM_ref2:
160 	case DW_FORM_ref4:
161 	case DW_FORM_ref8:
162 	case DW_FORM_ref_udata:
163 		*return_offset = (Dwarf_Off) at->u[0].u64 +
164 			at->at_die->die_cu->cu_offset;
165 		ret = DW_DLV_OK;
166 		break;
167 	default:
168 		DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
169 		ret = DW_DLV_ERROR;
170 	}
171 
172 	return (ret);
173 }
174 
175 int
dwarf_formaddr(Dwarf_Attribute at,Dwarf_Addr * return_addr,Dwarf_Error * error)176 dwarf_formaddr(Dwarf_Attribute at, Dwarf_Addr *return_addr, Dwarf_Error *error)
177 {
178 	int ret;
179 	Dwarf_Debug dbg;
180 
181 	dbg = at != NULL ? at->at_die->die_dbg : NULL;
182 
183 	if (at == NULL || return_addr == NULL) {
184 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
185 		return (DW_DLV_ERROR);
186 	}
187 
188 	if (at->at_form == DW_FORM_addr) {
189 		*return_addr = at->u[0].u64;
190 		ret = DW_DLV_OK;
191 	} else {
192 		DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
193 		ret = DW_DLV_ERROR;
194 	}
195 
196 	return (ret);
197 }
198 
199 int
dwarf_formflag(Dwarf_Attribute at,Dwarf_Bool * return_bool,Dwarf_Error * error)200 dwarf_formflag(Dwarf_Attribute at, Dwarf_Bool *return_bool, Dwarf_Error *error)
201 {
202 	int ret;
203 	Dwarf_Debug dbg;
204 
205 	dbg = at != NULL ? at->at_die->die_dbg : NULL;
206 
207 	if (at == NULL || return_bool == NULL) {
208 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
209 		return (DW_DLV_ERROR);
210 	}
211 
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);
215 		ret = DW_DLV_OK;
216 	} else {
217 		DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
218 		ret = DW_DLV_ERROR;
219 	}
220 
221 	return (ret);
222 }
223 
224 int
dwarf_formudata(Dwarf_Attribute at,Dwarf_Unsigned * return_uvalue,Dwarf_Error * error)225 dwarf_formudata(Dwarf_Attribute at, Dwarf_Unsigned *return_uvalue,
226     Dwarf_Error *error)
227 {
228 	int ret;
229 	Dwarf_Debug dbg;
230 
231 	dbg = at != NULL ? at->at_die->die_dbg : NULL;
232 
233 	if (at == NULL || return_uvalue == NULL) {
234 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
235 		return (DW_DLV_ERROR);
236 	}
237 
238 	switch (at->at_form) {
239 	case DW_FORM_data1:
240 	case DW_FORM_data2:
241 	case DW_FORM_data4:
242 	case DW_FORM_data8:
243 	case DW_FORM_udata:
244 		*return_uvalue = at->u[0].u64;
245 		ret = DW_DLV_OK;
246 		break;
247 	default:
248 		DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
249 		ret = DW_DLV_ERROR;
250 	}
251 
252 	return (ret);
253 }
254 
255 int
dwarf_formsdata(Dwarf_Attribute at,Dwarf_Signed * return_svalue,Dwarf_Error * error)256 dwarf_formsdata(Dwarf_Attribute at, Dwarf_Signed *return_svalue,
257     Dwarf_Error *error)
258 {
259 	int ret;
260 	Dwarf_Debug dbg;
261 
262 	dbg = at != NULL ? at->at_die->die_dbg : NULL;
263 
264 	if (at == NULL || return_svalue == NULL) {
265 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
266 		return (DW_DLV_ERROR);
267 	}
268 
269 	switch (at->at_form) {
270 	case DW_FORM_data1:
271 		*return_svalue = (int8_t) at->u[0].s64;
272 		ret = DW_DLV_OK;
273 		break;
274 	case DW_FORM_data2:
275 		*return_svalue = (int16_t) at->u[0].s64;
276 		ret = DW_DLV_OK;
277 		break;
278 	case DW_FORM_data4:
279 		*return_svalue = (int32_t) at->u[0].s64;
280 		ret = DW_DLV_OK;
281 		break;
282 	case DW_FORM_data8:
283 	case DW_FORM_sdata:
284 		*return_svalue = at->u[0].s64;
285 		ret = DW_DLV_OK;
286 		break;
287 	default:
288 		DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
289 		ret = DW_DLV_ERROR;
290 	}
291 
292 	return (ret);
293 }
294 
295 int
dwarf_formblock(Dwarf_Attribute at,Dwarf_Block ** return_block,Dwarf_Error * error)296 dwarf_formblock(Dwarf_Attribute at, Dwarf_Block **return_block,
297     Dwarf_Error *error)
298 {
299 	int ret;
300 	Dwarf_Debug dbg;
301 
302 	dbg = at != NULL ? at->at_die->die_dbg : NULL;
303 
304 	if (at == NULL || return_block == NULL) {
305 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
306 		return (DW_DLV_ERROR);
307 	}
308 
309 	switch (at->at_form) {
310 	case DW_FORM_block:
311 	case DW_FORM_block1:
312 	case DW_FORM_block2:
313 	case DW_FORM_block4:
314 		*return_block = &at->at_block;
315 		ret = DW_DLV_OK;
316 		break;
317 	default:
318 		DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
319 		ret = DW_DLV_ERROR;
320 	}
321 
322 	return (ret);
323 }
324 
325 int
dwarf_formsig8(Dwarf_Attribute at,Dwarf_Sig8 * return_sig8,Dwarf_Error * error)326 dwarf_formsig8(Dwarf_Attribute at, Dwarf_Sig8 *return_sig8, Dwarf_Error *error)
327 {
328 	Dwarf_Debug dbg;
329 
330 	dbg = at != NULL ? at->at_die->die_dbg : NULL;
331 
332 	if (at == NULL || return_sig8 == NULL) {
333 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
334 		return (DW_DLV_ERROR);
335 	}
336 
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);
340 	}
341 
342 	assert(at->u[0].u64 == 8);
343 	memcpy(return_sig8->signature, at->u[1].u8p, at->u[0].u64);
344 
345 	return (DW_DLV_OK);
346 }
347 
348 int
dwarf_formexprloc(Dwarf_Attribute at,Dwarf_Unsigned * return_exprlen,Dwarf_Ptr * return_expr,Dwarf_Error * error)349 dwarf_formexprloc(Dwarf_Attribute at, Dwarf_Unsigned *return_exprlen,
350     Dwarf_Ptr *return_expr, Dwarf_Error *error)
351 {
352 
353 	Dwarf_Debug dbg;
354 
355 	dbg = at != NULL ? at->at_die->die_dbg : NULL;
356 
357 	if (at == NULL || return_exprlen == NULL || return_expr == NULL) {
358 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
359 		return (DW_DLV_ERROR);
360 	}
361 
362 	if (at->at_form != DW_FORM_exprloc) {
363 		DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
364 		return (DW_DLV_ERROR);
365 	}
366 
367 	*return_exprlen = at->u[0].u64;
368 	*return_expr = (void *) at->u[1].u8p;
369 
370 	return (DW_DLV_OK);
371 }
372 
373 int
dwarf_formstring(Dwarf_Attribute at,char ** return_string,Dwarf_Error * error)374 dwarf_formstring(Dwarf_Attribute at, char **return_string,
375     Dwarf_Error *error)
376 {
377 	int ret;
378 	Dwarf_Debug dbg;
379 
380 	dbg = at != NULL ? at->at_die->die_dbg : NULL;
381 
382 	if (at == NULL || return_string == NULL) {
383 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
384 		return (DW_DLV_ERROR);
385 	}
386 
387 	switch (at->at_form) {
388 	case DW_FORM_string:
389 		*return_string = (char *) at->u[0].s;
390 		ret = DW_DLV_OK;
391 		break;
392 	case DW_FORM_strp:
393 		*return_string = (char *) at->u[1].s;
394 		ret = DW_DLV_OK;
395 		break;
396 	default:
397 		DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
398 		ret = DW_DLV_ERROR;
399 	}
400 
401 	return (ret);
402 }
403 
404 enum Dwarf_Form_Class
dwarf_get_form_class(Dwarf_Half dwversion,Dwarf_Half attr,Dwarf_Half offset_size,Dwarf_Half form)405 dwarf_get_form_class(Dwarf_Half dwversion, Dwarf_Half attr,
406     Dwarf_Half offset_size, Dwarf_Half form)
407 {
408 
409 	switch (form) {
410 	case DW_FORM_addr:
411 		return (DW_FORM_CLASS_ADDRESS);
412 	case DW_FORM_block:
413 	case DW_FORM_block1:
414 	case DW_FORM_block2:
415 	case DW_FORM_block4:
416 		return (DW_FORM_CLASS_BLOCK);
417 	case DW_FORM_string:
418 	case DW_FORM_strp:
419 		return (DW_FORM_CLASS_STRING);
420 	case DW_FORM_flag:
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:
426 	case DW_FORM_ref1:
427 	case DW_FORM_ref2:
428 	case DW_FORM_ref4:
429 	case DW_FORM_ref8:
430 		return (DW_FORM_CLASS_REFERENCE);
431 	case DW_FORM_exprloc:
432 		return (DW_FORM_CLASS_EXPRLOC);
433 	case DW_FORM_data1:
434 	case DW_FORM_data2:
435 	case DW_FORM_sdata:
436 	case DW_FORM_udata:
437 		return (DW_FORM_CLASS_CONSTANT);
438 	case DW_FORM_data4:
439 	case DW_FORM_data8:
440 		if (dwversion > 3)
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);
446 		/* FALLTHROUGH */
447 	case DW_FORM_sec_offset:
448 		/*
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.
455 		 */
456 		switch (attr) {
457 		case DW_AT_location:
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:
462 		case DW_AT_segment:
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:
470 		case DW_AT_ranges:
471 			return (DW_FORM_CLASS_RANGELISTPTR);
472 		case DW_AT_macro_info:
473 			return (DW_FORM_CLASS_MACPTR);
474 		default:
475 			if (form == DW_FORM_data4 || form == DW_FORM_data8)
476 				return (DW_FORM_CLASS_CONSTANT);
477 			else
478 				return (DW_FORM_CLASS_UNKNOWN);
479 		}
480 	default:
481 		return (DW_FORM_CLASS_UNKNOWN);
482 	}
483 }
484