tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_util.h
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2 
       
     3   Copyright (C) 2000,2003,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 /*
       
    46     Decodes unsigned leb128 encoded numbers.
       
    47     Make sure ptr is a pointer to a 1-byte type.  
       
    48     In 2003 and earlier this was a hand-inlined
       
    49     version of _dwarf_decode_u_leb128() which did
       
    50     not work correctly if Dwarf_Word was 64 bits.
       
    51 */
       
    52 #define DECODE_LEB128_UWORD(ptr, value) \
       
    53     do { \
       
    54        Dwarf_Word uleblen; \
       
    55 	value = _dwarf_decode_u_leb128(ptr,&uleblen); \
       
    56         ptr += uleblen; \
       
    57     } while (0)
       
    58 
       
    59 /*
       
    60     Decodes signed leb128 encoded numbers.
       
    61     Make sure ptr is a pointer to a 1-byte type.
       
    62     In 2003 and earlier this was a hand-inlined
       
    63     version of _dwarf_decode_s_leb128() which did
       
    64     not work correctly if Dwarf_Word was 64 bits.
       
    65 
       
    66 */
       
    67 #define DECODE_LEB128_SWORD(ptr, value) \
       
    68     do { \
       
    69        Dwarf_Word sleblen; \
       
    70 	value = _dwarf_decode_s_leb128(ptr,&sleblen); \
       
    71         ptr += sleblen; \
       
    72     } while(0)
       
    73 
       
    74 
       
    75 /*
       
    76     Skips leb128_encoded numbers that are guaranteed 
       
    77     to be no more than 4 bytes long.  Same for both
       
    78     signed and unsigned numbers.
       
    79 */
       
    80 #define SKIP_LEB128_WORD(ptr) \
       
    81     do{ if ((*(ptr++) & 0x80) != 0) { \
       
    82         if ((*(ptr++) & 0x80) != 0) { \
       
    83             if ((*(ptr++) & 0x80) != 0) { \
       
    84 	        if ((*(ptr++) & 0x80) != 0) { \
       
    85 	        } \
       
    86 	    } \
       
    87         } \
       
    88     } } while (0)
       
    89 
       
    90 
       
    91 #define CHECK_DIE(die, error_ret_value) \
       
    92 do {if (die == NULL) { \
       
    93 	_dwarf_error(NULL, error, DW_DLE_DIE_NULL); \
       
    94 	return(error_ret_value); \
       
    95     } \
       
    96     if (die->di_cu_context == NULL) { \
       
    97 	_dwarf_error(NULL, error, DW_DLE_DIE_NO_CU_CONTEXT); \
       
    98 	return(error_ret_value); \
       
    99     } \
       
   100     if (die->di_cu_context->cc_dbg == NULL) { \
       
   101 	_dwarf_error(NULL, error, DW_DLE_DBG_NULL); \
       
   102 	return(error_ret_value); \
       
   103     }  \
       
   104 } while (0)
       
   105 
       
   106 
       
   107 /* 
       
   108    Reads 'source' for 'length' bytes from unaligned addr.
       
   109 
       
   110    Avoids any constant-in-conditional warnings and
       
   111    avoids a test in the generated code (for non-const cases,
       
   112 	which are in the majority.)
       
   113    Uses a temp to avoid the test.
       
   114    The decl here should avoid any problem of size in the temp.
       
   115    This code is ENDIAN DEPENDENT
       
   116    The memcpy args are the endian issue.
       
   117 */
       
   118 typedef Dwarf_Unsigned BIGGEST_UINT;
       
   119 
       
   120 #ifdef WORDS_BIGENDIAN
       
   121 #define READ_UNALIGNED(dbg,dest,desttype, source, length) \
       
   122     do { \
       
   123       BIGGEST_UINT _ltmp = 0;  \
       
   124       dbg->de_copy_word( (((char *)(&_ltmp)) + sizeof(_ltmp) - length), \
       
   125 			source, length) ; \
       
   126       dest = (desttype)_ltmp;  \
       
   127     } while (0)
       
   128 
       
   129 
       
   130 /*
       
   131     This macro sign-extends a variable depending on the length.
       
   132     It fills the bytes between the size of the destination and
       
   133     the length with appropriate padding.
       
   134     This code is ENDIAN DEPENDENT but dependent only
       
   135     on host endianness, not object file endianness.
       
   136     The memcpy args are the issue.
       
   137 */
       
   138 #define SIGN_EXTEND(dest, length) \
       
   139     do {if (*(Dwarf_Sbyte *)((char *)&dest + sizeof(dest) - length) < 0) {\
       
   140 	memcpy((char *)&dest, "\xff\xff\xff\xff\xff\xff\xff\xff", \
       
   141 	    sizeof(dest) - length);  \
       
   142         } \
       
   143      } while (0)
       
   144 #else /* LITTLE ENDIAN */
       
   145 
       
   146 #define READ_UNALIGNED(dbg,dest,desttype, source, length) \
       
   147     do  { \
       
   148       BIGGEST_UINT _ltmp = 0;  \
       
   149       dbg->de_copy_word( (char *)(&_ltmp) , \
       
   150                         source, length) ; \
       
   151       dest = (desttype)_ltmp;  \
       
   152      } while (0)
       
   153 
       
   154 
       
   155 /*
       
   156     This macro sign-extends a variable depending on the length.
       
   157     It fills the bytes between the size of the destination and
       
   158     the length with appropriate padding.
       
   159     This code is ENDIAN DEPENDENT but dependent only
       
   160     on host endianness, not object file endianness.
       
   161     The memcpy args are the issue.
       
   162 */
       
   163 #define SIGN_EXTEND(dest, length) \
       
   164     do {if (*(Dwarf_Sbyte *)((char *)&dest + (length-1)) < 0) {\
       
   165         memcpy((char *)&dest+length,    \
       
   166                 "\xff\xff\xff\xff\xff\xff\xff\xff", \
       
   167             sizeof(dest) - length); \
       
   168         }  \
       
   169     } while (0)
       
   170 
       
   171 #endif /* ! LITTLE_ENDIAN */
       
   172 
       
   173 
       
   174 
       
   175 /*
       
   176    READ_AREA LENGTH reads the length (the older way
       
   177    of pure 32 or 64 bit
       
   178    or the new proposed dwarfv2.1 64bit-extension way)
       
   179 
       
   180    It reads the bits from where rw_src_data_p  points to 
       
   181    and updates the rw_src_data_p to point past what was just read.
       
   182 
       
   183    It updates w_length_size and w_exten_size (which
       
   184 	are really issues only for the dwarfv2.1  64bit extension).
       
   185 
       
   186    r_dbg is just the current dbg pointer.
       
   187    w_target is the output length field.
       
   188    r_targtype is the output type. Always Dwarf_Unsigned so far.
       
   189   
       
   190 */
       
   191 /* This one handles the v2.1 64bit extension  
       
   192    and 32bit (and   MIPS fixed 64  bit via the
       
   193 	dwarf_init-set r_dbg->de_length_size)..
       
   194    It does not recognize any but the one distingushed value
       
   195    (the only one with defined meaning).
       
   196    It assumes that no CU will have a length
       
   197 	0xffffffxx  (32bit length)
       
   198 	or
       
   199 	0xffffffxx xxxxxxxx (64bit length)
       
   200    which makes possible auto-detection of the extension.
       
   201 
       
   202    This depends on knowing that only a non-zero length
       
   203    is legitimate (AFAICT), and for IRIX non-standard -64 
       
   204    dwarf that the first 32 bits of the 64bit offset will be
       
   205    zero (because the compiler could not handle a truly large 
       
   206    value as of Jan 2003 and because no app has that much debug 
       
   207    info anyway (yet)).
       
   208 
       
   209    At present not testing for '64bit elf' here as that
       
   210    does not seem necessary (none of the 64bit length seems 
       
   211    appropriate unless it's  ident[EI_CLASS] == ELFCLASS64).
       
   212    Might be a good idea though.
       
   213 
       
   214 */
       
   215 #   define    READ_AREA_LENGTH(r_dbg,w_target,r_targtype,         \
       
   216 	rw_src_data_p,w_length_size,w_exten_size)                 \
       
   217 do {    READ_UNALIGNED(r_dbg,w_target,r_targtype,                     \
       
   218                 rw_src_data_p, ORIGINAL_DWARF_OFFSET_SIZE);       \
       
   219     if(w_target == DISTINGUISHED_VALUE) {                         \
       
   220 	     /* dwarf3 64bit extension */                         \
       
   221              w_length_size  = DISTINGUISHED_VALUE_OFFSET_SIZE;    \
       
   222              rw_src_data_p += ORIGINAL_DWARF_OFFSET_SIZE;         \
       
   223              w_exten_size   = ORIGINAL_DWARF_OFFSET_SIZE;         \
       
   224              READ_UNALIGNED(r_dbg,w_target,r_targtype,            \
       
   225                   rw_src_data_p, DISTINGUISHED_VALUE_OFFSET_SIZE);\
       
   226              rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE;    \
       
   227     } else {                                                      \
       
   228 	if(w_target == 0 && r_dbg->de_big_endian_object) {        \
       
   229 	     /* IRIX 64 bit, big endian */                        \
       
   230              READ_UNALIGNED(r_dbg,w_target,r_targtype,            \
       
   231                 rw_src_data_p, DISTINGUISHED_VALUE_OFFSET_SIZE);  \
       
   232 	     w_length_size  = DISTINGUISHED_VALUE_OFFSET_SIZE;    \
       
   233 	     rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE;    \
       
   234 	     w_exten_size = 0;                                    \
       
   235 	} else {                                                  \
       
   236 	     /* standard 32 bit dwarf2/dwarf3 */                  \
       
   237 	     w_exten_size   = 0;                                  \
       
   238              w_length_size  = ORIGINAL_DWARF_OFFSET_SIZE;         \
       
   239              rw_src_data_p += w_length_size;                      \
       
   240 	}                                                         \
       
   241     } } while(0)
       
   242 
       
   243 
       
   244 
       
   245 Dwarf_Unsigned
       
   246 _dwarf_decode_u_leb128(Dwarf_Small * leb128,
       
   247 		       Dwarf_Word * leb128_length);
       
   248 
       
   249 Dwarf_Signed
       
   250 _dwarf_decode_s_leb128(Dwarf_Small * leb128,
       
   251 		       Dwarf_Word * leb128_length);
       
   252 
       
   253 Dwarf_Unsigned
       
   254 _dwarf_get_size_of_val(Dwarf_Debug dbg,
       
   255 		       Dwarf_Unsigned form,
       
   256 		       Dwarf_Small * val_ptr, int v_length_size);
       
   257 
       
   258 /*
       
   259     This struct is used to build a hash table for the
       
   260     abbreviation codes for a compile-unit.  
       
   261 */
       
   262 struct Dwarf_Hash_Table_s {
       
   263     Dwarf_Abbrev_List at_head;
       
   264     Dwarf_Abbrev_List at_tail;
       
   265 };
       
   266 
       
   267 Dwarf_Abbrev_List
       
   268 _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context,
       
   269 			   Dwarf_Word code);
       
   270 
       
   271 
       
   272 /* return 1 if string ends before 'endptr' else
       
   273 ** return 0 meaning string is not properly terminated.
       
   274 ** Presumption is the 'endptr' pts to end of some dwarf section data.
       
   275 */
       
   276 int _dwarf_string_valid(void *startptr, void *endptr);
       
   277 
       
   278 Dwarf_Unsigned _dwarf_length_of_cu_header(Dwarf_Debug,
       
   279 					  Dwarf_Unsigned offset);
       
   280 Dwarf_Unsigned _dwarf_length_of_cu_header_simple(Dwarf_Debug);
       
   281 
       
   282 int _dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error *error);