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