tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_form.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2 
       
     3   Copyright (C) 2000,2002,2004,2005  Silicon Graphics, Inc.  All Rights Reserved.
       
     4   Portions Copyright 2007 Sun Microsystems, Inc. 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 
       
    37 
       
    38 
       
    39 #include "config.h"
       
    40 #include "dwarf_incl.h"
       
    41 #include "dwarf_die_deliv.h"
       
    42 
       
    43 int
       
    44 dwarf_hasform(Dwarf_Attribute attr,
       
    45 	      Dwarf_Half form,
       
    46 	      Dwarf_Bool * return_bool, Dwarf_Error * error)
       
    47 {
       
    48     Dwarf_CU_Context cu_context;
       
    49 
       
    50     if (attr == NULL) {
       
    51 	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
       
    52 	return (DW_DLV_ERROR);
       
    53     }
       
    54 
       
    55     cu_context = attr->ar_cu_context;
       
    56     if (cu_context == NULL) {
       
    57 	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
       
    58 	return (DW_DLV_ERROR);
       
    59     }
       
    60 
       
    61     if (cu_context->cc_dbg == NULL) {
       
    62 	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
       
    63 	return (DW_DLV_ERROR);
       
    64     }
       
    65 
       
    66     *return_bool = (attr->ar_attribute_form == form);
       
    67     return DW_DLV_OK;
       
    68 }
       
    69 
       
    70 /* Not often called, we do not worry about efficiency here.
       
    71    The dwarf_whatform() call does the sanity checks for us.
       
    72 */
       
    73 int
       
    74 dwarf_whatform_direct(Dwarf_Attribute attr,
       
    75 		      Dwarf_Half * return_form, Dwarf_Error * error)
       
    76 {
       
    77     int res = dwarf_whatform(attr, return_form, error);
       
    78 
       
    79     if (res != DW_DLV_OK) {
       
    80 	return res;
       
    81     }
       
    82 
       
    83     *return_form = attr->ar_attribute_form_direct;
       
    84     return (DW_DLV_OK);
       
    85 }
       
    86 void *
       
    87 dwarf_uncompress_integer_block(
       
    88     Dwarf_Debug      dbg,
       
    89     Dwarf_Bool       unit_is_signed,
       
    90     Dwarf_Small      unit_length_in_bits,
       
    91     void*            input_block,
       
    92     Dwarf_Unsigned   input_length_in_bytes,
       
    93     Dwarf_Unsigned*  output_length_in_units_ptr,
       
    94     Dwarf_Error*     error
       
    95 )
       
    96 {
       
    97     Dwarf_Unsigned output_length_in_units;
       
    98     void * output_block;
       
    99     int i;
       
   100     char * ptr;
       
   101     int remain;
       
   102     Dwarf_sfixed * array;
       
   103 
       
   104     if (dbg == NULL) {
       
   105         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
       
   106         return((void *)DW_DLV_BADADDR);
       
   107     }
       
   108     
       
   109     if (unit_is_signed == false ||
       
   110 	unit_length_in_bits != 32 ||
       
   111 	input_block == NULL ||
       
   112 	input_length_in_bytes == 0 ||
       
   113 	output_length_in_units_ptr == NULL) {
       
   114 	
       
   115 	_dwarf_error(NULL, error, DW_DLE_BADBITC);
       
   116 	return ((void *) DW_DLV_BADADDR);
       
   117     }
       
   118 
       
   119     /* At this point we assume the format is: signed 32 bit */
       
   120 
       
   121     /* first uncompress everything to find the total size. */
       
   122 
       
   123     output_length_in_units = 0;
       
   124     remain = input_length_in_bytes;
       
   125     ptr = input_block;
       
   126     while (remain > 0) {
       
   127 	Dwarf_Signed num;
       
   128 	Dwarf_Word len;
       
   129 	num = _dwarf_decode_s_leb128((unsigned char *)ptr, &len);
       
   130 	ptr += len;
       
   131 	remain -= len;
       
   132 	output_length_in_units++;
       
   133     }
       
   134 
       
   135     if (remain != 0) {
       
   136 	_dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
       
   137 	return((void *)DW_DLV_BADADDR);
       
   138     }
       
   139     
       
   140     /* then alloc */
       
   141 
       
   142     output_block = (void *)
       
   143         _dwarf_get_alloc(dbg,
       
   144 			 DW_DLA_STRING,
       
   145 			 output_length_in_units * (unit_length_in_bits / 8));
       
   146     if (output_block == NULL) {
       
   147         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
       
   148         return((void*)DW_DLV_BADADDR);
       
   149     }
       
   150     
       
   151     /* then uncompress again and copy into new buffer */
       
   152 
       
   153     array = (Dwarf_sfixed *) output_block;
       
   154     remain = input_length_in_bytes;
       
   155     ptr = input_block;
       
   156     for (i=0; i<output_length_in_units && remain>0; i++) {
       
   157 	Dwarf_Signed num;
       
   158 	Dwarf_Word len;
       
   159 	num = _dwarf_decode_s_leb128((unsigned char *)ptr, &len);
       
   160 	ptr += len;
       
   161 	remain -= len;
       
   162 	array[i] = num;
       
   163     }
       
   164 
       
   165     if (remain != 0) {
       
   166 	dwarf_dealloc(dbg, (unsigned char *)output_block, DW_DLA_STRING);
       
   167 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
       
   168 	return((Dwarf_P_Attribute)DW_DLV_BADADDR);
       
   169     }
       
   170 
       
   171     *output_length_in_units_ptr = output_length_in_units;
       
   172     return output_block;
       
   173 }
       
   174 
       
   175 void
       
   176 dwarf_dealloc_uncompressed_block(Dwarf_Debug dbg, void * space)
       
   177 {
       
   178     dwarf_dealloc(dbg, space, DW_DLA_STRING);
       
   179 }
       
   180 
       
   181 
       
   182 int
       
   183 dwarf_whatform(Dwarf_Attribute attr,
       
   184 	       Dwarf_Half * return_form, Dwarf_Error * error)
       
   185 {
       
   186     Dwarf_CU_Context cu_context;
       
   187 
       
   188     if (attr == NULL) {
       
   189 	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
       
   190 	return (DW_DLV_ERROR);
       
   191     }
       
   192 
       
   193     cu_context = attr->ar_cu_context;
       
   194     if (cu_context == NULL) {
       
   195 	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
       
   196 	return (DW_DLV_ERROR);
       
   197     }
       
   198 
       
   199     if (cu_context->cc_dbg == NULL) {
       
   200 	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
       
   201 	return (DW_DLV_ERROR);
       
   202     }
       
   203 
       
   204     *return_form = attr->ar_attribute_form;
       
   205     return (DW_DLV_OK);
       
   206 }
       
   207 
       
   208 
       
   209 /*
       
   210     This function is analogous to dwarf_whatform.
       
   211     It returns the attribute in attr instead of
       
   212     the form.
       
   213 */
       
   214 int
       
   215 dwarf_whatattr(Dwarf_Attribute attr,
       
   216 	       Dwarf_Half * return_attr, Dwarf_Error * error)
       
   217 {
       
   218     Dwarf_CU_Context cu_context;
       
   219 
       
   220     if (attr == NULL) {
       
   221 	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
       
   222 	return (DW_DLV_ERROR);
       
   223     }
       
   224 
       
   225     cu_context = attr->ar_cu_context;
       
   226     if (cu_context == NULL) {
       
   227 	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
       
   228 	return (DW_DLV_ERROR);
       
   229     }
       
   230 
       
   231     if (cu_context->cc_dbg == NULL) {
       
   232 	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
       
   233 	return (DW_DLV_ERROR);
       
   234     }
       
   235 
       
   236     *return_attr = (attr->ar_attribute);
       
   237     return DW_DLV_OK;
       
   238 }
       
   239 
       
   240 
       
   241 /* 
       
   242     DW_FORM_ref_addr is considered an incorrect form 
       
   243     for this call because this function returns an 
       
   244     offset  within the local CU thru the pointer.
       
   245 
       
   246     DW_FORM_ref_addr is a global-offset into the debug_info section.
       
   247     A DW_FORM_ref_addr cannot be returned by this interface:
       
   248     see dwarf_global_formref();
       
   249 
       
   250     DW_FORM_ref_addr has a value which was documented in
       
   251     DWARF2 as address-size but which was always an offset
       
   252     so should have always been offset size (wording
       
   253     corrected in DWARF3). 
       
   254     
       
   255 */
       
   256 int
       
   257 dwarf_formref(Dwarf_Attribute attr,
       
   258 	      Dwarf_Off * ret_offset, Dwarf_Error * error)
       
   259 {
       
   260     Dwarf_Debug dbg;
       
   261     Dwarf_Unsigned offset;
       
   262     Dwarf_CU_Context cu_context;
       
   263 
       
   264 
       
   265     if (attr == NULL) {
       
   266 	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
       
   267 	return (DW_DLV_ERROR);
       
   268     }
       
   269 
       
   270     cu_context = attr->ar_cu_context;
       
   271     if (cu_context == NULL) {
       
   272 	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
       
   273 	return (DW_DLV_ERROR);
       
   274     }
       
   275 
       
   276     if (cu_context->cc_dbg == NULL) {
       
   277 	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
       
   278 	return (DW_DLV_ERROR);
       
   279     }
       
   280     dbg = cu_context->cc_dbg;
       
   281 
       
   282     switch (attr->ar_attribute_form) {
       
   283 
       
   284     case DW_FORM_ref1:
       
   285 	offset = *(Dwarf_Small *) attr->ar_debug_info_ptr;
       
   286 	break;
       
   287 
       
   288     case DW_FORM_ref2:
       
   289 	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
       
   290 		       attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
       
   291 	break;
       
   292 
       
   293     case DW_FORM_ref4:
       
   294 	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
       
   295 		       attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
       
   296 	break;
       
   297 
       
   298     case DW_FORM_ref8:
       
   299 	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
       
   300 		       attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned));
       
   301 	break;
       
   302 
       
   303     case DW_FORM_ref_udata:
       
   304 	offset = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL);
       
   305 	break;
       
   306 
       
   307     default:
       
   308 	_dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM);
       
   309 	return (DW_DLV_ERROR);
       
   310     }
       
   311 
       
   312     /* Check that offset is within current cu portion of .debug_info. */
       
   313 
       
   314     if (offset >= cu_context->cc_length +
       
   315 	cu_context->cc_length_size + cu_context->cc_extension_size) {
       
   316 	_dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD);
       
   317 	return (DW_DLV_ERROR);
       
   318     }
       
   319 
       
   320     *ret_offset = (offset);
       
   321     return DW_DLV_OK;
       
   322 }
       
   323 
       
   324 /* 
       
   325     Since this returns section-relative debug_info offsets,
       
   326     this can represent all REFERENCE forms correctly
       
   327     and allows all forms.
       
   328 
       
   329     DW_FORM_ref_addr has a value which was documented in
       
   330     DWARF2 as address-size but which was always an offset
       
   331     so should have always been offset size (wording
       
   332     corrected in DWARF3).
       
   333     
       
   334 */
       
   335 int
       
   336 dwarf_global_formref(Dwarf_Attribute attr,
       
   337 		     Dwarf_Off * ret_offset, Dwarf_Error * error)
       
   338 {
       
   339     Dwarf_Debug dbg;
       
   340     Dwarf_Unsigned offset;
       
   341     Dwarf_Addr ref_addr;
       
   342     Dwarf_CU_Context cu_context;
       
   343 
       
   344     if (attr == NULL) {
       
   345 	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
       
   346 	return (DW_DLV_ERROR);
       
   347     }
       
   348 
       
   349     cu_context = attr->ar_cu_context;
       
   350     if (cu_context == NULL) {
       
   351 	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
       
   352 	return (DW_DLV_ERROR);
       
   353     }
       
   354 
       
   355     if (cu_context->cc_dbg == NULL) {
       
   356 	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
       
   357 	return (DW_DLV_ERROR);
       
   358     }
       
   359     dbg = cu_context->cc_dbg;
       
   360 
       
   361     switch (attr->ar_attribute_form) {
       
   362 
       
   363     case DW_FORM_ref1:
       
   364 	offset = *(Dwarf_Small *) attr->ar_debug_info_ptr;
       
   365 	goto fixoffset;
       
   366 
       
   367     case DW_FORM_ref2:
       
   368 	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
       
   369 		       attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
       
   370 	goto fixoffset;
       
   371 
       
   372     case DW_FORM_ref4:
       
   373 	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
       
   374 		       attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
       
   375 	goto fixoffset;
       
   376 
       
   377     case DW_FORM_ref8:
       
   378 	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
       
   379 		       attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned));
       
   380 	goto fixoffset;
       
   381 
       
   382     case DW_FORM_ref_udata:
       
   383 	offset = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL);
       
   384 
       
   385       fixoffset:		/* we have a local offset, make it
       
   386 				   global */
       
   387 
       
   388 	/* check legality of offset */
       
   389 	if (offset >= cu_context->cc_length +
       
   390 	    cu_context->cc_length_size +
       
   391 	    cu_context->cc_extension_size) {
       
   392 	    _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD);
       
   393 	    return (DW_DLV_ERROR);
       
   394 	}
       
   395 
       
   396 	/* globalize the offset */
       
   397 	offset += cu_context->cc_debug_info_offset;
       
   398 	break;
       
   399 
       
   400     case DW_FORM_ref_addr:
       
   401 	/* This offset is defined to be debug_info global already, so
       
   402 	   use this value unaltered. */
       
   403 	READ_UNALIGNED(dbg, ref_addr, Dwarf_Addr,
       
   404 		       attr->ar_debug_info_ptr,
       
   405 		       cu_context->cc_length_size);
       
   406 	offset = ref_addr;
       
   407 	break;
       
   408     default:
       
   409 	_dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM);
       
   410 	return (DW_DLV_ERROR);
       
   411     }
       
   412 
       
   413     /* Check that offset is within current cu portion of .debug_info. */
       
   414 
       
   415     *ret_offset = (offset);
       
   416     return DW_DLV_OK;
       
   417 }
       
   418 
       
   419 
       
   420 int
       
   421 dwarf_formaddr(Dwarf_Attribute attr,
       
   422 	       Dwarf_Addr * return_addr, Dwarf_Error * error)
       
   423 {
       
   424     Dwarf_Debug dbg;
       
   425     Dwarf_Addr ret_addr;
       
   426     Dwarf_CU_Context cu_context;
       
   427 
       
   428     if (attr == NULL) {
       
   429 	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
       
   430 	return (DW_DLV_ERROR);
       
   431     }
       
   432 
       
   433     cu_context = attr->ar_cu_context;
       
   434     if (cu_context == NULL) {
       
   435 	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
       
   436 	return (DW_DLV_ERROR);
       
   437     }
       
   438 
       
   439     if (cu_context->cc_dbg == NULL) {
       
   440 	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
       
   441 	return (DW_DLV_ERROR);
       
   442     }
       
   443     dbg = cu_context->cc_dbg;
       
   444 
       
   445     if (attr->ar_attribute_form == DW_FORM_addr
       
   446 	/* || attr->ar_attribute_form == DW_FORM_ref_addr Allowance of
       
   447 	   DW_FORM_ref_addr was a mistake. The value returned in that
       
   448 	   case is NOT an address it is a global debug_info offset (ie, 
       
   449 	   not CU-relative offset within the CU in debug_info). The
       
   450 	   Dwarf document refers to it as an address (misleadingly) in
       
   451 	   sec 6.5.4 where it describes the reference form. It is
       
   452 	   address-sized so that the linker can easily update it, but
       
   453 	   it is a reference inside the debug_info section. No longer
       
   454 	   allowed. */
       
   455 	) {
       
   456 
       
   457 	READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
       
   458 		       attr->ar_debug_info_ptr, dbg->de_pointer_size);
       
   459 	*return_addr = ret_addr;
       
   460 	return (DW_DLV_OK);
       
   461     }
       
   462 
       
   463     _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
       
   464     return (DW_DLV_ERROR);
       
   465 }
       
   466 
       
   467 
       
   468 int
       
   469 dwarf_formflag(Dwarf_Attribute attr,
       
   470 	       Dwarf_Bool * ret_bool, Dwarf_Error * error)
       
   471 {
       
   472     Dwarf_CU_Context cu_context;
       
   473 
       
   474     if (attr == NULL) {
       
   475 	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
       
   476 	return (DW_DLV_ERROR);
       
   477     }
       
   478 
       
   479     cu_context = attr->ar_cu_context;
       
   480     if (cu_context == NULL) {
       
   481 	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
       
   482 	return (DW_DLV_ERROR);
       
   483     }
       
   484 
       
   485     if (cu_context->cc_dbg == NULL) {
       
   486 	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
       
   487 	return (DW_DLV_ERROR);
       
   488     }
       
   489 
       
   490     if (attr->ar_attribute_form == DW_FORM_flag) {
       
   491 	*ret_bool = (*(Dwarf_Small *) attr->ar_debug_info_ptr != 0);
       
   492 	return (DW_DLV_OK);
       
   493     }
       
   494     _dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD);
       
   495     return (DW_DLV_ERROR);
       
   496 }
       
   497 
       
   498 
       
   499 int
       
   500 dwarf_formudata(Dwarf_Attribute attr,
       
   501 		Dwarf_Unsigned * return_uval, Dwarf_Error * error)
       
   502 {
       
   503     Dwarf_Unsigned ret_value;
       
   504     Dwarf_Debug dbg;
       
   505     Dwarf_CU_Context cu_context;
       
   506 
       
   507     if (attr == NULL) {
       
   508 	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
       
   509 	return (DW_DLV_ERROR);
       
   510     }
       
   511 
       
   512 
       
   513     cu_context = attr->ar_cu_context;
       
   514     if (cu_context == NULL) {
       
   515 	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
       
   516 	return (DW_DLV_ERROR);
       
   517     }
       
   518 
       
   519     dbg = cu_context->cc_dbg;
       
   520     if (dbg == NULL) {
       
   521 	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
       
   522 	return (DW_DLV_ERROR);
       
   523     }
       
   524 
       
   525     switch (attr->ar_attribute_form) {
       
   526 
       
   527     case DW_FORM_data1:
       
   528 	READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
       
   529 		       attr->ar_debug_info_ptr, sizeof(Dwarf_Small));
       
   530 	*return_uval = ret_value;
       
   531 	return DW_DLV_OK;
       
   532 
       
   533     /* READ_UNALIGNED does the right thing as it reads
       
   534        the right number bits and generates host order. 
       
   535        So we can just assign to *return_uval. */
       
   536     case DW_FORM_data2:{
       
   537 	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
       
   538 			   attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
       
   539 	    *return_uval = ret_value;
       
   540 	    return DW_DLV_OK;
       
   541 	}
       
   542 
       
   543     case DW_FORM_data4:{
       
   544 	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
       
   545 			   attr->ar_debug_info_ptr,
       
   546 			   sizeof(Dwarf_ufixed));
       
   547 	    *return_uval = ret_value;
       
   548 	    return DW_DLV_OK;
       
   549 	}
       
   550 
       
   551     case DW_FORM_data8:{
       
   552 	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
       
   553 			   attr->ar_debug_info_ptr,
       
   554 			   sizeof(Dwarf_Unsigned));
       
   555 	    *return_uval = ret_value;
       
   556 	    return DW_DLV_OK;
       
   557 	}
       
   558 
       
   559     case DW_FORM_udata:
       
   560 	ret_value =
       
   561 	    (_dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL));
       
   562 	*return_uval = ret_value;
       
   563 	return DW_DLV_OK;
       
   564 
       
   565 
       
   566 	/* see bug 583450. We do not allow reading sdata from a udata
       
   567 	   value. Caller can retry, calling sdata */
       
   568 
       
   569 
       
   570     default:
       
   571 	break;
       
   572     }
       
   573     _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
       
   574     return (DW_DLV_ERROR);
       
   575 }
       
   576 
       
   577 
       
   578 int
       
   579 dwarf_formsdata(Dwarf_Attribute attr,
       
   580 		Dwarf_Signed * return_sval, Dwarf_Error * error)
       
   581 {
       
   582     Dwarf_Signed ret_value;
       
   583     Dwarf_Debug dbg;
       
   584     Dwarf_CU_Context cu_context;
       
   585 
       
   586     if (attr == NULL) {
       
   587 	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
       
   588 	return (DW_DLV_ERROR);
       
   589     }
       
   590 
       
   591     cu_context = attr->ar_cu_context;
       
   592     if (cu_context == NULL) {
       
   593 	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
       
   594 	return (DW_DLV_ERROR);
       
   595     }
       
   596 
       
   597     dbg = cu_context->cc_dbg;
       
   598     if (dbg == NULL) {
       
   599 	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
       
   600 	return (DW_DLV_ERROR);
       
   601     }
       
   602 
       
   603     switch (attr->ar_attribute_form) {
       
   604 
       
   605     case DW_FORM_data1:
       
   606 	*return_sval = (*(Dwarf_Sbyte *) attr->ar_debug_info_ptr);
       
   607 	return DW_DLV_OK;
       
   608 
       
   609     /* READ_UNALIGNED does not sign extend. 
       
   610        So we have to use a cast to get the
       
   611        value sign extended in the right way for each case. */
       
   612     case DW_FORM_data2:{
       
   613 	    READ_UNALIGNED(dbg, ret_value, Dwarf_Signed,
       
   614 			   attr->ar_debug_info_ptr,
       
   615 			   sizeof(Dwarf_Shalf));
       
   616 	    *return_sval = (Dwarf_Shalf) ret_value;
       
   617 	    return DW_DLV_OK;
       
   618 
       
   619 	}
       
   620 
       
   621     case DW_FORM_data4:{
       
   622 	    READ_UNALIGNED(dbg, ret_value, Dwarf_Signed,
       
   623 			   attr->ar_debug_info_ptr,
       
   624 			   sizeof(Dwarf_sfixed));
       
   625 	    *return_sval = (Dwarf_sfixed) ret_value;
       
   626 	    return DW_DLV_OK;
       
   627 	}
       
   628 
       
   629     case DW_FORM_data8:{
       
   630 	    READ_UNALIGNED(dbg, ret_value, Dwarf_Signed,
       
   631 			   attr->ar_debug_info_ptr,
       
   632 			   sizeof(Dwarf_Signed));
       
   633 	    *return_sval = (Dwarf_Signed) ret_value;
       
   634 	    return DW_DLV_OK;
       
   635 	}
       
   636 
       
   637     case DW_FORM_sdata:
       
   638 	ret_value =
       
   639 	    (_dwarf_decode_s_leb128(attr->ar_debug_info_ptr, NULL));
       
   640 	*return_sval = ret_value;
       
   641 	return DW_DLV_OK;
       
   642 
       
   643 
       
   644 	/* see bug 583450. We do not allow reading sdata from a udata
       
   645 	   value. Caller can retry, calling sdata */
       
   646 
       
   647 
       
   648     default:
       
   649 	break;
       
   650     }
       
   651     _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
       
   652     return (DW_DLV_ERROR);
       
   653 }
       
   654 
       
   655 
       
   656 int
       
   657 dwarf_formblock(Dwarf_Attribute attr,
       
   658 		Dwarf_Block ** return_block, Dwarf_Error * error)
       
   659 {
       
   660     Dwarf_CU_Context cu_context;
       
   661     Dwarf_Debug dbg;
       
   662     Dwarf_Unsigned length;
       
   663     Dwarf_Small *data;
       
   664     Dwarf_Word leb128_length;
       
   665     Dwarf_Block *ret_block;
       
   666 
       
   667     if (attr == NULL) {
       
   668 	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
       
   669 	return (DW_DLV_ERROR);
       
   670     }
       
   671 
       
   672     cu_context = attr->ar_cu_context;
       
   673     if (cu_context == NULL) {
       
   674 	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
       
   675 	return (DW_DLV_ERROR);
       
   676     }
       
   677 
       
   678     if (cu_context->cc_dbg == NULL) {
       
   679 	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
       
   680 	return (DW_DLV_ERROR);
       
   681     }
       
   682     dbg = cu_context->cc_dbg;
       
   683 
       
   684     switch (attr->ar_attribute_form) {
       
   685 
       
   686     case DW_FORM_block1:
       
   687 	length = *(Dwarf_Small *) attr->ar_debug_info_ptr;
       
   688 	data = attr->ar_debug_info_ptr + sizeof(Dwarf_Small);
       
   689 	break;
       
   690 
       
   691     case DW_FORM_block2:
       
   692 	READ_UNALIGNED(dbg, length, Dwarf_Unsigned,
       
   693 		       attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
       
   694 	data = attr->ar_debug_info_ptr + sizeof(Dwarf_Half);
       
   695 	break;
       
   696 
       
   697     case DW_FORM_block4:
       
   698 	READ_UNALIGNED(dbg, length, Dwarf_Unsigned,
       
   699 		       attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
       
   700 	data = attr->ar_debug_info_ptr + sizeof(Dwarf_ufixed);
       
   701 	break;
       
   702 
       
   703     case DW_FORM_block:
       
   704 	length = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr,
       
   705 					&leb128_length);
       
   706 	data = attr->ar_debug_info_ptr + leb128_length;
       
   707 	break;
       
   708 
       
   709     default:
       
   710 	_dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD);
       
   711 	return (DW_DLV_ERROR);
       
   712     }
       
   713 
       
   714     /* Check that block lies within current cu in .debug_info. */
       
   715     if (attr->ar_debug_info_ptr + length >=
       
   716 	dbg->de_debug_info + cu_context->cc_debug_info_offset +
       
   717 	cu_context->cc_length + cu_context->cc_length_size +
       
   718 	cu_context->cc_extension_size) {
       
   719 	_dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
       
   720 	return (DW_DLV_ERROR);
       
   721     }
       
   722 
       
   723     ret_block = (Dwarf_Block *) _dwarf_get_alloc(dbg, DW_DLA_BLOCK, 1);
       
   724     if (ret_block == NULL) {
       
   725 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
       
   726 	return (DW_DLV_ERROR);
       
   727     }
       
   728 
       
   729     ret_block->bl_len = length;
       
   730     ret_block->bl_data = (Dwarf_Ptr) data;
       
   731     ret_block->bl_from_loclist = 0;
       
   732     ret_block->bl_section_offset = data - dbg->de_debug_info;
       
   733 
       
   734 
       
   735     *return_block = ret_block;
       
   736     return (DW_DLV_OK);
       
   737 }
       
   738 
       
   739 
       
   740 /* Contrary to long standing documentation,
       
   741    The string pointer returned thru return_str must
       
   742    never have dwarf_dealloc() applied to it.
       
   743    Documentation fixed July 2005.
       
   744 */
       
   745 int
       
   746 dwarf_formstring(Dwarf_Attribute attr,
       
   747 		 char **return_str, Dwarf_Error * error)
       
   748 {
       
   749     Dwarf_CU_Context cu_context;
       
   750     Dwarf_Debug dbg;
       
   751     Dwarf_Unsigned offset;
       
   752     int res;
       
   753 
       
   754     if (attr == NULL) {
       
   755 	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
       
   756 	return (DW_DLV_ERROR);
       
   757     }
       
   758 
       
   759     cu_context = attr->ar_cu_context;
       
   760     if (cu_context == NULL) {
       
   761 	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
       
   762 	return (DW_DLV_ERROR);
       
   763     }
       
   764 
       
   765     if (cu_context->cc_dbg == NULL) {
       
   766 	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
       
   767 	return (DW_DLV_ERROR);
       
   768     }
       
   769     dbg = cu_context->cc_dbg;
       
   770 
       
   771     if (attr->ar_attribute_form == DW_FORM_string) {
       
   772 
       
   773 	void *begin = attr->ar_debug_info_ptr;
       
   774 
       
   775 	if (0 == dbg->de_assume_string_in_bounds) {
       
   776 	    /* Check that string lies within current cu in .debug_info. 
       
   777 	     */
       
   778 	    void *end = dbg->de_debug_info +
       
   779 		cu_context->cc_debug_info_offset +
       
   780 		cu_context->cc_length + cu_context->cc_length_size +
       
   781 		cu_context->cc_extension_size;
       
   782 	    if (0 == _dwarf_string_valid(begin, end)) {
       
   783 		_dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
       
   784 		return (DW_DLV_ERROR);
       
   785 	    }
       
   786 	}
       
   787 	*return_str = (char *) (begin);
       
   788 	return DW_DLV_OK;
       
   789     }
       
   790 
       
   791     if (attr->ar_attribute_form == DW_FORM_strp) {
       
   792 	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
       
   793 		       attr->ar_debug_info_ptr,
       
   794 		       cu_context->cc_length_size);
       
   795 
       
   796 	res =
       
   797 	    _dwarf_load_section(dbg,
       
   798 				dbg->de_debug_str_index,
       
   799 				&dbg->de_debug_str, error);
       
   800 	if (res != DW_DLV_OK) {
       
   801 	    return res;
       
   802 	}
       
   803 
       
   804 	*return_str = (char *) (dbg->de_debug_str + offset);
       
   805 	return DW_DLV_OK;
       
   806     }
       
   807 
       
   808     _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
       
   809     return (DW_DLV_ERROR);
       
   810 }