tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_util.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2   Copyright (C) 2000,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
       
     3   Portions Copyright (C) 2007 David Anderson. 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., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
       
    23   USA.
       
    24 
       
    25   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
       
    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 /* The address of the Free Software Foundation is
       
    36    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
       
    37    Boston, MA 02110-1301, USA.
       
    38    SGI has moved from the Crittenden Lane address.
       
    39 */
       
    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 
       
    51 
       
    52 /*
       
    53     Given a form, and a pointer to the bytes encoding 
       
    54     a value of that form, val_ptr, this function returns
       
    55     the length, in bytes, of a value of that form.
       
    56     When using this function, check for a return of 0
       
    57     a recursive DW_FORM_INDIRECT value.
       
    58 */
       
    59 Dwarf_Unsigned
       
    60 _dwarf_get_size_of_val(Dwarf_Debug dbg,
       
    61 		       Dwarf_Unsigned form,
       
    62 		       Dwarf_Small * val_ptr, int v_length_size)
       
    63 {
       
    64     Dwarf_Unsigned length = 0;
       
    65     Dwarf_Word leb128_length = 0;
       
    66     Dwarf_Unsigned form_indirect = 0;
       
    67     Dwarf_Unsigned ret_value = 0;
       
    68 
       
    69     switch (form) {
       
    70 
       
    71     default:			/* Handles form = 0. */
       
    72 	return (form);
       
    73 
       
    74     case DW_FORM_addr:
       
    75 	return (dbg->de_pointer_size);
       
    76 
       
    77     case DW_FORM_ref_addr:
       
    78 	return (v_length_size);
       
    79 
       
    80     case DW_FORM_block1:
       
    81 	return (*(Dwarf_Small *) val_ptr + 1);
       
    82 
       
    83     case DW_FORM_block2:
       
    84 	READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
       
    85 		       val_ptr, sizeof(Dwarf_Half));
       
    86 	return (ret_value + sizeof(Dwarf_Half));
       
    87 
       
    88     case DW_FORM_block4:
       
    89 	READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
       
    90 		       val_ptr, sizeof(Dwarf_ufixed));
       
    91 	return (ret_value + sizeof(Dwarf_ufixed));
       
    92 
       
    93 
       
    94     case DW_FORM_data1:
       
    95 	return (1);
       
    96 
       
    97     case DW_FORM_data2:
       
    98 	return (2);
       
    99 
       
   100     case DW_FORM_data4:
       
   101 	return (4);
       
   102 
       
   103     case DW_FORM_data8:
       
   104 	return (8);
       
   105 
       
   106     case DW_FORM_string:
       
   107 	return (strlen((char *) val_ptr) + 1);
       
   108 
       
   109     case DW_FORM_block:
       
   110 	length = _dwarf_decode_u_leb128(val_ptr, &leb128_length);
       
   111 	return (length + leb128_length);
       
   112 
       
   113     case DW_FORM_flag:
       
   114 	return (1);
       
   115 
       
   116     case DW_FORM_ref_udata:
       
   117 	_dwarf_decode_u_leb128(val_ptr, &leb128_length);
       
   118 	return (leb128_length);
       
   119 
       
   120     case DW_FORM_indirect:
       
   121 	{
       
   122 	    Dwarf_Word indir_len = 0;
       
   123 
       
   124 	    form_indirect = _dwarf_decode_u_leb128(val_ptr, &indir_len);
       
   125 	    if (form_indirect == DW_FORM_indirect) {
       
   126 		return (0);	/* We are in big trouble: The true form 
       
   127 				   of DW_FORM_indirect is
       
   128 				   DW_FORM_indirect? Nonsense. Should
       
   129 				   never happen. */
       
   130 	    }
       
   131 	    return (indir_len + _dwarf_get_size_of_val(dbg,
       
   132 						       form_indirect,
       
   133 						       val_ptr +
       
   134 						       indir_len,
       
   135 						       v_length_size));
       
   136 	}
       
   137 
       
   138     case DW_FORM_ref1:
       
   139 	return (1);
       
   140 
       
   141     case DW_FORM_ref2:
       
   142 	return (2);
       
   143 
       
   144     case DW_FORM_ref4:
       
   145 	return (4);
       
   146 
       
   147     case DW_FORM_ref8:
       
   148 	return (8);
       
   149 
       
   150     case DW_FORM_sdata:
       
   151 	_dwarf_decode_s_leb128(val_ptr, &leb128_length);
       
   152 	return (leb128_length);
       
   153 
       
   154     case DW_FORM_strp:
       
   155 	return (v_length_size);
       
   156 
       
   157     case DW_FORM_udata:
       
   158 	_dwarf_decode_u_leb128(val_ptr, &leb128_length);
       
   159 	return (leb128_length);
       
   160     }
       
   161 }
       
   162 
       
   163 
       
   164 /*
       
   165     This function returns a pointer to a Dwarf_Abbrev_List_s
       
   166     struct for the abbrev with the given code.  It puts the
       
   167     struct on the appropriate hash table.  It also adds all
       
   168     the abbrev between the last abbrev added and this one to
       
   169     the hash table.  In other words, the .debug_abbrev section
       
   170     is scanned sequentially from the top for an abbrev with
       
   171     the given code.  All intervening abbrevs are also put 
       
   172     into the hash table.
       
   173 
       
   174     This function hashes the given code, and checks the chain
       
   175     at that hash table entry to see if a Dwarf_Abbrev_List_s
       
   176     with the given code exists.  If yes, it returns a pointer
       
   177     to that struct.  Otherwise, it scans the .debug_abbrev
       
   178     section from the last byte scanned for that CU till either
       
   179     an abbrev with the given code is found, or an abbrev code
       
   180     of 0 is read.  It puts Dwarf_Abbrev_List_s entries for all
       
   181     abbrev's read till that point into the hash table.  The
       
   182     hash table contains both a head pointer and a tail pointer
       
   183     for each entry.
       
   184 
       
   185     Returns NULL on error.
       
   186 */
       
   187 Dwarf_Abbrev_List
       
   188 _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Word code)
       
   189 {
       
   190     Dwarf_Debug dbg = cu_context->cc_dbg;
       
   191     Dwarf_Hash_Table hash_table = cu_context->cc_abbrev_hash_table;
       
   192     Dwarf_Word hash_num;
       
   193     Dwarf_Abbrev_List hash_abbrev_list;
       
   194     Dwarf_Abbrev_List abbrev_list;
       
   195     Dwarf_Byte_Ptr abbrev_ptr;
       
   196     Dwarf_Half abbrev_code, abbrev_tag;
       
   197     Dwarf_Half attr_name, attr_form;
       
   198 
       
   199     hash_num = code % ABBREV_HASH_TABLE_SIZE;
       
   200     for (hash_abbrev_list = hash_table[hash_num].at_head;
       
   201 	 hash_abbrev_list != NULL && hash_abbrev_list->ab_code != code;
       
   202 	 hash_abbrev_list = hash_abbrev_list->ab_next);
       
   203     if (hash_abbrev_list != NULL)
       
   204 	return (hash_abbrev_list);
       
   205 
       
   206     abbrev_ptr = cu_context->cc_last_abbrev_ptr != NULL ?
       
   207 	cu_context->cc_last_abbrev_ptr :
       
   208 	dbg->de_debug_abbrev + cu_context->cc_abbrev_offset;
       
   209 
       
   210     /* End of abbrev's for this cu, since abbrev code is 0. */
       
   211     if (*abbrev_ptr == 0) {
       
   212 	return (NULL);
       
   213     }
       
   214 
       
   215     do {
       
   216 	Dwarf_Unsigned utmp;
       
   217 
       
   218 	DECODE_LEB128_UWORD(abbrev_ptr, utmp);
       
   219 	abbrev_code = (Dwarf_Half) utmp;
       
   220 	DECODE_LEB128_UWORD(abbrev_ptr, utmp);
       
   221 	abbrev_tag = (Dwarf_Half) utmp;
       
   222 
       
   223 	abbrev_list = (Dwarf_Abbrev_List)
       
   224 	    _dwarf_get_alloc(cu_context->cc_dbg, DW_DLA_ABBREV_LIST, 1);
       
   225 	if (abbrev_list == NULL)
       
   226 	    return (NULL);
       
   227 
       
   228 	hash_num = abbrev_code % ABBREV_HASH_TABLE_SIZE;
       
   229 	if (hash_table[hash_num].at_head == NULL) {
       
   230 	    hash_table[hash_num].at_head =
       
   231 		hash_table[hash_num].at_tail = abbrev_list;
       
   232 	} else {
       
   233 	    hash_table[hash_num].at_tail->ab_next = abbrev_list;
       
   234 	    hash_table[hash_num].at_tail = abbrev_list;
       
   235 	}
       
   236 
       
   237 	abbrev_list->ab_code = abbrev_code;
       
   238 	abbrev_list->ab_tag = abbrev_tag;
       
   239 
       
   240 	abbrev_list->ab_has_child = *(abbrev_ptr++);
       
   241 	abbrev_list->ab_abbrev_ptr = abbrev_ptr;
       
   242 
       
   243 	/* Cycle thru the abbrev content, ignoring the content except
       
   244 	   to find the end of the content. */
       
   245 	do {
       
   246 	    Dwarf_Unsigned utmp3;
       
   247 
       
   248 	    DECODE_LEB128_UWORD(abbrev_ptr, utmp3);
       
   249 	    attr_name = (Dwarf_Half) utmp3;
       
   250 	    DECODE_LEB128_UWORD(abbrev_ptr, utmp3);
       
   251 	    attr_form = (Dwarf_Half) utmp3;
       
   252 	} while (attr_name != 0 && attr_form != 0);
       
   253 
       
   254     } while (*abbrev_ptr != 0 && abbrev_code != code);
       
   255 
       
   256     cu_context->cc_last_abbrev_ptr = abbrev_ptr;
       
   257     return (abbrev_code == code ? abbrev_list : NULL);
       
   258 }
       
   259 
       
   260 
       
   261 /* return 1 if string ends before 'endptr' else
       
   262 ** return 0 meaning string is not properly terminated.
       
   263 ** Presumption is the 'endptr' pts to end of some dwarf section data.
       
   264 */
       
   265 int
       
   266 _dwarf_string_valid(void *startptr, void *endptr)
       
   267 {
       
   268 
       
   269     char *start = startptr;
       
   270     char *end = endptr;
       
   271 
       
   272     while (start < end) {
       
   273 	if (*start == 0) {
       
   274 	    return 1;		/* OK! */
       
   275 	}
       
   276 	++start;
       
   277 	++end;
       
   278     }
       
   279     return 0;			/* FAIL! bad string! */
       
   280 }
       
   281 
       
   282 /*
       
   283   A byte-swapping version of memcpy
       
   284   for cross-endian use.
       
   285   Only 2,4,8 should be lengths passed in.
       
   286 */
       
   287 void *
       
   288 _dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len)
       
   289 {
       
   290     void *orig_s1 = s1;
       
   291     unsigned char *targ = (unsigned char *) s1;
       
   292     unsigned char *src = (unsigned char *) s2;
       
   293 
       
   294     if (len == 4) {
       
   295 	targ[3] = src[0];
       
   296 	targ[2] = src[1];
       
   297 	targ[1] = src[2];
       
   298 	targ[0] = src[3];
       
   299     } else if (len == 8) {
       
   300 	targ[7] = src[0];
       
   301 	targ[6] = src[1];
       
   302 	targ[5] = src[2];
       
   303 	targ[4] = src[3];
       
   304 	targ[3] = src[4];
       
   305 	targ[2] = src[5];
       
   306 	targ[1] = src[6];
       
   307 	targ[0] = src[7];
       
   308     } else if (len == 2) {
       
   309 	targ[1] = src[0];
       
   310 	targ[0] = src[1];
       
   311     }
       
   312 /* should NOT get below here: is not the intended use */
       
   313     else if (len == 1) {
       
   314 	targ[0] = src[0];
       
   315     } else {
       
   316 	memcpy(s1, s2, len);
       
   317     }
       
   318 
       
   319     return orig_s1;
       
   320 }
       
   321 
       
   322 
       
   323 /*
       
   324   This calculation used to be sprinkled all over.
       
   325   Now brought to one place.
       
   326 
       
   327   We try to accurately compute the size of a cu header
       
   328   given a known cu header location ( an offset in .debug_info).
       
   329 
       
   330 */
       
   331 /* ARGSUSED */
       
   332 Dwarf_Unsigned
       
   333 _dwarf_length_of_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned offset)
       
   334 {
       
   335     int local_length_size = 0;
       
   336     int local_extension_size = 0;
       
   337     Dwarf_Unsigned length = 0;
       
   338     Dwarf_Small *cuptr = dbg->de_debug_info + offset;
       
   339 
       
   340     READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
       
   341 		     cuptr, local_length_size, local_extension_size);
       
   342 
       
   343     return local_extension_size +	/* initial extesion, if present 
       
   344 					 */
       
   345 	local_length_size +	/* Size of cu length field. */
       
   346 	sizeof(Dwarf_Half) +	/* Size of version stamp field. */
       
   347 	local_length_size +	/* Size of abbrev offset field. */
       
   348 	sizeof(Dwarf_Small);	/* Size of address size field. */
       
   349 
       
   350 }
       
   351 
       
   352 /*
       
   353 	Pretend we know nothing about the CU
       
   354 	and just roughly compute the result. 
       
   355 */
       
   356 Dwarf_Unsigned
       
   357 _dwarf_length_of_cu_header_simple(Dwarf_Debug dbg)
       
   358 {
       
   359     return dbg->de_length_size +	/* Size of cu length field. */
       
   360 	sizeof(Dwarf_Half) +	/* Size of version stamp field. */
       
   361 	dbg->de_length_size +	/* Size of abbrev offset field. */
       
   362 	sizeof(Dwarf_Small);	/* Size of address size field. */
       
   363 }
       
   364 
       
   365 /* Now that we delay loading .debug_info, we need to do the
       
   366    load in more places. So putting the load
       
   367    code in one place now instead of replicating it in multiple
       
   368    places.
       
   369 
       
   370 */
       
   371 int
       
   372 _dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error * error)
       
   373 {
       
   374     int res;
       
   375 
       
   376     /* Testing de_debug_info allows us to avoid testing
       
   377        de_debug_abbrev. One test instead of 2. .debug_info is useless
       
   378        without .debug_abbrev. */
       
   379     if (dbg->de_debug_info) {
       
   380 	return DW_DLV_OK;
       
   381     }
       
   382 
       
   383     res = _dwarf_load_section(dbg, dbg->de_debug_abbrev_index,
       
   384 			      &dbg->de_debug_abbrev, error);
       
   385     if (res != DW_DLV_OK) {
       
   386 	return res;
       
   387     }
       
   388     res = _dwarf_load_section(dbg, dbg->de_debug_info_index,
       
   389 			      &dbg->de_debug_info, error);
       
   390     return res;
       
   391 
       
   392 }