xref: /titanic_41/usr/src/tools/ctf/dwarf/common/dwarf_query.c (revision 5aeb94743e3be0c51e86f73096334611ae3a058e)
1 /*
2 
3   Copyright (C) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
4 
5   This program is free software; you can redistribute it and/or modify it
6   under the terms of version 2.1 of the GNU Lesser General Public License
7   as published by the Free Software Foundation.
8 
9   This program is distributed in the hope that it would be useful, but
10   WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13   Further, this software is distributed without any warranty that it is
14   free of the rightful claim of any third person regarding infringement
15   or the like.  Any license provided herein, whether implied or
16   otherwise, applies only to this software file.  Patent licenses, if
17   any, provided herein do not apply to combinations of this program with
18   other software, or any other product whatsoever.
19 
20   You should have received a copy of the GNU Lesser General Public
21   License along with this program; if not, write the Free Software
22   Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
23   USA.
24 
25   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
26   Mountain View, CA 94043, or:
27 
28   http://www.sgi.com
29 
30   For further information regarding this notice, see:
31 
32   http://oss.sgi.com/projects/GenInfo/NoticeExplan
33 
34 */
35 
36 
37 #include "config.h"
38 #include "dwarf_incl.h"
39 #include <stdio.h>
40 #include "dwarf_die_deliv.h"
41 
42 int
43 dwarf_get_address_size(Dwarf_Debug dbg,
44 		       Dwarf_Half * ret_addr_size, Dwarf_Error * error)
45 {
46     Dwarf_Half address_size;
47 
48     if (dbg == 0) {
49 	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
50 	return (DW_DLV_ERROR);
51     }
52     /* length size same as address size */
53     address_size = dbg->de_pointer_size;
54     *ret_addr_size = address_size;
55     return DW_DLV_OK;
56 }
57 
58 int
59 dwarf_dieoffset(Dwarf_Die die,
60 		Dwarf_Off * ret_offset, Dwarf_Error * error)
61 {
62     CHECK_DIE(die, DW_DLV_ERROR)
63 
64 	* ret_offset = (die->di_debug_info_ptr -
65 			die->di_cu_context->cc_dbg->de_debug_info);
66     return DW_DLV_OK;
67 }
68 
69 
70 /*
71     This function returns the offset of
72     the die relative to the start of its
73     compilation-unit rather than .debug_info.
74     Returns DW_DLV_ERROR on error.
75 */
76 int
77 dwarf_die_CU_offset(Dwarf_Die die,
78 		    Dwarf_Off * cu_off, Dwarf_Error * error)
79 {
80     Dwarf_CU_Context cu_context;
81 
82     CHECK_DIE(die, DW_DLV_ERROR)
83 	cu_context = die->di_cu_context;
84 
85     *cu_off =
86 	(die->di_debug_info_ptr - cu_context->cc_dbg->de_debug_info -
87 	 cu_context->cc_debug_info_offset);
88     return DW_DLV_OK;
89 }
90 
91 
92 int
93 dwarf_tag(Dwarf_Die die, Dwarf_Half * tag, Dwarf_Error * error)
94 {
95     CHECK_DIE(die, DW_DLV_ERROR)
96 
97 
98 	* tag = (die->di_abbrev_list->ab_tag);
99     return DW_DLV_OK;
100 }
101 
102 
103 int
104 dwarf_attrlist(Dwarf_Die die,
105 	       Dwarf_Attribute ** attrbuf,
106 	       Dwarf_Signed * attrcnt, Dwarf_Error * error)
107 {
108     Dwarf_Word attr_count = 0;
109     Dwarf_Word i;
110     Dwarf_Half attr;
111     Dwarf_Half attr_form;
112     Dwarf_Byte_Ptr abbrev_ptr;
113     Dwarf_Abbrev_List abbrev_list;
114     Dwarf_Attribute new_attr;
115     Dwarf_Attribute head_attr = NULL, curr_attr;
116     Dwarf_Attribute *attr_ptr;
117     Dwarf_Debug dbg;
118     Dwarf_Byte_Ptr info_ptr;
119 
120     CHECK_DIE(die, DW_DLV_ERROR)
121 	dbg = die->di_cu_context->cc_dbg;
122 
123     abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context,
124 					     die->di_abbrev_list->
125 					     ab_code);
126     if (abbrev_list == NULL) {
127 	_dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_BAD);
128 	return (DW_DLV_ERROR);
129     }
130     abbrev_ptr = abbrev_list->ab_abbrev_ptr;
131 
132     info_ptr = die->di_debug_info_ptr;
133     SKIP_LEB128_WORD(info_ptr)
134 
135 	do {
136 	Dwarf_Unsigned utmp2;
137 
138 	DECODE_LEB128_UWORD(abbrev_ptr, utmp2)
139 	    attr = (Dwarf_Half) utmp2;
140 	DECODE_LEB128_UWORD(abbrev_ptr, utmp2)
141 	    attr_form = (Dwarf_Half) utmp2;
142 
143 	if (attr != 0) {
144 	    new_attr =
145 		(Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
146 	    if (new_attr == NULL) {
147 		_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
148 		return (DW_DLV_ERROR);
149 	    }
150 
151 	    new_attr->ar_attribute = attr;
152 	    new_attr->ar_attribute_form_direct = attr_form;
153 	    new_attr->ar_attribute_form = attr_form;
154 	    if(attr_form == DW_FORM_indirect) {
155 		Dwarf_Unsigned utmp6;
156 		/* DECODE_LEB128_UWORD does info_ptr update */
157 		DECODE_LEB128_UWORD(info_ptr, utmp6)
158                 attr_form = (Dwarf_Half) utmp6;
159 	        new_attr->ar_attribute_form = attr_form;
160 	    }
161 	    new_attr->ar_cu_context = die->di_cu_context;
162 	    new_attr->ar_debug_info_ptr = info_ptr;
163 
164 	    info_ptr += _dwarf_get_size_of_val(dbg, attr_form, info_ptr,
165 					       die->di_cu_context->
166 					       cc_length_size);
167 
168 	    if (head_attr == NULL)
169 		head_attr = curr_attr = new_attr;
170 	    else {
171 		curr_attr->ar_next = new_attr;
172 		curr_attr = new_attr;
173 	    }
174 	    attr_count++;
175 	}
176     } while (attr != 0 || attr_form != 0);
177 
178     if (attr_count == 0) {
179 	*attrbuf = NULL;
180 	*attrcnt = 0;
181 	return (DW_DLV_NO_ENTRY);
182     }
183 
184     attr_ptr = (Dwarf_Attribute *)
185 	_dwarf_get_alloc(dbg, DW_DLA_LIST, attr_count);
186     if (attr_ptr == NULL) {
187 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
188 	return (DW_DLV_ERROR);
189     }
190 
191     curr_attr = head_attr;
192     for (i = 0; i < attr_count; i++) {
193 	*(attr_ptr + i) = curr_attr;
194 	curr_attr = curr_attr->ar_next;
195     }
196 
197     *attrbuf = attr_ptr;
198     *attrcnt = attr_count;
199     return (DW_DLV_OK);
200 }
201 
202 
203 /*
204     This function takes a die, and an attr, and returns
205     a pointer to the start of the value of that attr in
206     the given die in the .debug_info section.  The form
207     is returned in *attr_form.
208 
209     Returns NULL on error, or if attr is not found.
210     However, *attr_form is 0 on error, and positive
211     otherwise.
212 */
213 static Dwarf_Byte_Ptr
214 _dwarf_get_value_ptr(Dwarf_Die die,
215 		     Dwarf_Half attr, Dwarf_Half * attr_form)
216 {
217     Dwarf_Byte_Ptr abbrev_ptr;
218     Dwarf_Abbrev_List abbrev_list;
219     Dwarf_Half curr_attr;
220     Dwarf_Half curr_attr_form;
221     Dwarf_Byte_Ptr info_ptr;
222 
223     abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context,
224 					     die->di_abbrev_list->
225 					     ab_code);
226     if (abbrev_list == NULL) {
227 	*attr_form = 0;
228 	return (NULL);
229     }
230     abbrev_ptr = abbrev_list->ab_abbrev_ptr;
231 
232     info_ptr = die->di_debug_info_ptr;
233     SKIP_LEB128_WORD(info_ptr)
234 
235     do {
236 	Dwarf_Unsigned utmp3;
237 
238 	DECODE_LEB128_UWORD(abbrev_ptr, utmp3)
239 	    curr_attr = (Dwarf_Half) utmp3;
240 	DECODE_LEB128_UWORD(abbrev_ptr, utmp3)
241 	    curr_attr_form = (Dwarf_Half) utmp3;
242 	if(curr_attr_form == DW_FORM_indirect) {
243                 Dwarf_Unsigned utmp6;
244 
245 	        /* DECODE_LEB128_UWORD updates info_ptr */
246                 DECODE_LEB128_UWORD(info_ptr, utmp6)
247                 curr_attr_form = (Dwarf_Half) utmp6;
248         }
249 
250 	if (curr_attr == attr) {
251 	    *attr_form = curr_attr_form;
252 	    return (info_ptr);
253 	}
254 
255 	info_ptr += _dwarf_get_size_of_val(die->di_cu_context->cc_dbg,
256 					   curr_attr_form, info_ptr,
257 					   die->di_cu_context->
258 					   cc_length_size);
259     } while (curr_attr != 0 || curr_attr_form != 0);
260 
261     *attr_form = 1;
262     return (NULL);
263 }
264 
265 
266 int
267 dwarf_diename(Dwarf_Die die, char **ret_name, Dwarf_Error * error)
268 {
269     Dwarf_Half attr_form;
270     Dwarf_Debug dbg;
271     Dwarf_Byte_Ptr info_ptr;
272     Dwarf_Unsigned string_offset;
273     int res;
274 
275     CHECK_DIE(die, DW_DLV_ERROR)
276 
277 	info_ptr = _dwarf_get_value_ptr(die, DW_AT_name, &attr_form);
278     if (info_ptr == NULL) {
279 	if (attr_form == 0) {
280 	    _dwarf_error(die->di_cu_context->cc_dbg, error,
281 			 DW_DLE_DIE_BAD);
282 	    return (DW_DLV_ERROR);
283 	}
284 	return DW_DLV_NO_ENTRY;
285     }
286 
287     if (attr_form == DW_FORM_string) {
288 	*ret_name = (char *) (info_ptr);
289 	return DW_DLV_OK;
290     }
291 
292     dbg = die->di_cu_context->cc_dbg;
293     if (attr_form != DW_FORM_strp) {
294 	_dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
295 	return (DW_DLV_ERROR);
296     }
297 
298     READ_UNALIGNED(dbg, string_offset, Dwarf_Unsigned,
299 		   info_ptr, die->di_cu_context->cc_length_size);
300 
301     if (string_offset >= dbg->de_debug_str_size) {
302 	_dwarf_error(dbg, error, DW_DLE_STRING_OFFSET_BAD);
303 	return (DW_DLV_ERROR);
304     }
305 
306     res =
307        _dwarf_load_section(dbg,
308                            dbg->de_debug_str_index,
309                            &dbg->de_debug_str,
310                            error);
311     if (res != DW_DLV_OK) {
312         return res;
313     }
314 
315     *ret_name = (char *) (dbg->de_debug_str + string_offset);
316     return DW_DLV_OK;
317 }
318 
319 
320 int
321 dwarf_hasattr(Dwarf_Die die,
322 	      Dwarf_Half attr,
323 	      Dwarf_Bool * return_bool, Dwarf_Error * error)
324 {
325     Dwarf_Half attr_form;
326 
327     CHECK_DIE(die, DW_DLV_ERROR)
328 
329 	if (_dwarf_get_value_ptr(die, attr, &attr_form) == NULL) {
330 	if (attr_form == 0) {
331 	    _dwarf_error(die->di_cu_context->cc_dbg, error,
332 			 DW_DLE_DIE_BAD);
333 	    return (DW_DLV_ERROR);
334 	}
335 	*return_bool = false;
336 	return DW_DLV_OK;
337     }
338 
339     *return_bool = (true);
340     return DW_DLV_OK;
341 }
342 
343 
344 int
345 dwarf_attr(Dwarf_Die die,
346 	   Dwarf_Half attr,
347 	   Dwarf_Attribute * ret_attr, Dwarf_Error * error)
348 {
349     Dwarf_Half attr_form;
350     Dwarf_Attribute attrib;
351     Dwarf_Byte_Ptr info_ptr;
352     Dwarf_Debug dbg;
353 
354     CHECK_DIE(die, DW_DLV_ERROR)
355 	dbg = die->di_cu_context->cc_dbg;
356 
357     info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form);
358     if (info_ptr == NULL) {
359 	if (attr_form == 0) {
360 	    _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
361 	    return (DW_DLV_ERROR);
362 	}
363 	return DW_DLV_NO_ENTRY;
364     }
365 
366     attrib = (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
367     if (attrib == NULL) {
368 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
369 	return (DW_DLV_ERROR);
370     }
371 
372     attrib->ar_attribute = attr;
373     attrib->ar_attribute_form = attr_form;
374     attrib->ar_attribute_form_direct = attr_form;
375     attrib->ar_cu_context = die->di_cu_context;
376     attrib->ar_debug_info_ptr = info_ptr;
377     *ret_attr = (attrib);
378     return DW_DLV_OK;
379 }
380 
381 
382 int
383 dwarf_lowpc(Dwarf_Die die,
384 	    Dwarf_Addr * return_addr, Dwarf_Error * error)
385 {
386     Dwarf_Addr ret_addr;
387     Dwarf_Byte_Ptr info_ptr;
388     Dwarf_Half attr_form;
389     Dwarf_Debug dbg;
390 
391     CHECK_DIE(die, DW_DLV_ERROR)
392 
393 	dbg = die->di_cu_context->cc_dbg;
394     info_ptr = _dwarf_get_value_ptr(die, DW_AT_low_pc, &attr_form);
395     if ((info_ptr == NULL && attr_form == 0) ||
396 	(info_ptr != NULL && attr_form != DW_FORM_addr)) {
397 	_dwarf_error(dbg, error, DW_DLE_DIE_BAD);
398 	return (DW_DLV_ERROR);
399     }
400     if (info_ptr == NULL) {
401 	return (DW_DLV_NO_ENTRY);
402     }
403 
404 
405     READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
406 		   info_ptr, dbg->de_pointer_size);
407 
408     *return_addr = ret_addr;
409     return (DW_DLV_OK);
410 }
411 
412 
413 int
414 dwarf_highpc(Dwarf_Die die,
415 	     Dwarf_Addr * return_addr, Dwarf_Error * error)
416 {
417     Dwarf_Addr ret_addr;
418     Dwarf_Byte_Ptr info_ptr;
419     Dwarf_Half attr_form;
420     Dwarf_Debug dbg;
421 
422     CHECK_DIE(die, DW_DLV_ERROR)
423 
424 	dbg = die->di_cu_context->cc_dbg;
425     info_ptr = _dwarf_get_value_ptr(die, DW_AT_high_pc, &attr_form);
426     if ((info_ptr == NULL && attr_form == 0) ||
427 	(info_ptr != NULL && attr_form != DW_FORM_addr)) {
428 	_dwarf_error(dbg, error, DW_DLE_DIE_BAD);
429 	return (DW_DLV_ERROR);
430     }
431     if (info_ptr == NULL) {
432 	return (DW_DLV_NO_ENTRY);
433     }
434 
435     READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
436 		   info_ptr, dbg->de_pointer_size);
437 
438     *return_addr = ret_addr;
439     return (DW_DLV_OK);
440 }
441 
442 
443 /*
444     Takes a die, an attribute attr, and checks if attr
445     occurs in die.  Attr is required to be an attribute
446     whose form is in the "constant" class.  If attr occurs
447     in die, the value is returned.
448   Returns DW_DLV_OK, DW_DLV_ERROR, or DW_DLV_NO_ENTRY as
449     appropriate. Sets the value thru the pointer return_val.
450     This function is meant to do all the
451     processing for dwarf_bytesize, dwarf_bitsize, dwarf_bitoffset,
452     and dwarf_srclang.
453 */
454 static int
455 _dwarf_die_attr_unsigned_constant(Dwarf_Die die,
456 				  Dwarf_Half attr,
457 				  Dwarf_Unsigned * return_val,
458 				  Dwarf_Error * error)
459 {
460     Dwarf_Byte_Ptr info_ptr;
461     Dwarf_Half attr_form;
462     Dwarf_Unsigned ret_value;
463     Dwarf_Debug dbg;
464 
465     CHECK_DIE(die, DW_DLV_ERROR)
466 
467 	dbg = die->di_cu_context->cc_dbg;
468     info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form);
469     if (info_ptr != NULL) {
470 	switch (attr_form) {
471 
472 	case DW_FORM_data1:
473 	    *return_val = (*(Dwarf_Small *) info_ptr);
474 	    return (DW_DLV_OK);
475 
476 	case DW_FORM_data2:
477 	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
478 			   info_ptr, sizeof(Dwarf_Shalf));
479 	    *return_val = ret_value;
480 	    return (DW_DLV_OK);
481 
482 	case DW_FORM_data4:
483 	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
484 			   info_ptr, sizeof(Dwarf_sfixed));
485 	    *return_val = ret_value;
486 	    return (DW_DLV_OK);
487 
488 	case DW_FORM_data8:
489 	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
490 			   info_ptr, sizeof(Dwarf_Unsigned));
491 	    *return_val = ret_value;
492 	    return (DW_DLV_OK);
493 
494 	case DW_FORM_udata:
495 	    *return_val = (_dwarf_decode_u_leb128(info_ptr, NULL));
496 	    return (DW_DLV_OK);
497 
498 	default:
499 	    _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
500 	    return (DW_DLV_ERROR);
501 	}
502     }
503     if (attr_form == 0) {
504 	_dwarf_error(dbg, error, DW_DLE_DIE_BAD);
505 	return (DW_DLV_ERROR);
506     }
507     return DW_DLV_NO_ENTRY;
508 }
509 
510 
511 int
512 dwarf_bytesize(Dwarf_Die die,
513 	       Dwarf_Unsigned * ret_size, Dwarf_Error * error)
514 {
515     Dwarf_Unsigned luns;
516     int res =
517 	_dwarf_die_attr_unsigned_constant(die, DW_AT_byte_size, &luns,
518 					  error);
519     *ret_size = luns;
520     return res;
521 }
522 
523 
524 int
525 dwarf_bitsize(Dwarf_Die die,
526 	      Dwarf_Unsigned * ret_size, Dwarf_Error * error)
527 {
528     Dwarf_Unsigned luns;
529     int res;
530 
531     res =
532 	_dwarf_die_attr_unsigned_constant(die, DW_AT_bit_size, &luns,
533 					  error);
534     *ret_size = luns;
535     return res;
536 }
537 
538 
539 int
540 dwarf_bitoffset(Dwarf_Die die,
541 		Dwarf_Unsigned * ret_size, Dwarf_Error * error)
542 {
543     Dwarf_Unsigned luns;
544     int res;
545 
546     res =
547 	_dwarf_die_attr_unsigned_constant(die, DW_AT_bit_offset, &luns,
548 					  error);
549     *ret_size = luns;
550     return res;
551 }
552 
553 
554 /* Refer section 3.1, page 21 in Dwarf Definition. */
555 int
556 dwarf_srclang(Dwarf_Die die,
557 	      Dwarf_Unsigned * ret_size, Dwarf_Error * error)
558 {
559     Dwarf_Unsigned luns;
560     int res;
561 
562     res =
563 	_dwarf_die_attr_unsigned_constant(die, DW_AT_language, &luns,
564 					  error);
565     *ret_size = luns;
566     return res;
567 }
568 
569 
570 /* Refer section 5.4, page 37 in Dwarf Definition. */
571 int
572 dwarf_arrayorder(Dwarf_Die die,
573 		 Dwarf_Unsigned * ret_size, Dwarf_Error * error)
574 {
575     Dwarf_Unsigned luns;
576     int res;
577 
578     res =
579 	_dwarf_die_attr_unsigned_constant(die, DW_AT_ordering, &luns,
580 					  error);
581     *ret_size = luns;
582     return res;
583 }
584 
585 /*
586 	Return DW_DLV_OK if ok
587 	DW_DLV_ERROR if failure.
588 
589 	If the die and the attr are not related the result is
590 	meaningless.
591 */
592 int
593 dwarf_attr_offset(Dwarf_Die die, Dwarf_Attribute attr, Dwarf_Off * offset,	/* return
594 										   offset
595 										   thru
596 										   this
597 										   ptr
598 										 */
599 		  Dwarf_Error * error)
600 {
601     Dwarf_Off attroff;
602 
603     CHECK_DIE(die, DW_DLV_ERROR)
604 
605 	attroff = (attr->ar_debug_info_ptr -
606 		   die->di_cu_context->cc_dbg->de_debug_info);
607     *offset = attroff;
608     return DW_DLV_OK;
609 }
610