tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_die_deliv.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2 
       
     3   Copyright (C) 2000,2001,2002,2003,2004,2005,2006 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 #ifdef HAVE_ELF_H
       
    48 #include <elf.h>
       
    49 #endif
       
    50 #include <stdio.h>
       
    51 #include "dwarf_die_deliv.h"
       
    52 
       
    53 
       
    54 /*
       
    55     For a given Dwarf_Debug dbg, this function checks 
       
    56     if a CU that includes the given offset has been read 
       
    57     or not.  If yes, it returns the Dwarf_CU_Context 
       
    58     for the CU.  Otherwise it returns NULL.  Being an 
       
    59     internal routine, it is assumed that a valid dbg 
       
    60     is passed.
       
    61 
       
    62     **This is a sequential search.  May be too slow.
       
    63 
       
    64     If debug_info and debug_abbrev not loaded, this will
       
    65     wind up returning NULL. So no need to load before calling
       
    66     this.
       
    67 */
       
    68 static Dwarf_CU_Context
       
    69 _dwarf_find_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset)
       
    70 {
       
    71     Dwarf_CU_Context cu_context;
       
    72 
       
    73     if (offset >= dbg->de_info_last_offset)
       
    74 	return (NULL);
       
    75 
       
    76     if (dbg->de_cu_context != NULL &&
       
    77 	dbg->de_cu_context->cc_next != NULL &&
       
    78 	dbg->de_cu_context->cc_next->cc_debug_info_offset == offset) {
       
    79 
       
    80 	return (dbg->de_cu_context->cc_next);
       
    81     }
       
    82 
       
    83     if (dbg->de_cu_context != NULL &&
       
    84 	dbg->de_cu_context->cc_debug_info_offset <= offset) {
       
    85 
       
    86 	for (cu_context = dbg->de_cu_context;
       
    87 	     cu_context != NULL; cu_context = cu_context->cc_next) {
       
    88 
       
    89 	    if (offset >= cu_context->cc_debug_info_offset &&
       
    90 		offset < cu_context->cc_debug_info_offset +
       
    91 		cu_context->cc_length + cu_context->cc_length_size
       
    92 		+ cu_context->cc_extension_size) {
       
    93 
       
    94 		return (cu_context);
       
    95 	    }
       
    96 	}
       
    97     }
       
    98 
       
    99     for (cu_context = dbg->de_cu_context_list;
       
   100 	 cu_context != NULL; cu_context = cu_context->cc_next) {
       
   101 
       
   102 	if (offset >= cu_context->cc_debug_info_offset &&
       
   103 	    offset < cu_context->cc_debug_info_offset +
       
   104 	    cu_context->cc_length + cu_context->cc_length_size
       
   105 	    + cu_context->cc_extension_size) {
       
   106 
       
   107 	    return (cu_context);
       
   108 	}
       
   109     }
       
   110 
       
   111     return (NULL);
       
   112 }
       
   113 
       
   114 
       
   115 /*
       
   116     This routine checks the dwarf_offdie() list of 
       
   117     CU contexts for the right CU context.
       
   118 */
       
   119 static Dwarf_CU_Context
       
   120 _dwarf_find_offdie_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset)
       
   121 {
       
   122     Dwarf_CU_Context cu_context;
       
   123 
       
   124     for (cu_context = dbg->de_offdie_cu_context;
       
   125 	 cu_context != NULL; cu_context = cu_context->cc_next)
       
   126 
       
   127 	if (offset >= cu_context->cc_debug_info_offset &&
       
   128 	    offset < cu_context->cc_debug_info_offset +
       
   129 	    cu_context->cc_length + cu_context->cc_length_size
       
   130 	    + cu_context->cc_extension_size)
       
   131 
       
   132 	    return (cu_context);
       
   133 
       
   134     return (NULL);
       
   135 }
       
   136 
       
   137 
       
   138 /*
       
   139     This function is used to create a CU Context for
       
   140     a compilation-unit that begins at offset in 
       
   141     .debug_info.  The CU Context is attached to the
       
   142     list of CU Contexts for this dbg.  It is assumed
       
   143     that the CU at offset has not been read before,
       
   144     and so do not call this routine before making
       
   145     sure of this with _dwarf_find_CU_Context().
       
   146     Returns NULL on error.  As always, being an
       
   147     internal routine, assumes a good dbg.
       
   148 
       
   149     This function must always set a dwarf error code
       
   150     before returning NULL. Always.
       
   151 */
       
   152 static Dwarf_CU_Context
       
   153 _dwarf_make_CU_Context(Dwarf_Debug dbg,
       
   154 		       Dwarf_Off offset, Dwarf_Error * error)
       
   155 {
       
   156     Dwarf_CU_Context cu_context;
       
   157     Dwarf_Unsigned length;
       
   158     Dwarf_Signed abbrev_offset;
       
   159     Dwarf_Byte_Ptr cu_ptr;
       
   160     int local_extension_size = 0;
       
   161     int local_length_size;
       
   162 
       
   163     cu_context =
       
   164 	(Dwarf_CU_Context) _dwarf_get_alloc(dbg, DW_DLA_CU_CONTEXT, 1);
       
   165     if (cu_context == NULL) {
       
   166 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
       
   167 	return (NULL);
       
   168     }
       
   169     cu_context->cc_dbg = dbg;
       
   170 
       
   171     cu_ptr = (Dwarf_Byte_Ptr) (dbg->de_debug_info + offset);
       
   172 
       
   173     /* READ_AREA_LENGTH updates cu_ptr for consumed bytes */
       
   174     READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
       
   175 		     cu_ptr, local_length_size, local_extension_size);
       
   176     cu_context->cc_length_size = local_length_size;
       
   177     cu_context->cc_extension_size = local_extension_size;
       
   178 
       
   179 
       
   180     cu_context->cc_length = (Dwarf_Word) length;
       
   181 
       
   182     READ_UNALIGNED(dbg, cu_context->cc_version_stamp, Dwarf_Half,
       
   183 		   cu_ptr, sizeof(Dwarf_Half));
       
   184     cu_ptr += sizeof(Dwarf_Half);
       
   185 
       
   186     READ_UNALIGNED(dbg, abbrev_offset, Dwarf_Signed,
       
   187 		   cu_ptr, local_length_size);
       
   188     cu_ptr += local_length_size;
       
   189     cu_context->cc_abbrev_offset = (Dwarf_Sword) abbrev_offset;
       
   190 
       
   191     cu_context->cc_address_size = *(Dwarf_Small *) cu_ptr;
       
   192 
       
   193     if ((length < CU_VERSION_STAMP_SIZE + local_length_size +
       
   194 	 CU_ADDRESS_SIZE_SIZE) ||
       
   195 	(offset + length + local_length_size +
       
   196 	 local_extension_size > dbg->de_debug_info_size)) {
       
   197 
       
   198 	dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
       
   199 	_dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR);
       
   200 	return (NULL);
       
   201     }
       
   202 
       
   203     if (cu_context->cc_address_size != dbg->de_pointer_size) {
       
   204 	dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
       
   205 	_dwarf_error(dbg, error, DW_DLE_CU_ADDRESS_SIZE_BAD);
       
   206 	return (NULL);
       
   207     }
       
   208 
       
   209     if (cu_context->cc_version_stamp != CURRENT_VERSION_STAMP
       
   210         && cu_context->cc_version_stamp != CURRENT_VERSION_STAMP3
       
   211         && cu_context->cc_version_stamp != CURRENT_VERSION_STAMP4) {
       
   212 	dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
       
   213 	_dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
       
   214 	return (NULL);
       
   215     }
       
   216 
       
   217     if (abbrev_offset >= dbg->de_debug_abbrev_size) {
       
   218 	dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
       
   219 	_dwarf_error(dbg, error, DW_DLE_ABBREV_OFFSET_ERROR);
       
   220 	return (NULL);
       
   221     }
       
   222 
       
   223     cu_context->cc_abbrev_hash_table =
       
   224 	(Dwarf_Hash_Table) _dwarf_get_alloc(dbg, DW_DLA_HASH_TABLE, 1);
       
   225     if (cu_context->cc_abbrev_hash_table == NULL) {
       
   226 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
       
   227 	return (NULL);
       
   228     }
       
   229 
       
   230     cu_context->cc_debug_info_offset = (Dwarf_Word) offset;
       
   231     dbg->de_info_last_offset =
       
   232 	(Dwarf_Word) (offset + length +
       
   233 		      local_extension_size + local_length_size);
       
   234 
       
   235     if (dbg->de_cu_context_list == NULL) {
       
   236 	dbg->de_cu_context_list = cu_context;
       
   237 	dbg->de_cu_context_list_end = cu_context;
       
   238     } else {
       
   239 	dbg->de_cu_context_list_end->cc_next = cu_context;
       
   240 	dbg->de_cu_context_list_end = cu_context;
       
   241     }
       
   242 
       
   243     return (cu_context);
       
   244 }
       
   245 
       
   246 
       
   247 /*
       
   248     Returns offset of next compilation-unit thru next_cu_offset
       
   249 	pointer.
       
   250     It basically sequentially moves from one
       
   251     cu to the next.  The current cu is recorded
       
   252     internally by libdwarf.
       
   253 */
       
   254 int
       
   255 dwarf_next_cu_header(Dwarf_Debug dbg,
       
   256 		     Dwarf_Unsigned * cu_header_length,
       
   257 		     Dwarf_Half * version_stamp,
       
   258 		     Dwarf_Unsigned * abbrev_offset,
       
   259 		     Dwarf_Half * address_size,
       
   260 		     Dwarf_Unsigned * next_cu_offset,
       
   261 		     Dwarf_Error * error)
       
   262 {
       
   263     /* Offset for current and new CU. */
       
   264     Dwarf_Unsigned new_offset;
       
   265 
       
   266     /* CU Context for current CU. */
       
   267     Dwarf_CU_Context cu_context;
       
   268 
       
   269     /* ***** BEGIN CODE ***** */
       
   270 
       
   271     if (dbg == NULL) {
       
   272 	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
       
   273 	return (DW_DLV_ERROR);
       
   274     }
       
   275     /* 
       
   276        Get offset into .debug_info of next CU. If dbg has no context,
       
   277        this has to be the first one. */
       
   278     if (dbg->de_cu_context == NULL) {
       
   279 	new_offset = 0;
       
   280 	if (!dbg->de_debug_info) {
       
   281 	    int res = _dwarf_load_debug_info(dbg, error);
       
   282 
       
   283 	    if (res != DW_DLV_OK) {
       
   284 		return res;
       
   285 	    }
       
   286 	}
       
   287 
       
   288     } else {
       
   289 	new_offset = dbg->de_cu_context->cc_debug_info_offset +
       
   290 	    dbg->de_cu_context->cc_length +
       
   291 	    dbg->de_cu_context->cc_length_size +
       
   292 	    dbg->de_cu_context->cc_extension_size;
       
   293     }
       
   294 
       
   295     /* 
       
   296        Check that there is room in .debug_info beyond the new offset
       
   297        for at least a new cu header. If not, return 0 to indicate end
       
   298        of debug_info section, and reset de_cu_debug_info_offset to
       
   299        enable looping back through the cu's. */
       
   300     if ((new_offset + _dwarf_length_of_cu_header_simple(dbg)) >=
       
   301 	dbg->de_debug_info_size) {
       
   302 	dbg->de_cu_context = NULL;
       
   303 	return (DW_DLV_NO_ENTRY);
       
   304     }
       
   305 
       
   306     /* Check if this CU has been read before. */
       
   307     cu_context = _dwarf_find_CU_Context(dbg, new_offset);
       
   308 
       
   309     /* If not, make CU Context for it. */
       
   310     if (cu_context == NULL) {
       
   311 	cu_context = _dwarf_make_CU_Context(dbg, new_offset, error);
       
   312 	if (cu_context == NULL) {
       
   313 	    /* Error if CU Context could not be made. Since
       
   314 	       _dwarf_make_CU_Context has already registered an error
       
   315 	       we do not do that here: we let the lower error pass
       
   316 	       thru. */
       
   317 	    return (DW_DLV_ERROR);
       
   318 	}
       
   319     }
       
   320 
       
   321     dbg->de_cu_context = cu_context;
       
   322 
       
   323     if (cu_header_length != NULL)
       
   324 	*cu_header_length = cu_context->cc_length;
       
   325 
       
   326     if (version_stamp != NULL)
       
   327 	*version_stamp = cu_context->cc_version_stamp;
       
   328 
       
   329     if (abbrev_offset != NULL)
       
   330 	*abbrev_offset = cu_context->cc_abbrev_offset;
       
   331 
       
   332     if (address_size != NULL)
       
   333 	*address_size = cu_context->cc_address_size;
       
   334 
       
   335     new_offset = new_offset + cu_context->cc_length +
       
   336 	cu_context->cc_length_size + cu_context->cc_extension_size;
       
   337     *next_cu_offset = new_offset;
       
   338     return (DW_DLV_OK);
       
   339 }
       
   340 
       
   341 
       
   342 /* 
       
   343     This function does two slightly different things
       
   344     depending on the input flag want_AT_sibling.  If
       
   345     this flag is true, it checks if the input die has
       
   346     a DW_AT_sibling attribute.  If it does it returns
       
   347     a pointer to the start of the sibling die in the
       
   348     .debug_info section.  Otherwise it behaves the 
       
   349     same as the want_AT_sibling false case.
       
   350 
       
   351     If the want_AT_sibling flag is false, it returns
       
   352     a pointer to the immediately adjacent die in the 
       
   353     .debug_info section.
       
   354 
       
   355     Die_info_end points to the end of the .debug_info 
       
   356     portion for the cu the die belongs to.  It is used 
       
   357     to check that the search for the next die does not 
       
   358     cross the end of the current cu.  Cu_info_start points 
       
   359     to the start of the .debug_info portion for the 
       
   360     current cu, and is used to add to the offset for 
       
   361     DW_AT_sibling attributes.  Finally, has_die_child 
       
   362     is a pointer to a Dwarf_Bool that is set true if 
       
   363     the present die has children, false otherwise.  
       
   364     However, in case want_AT_child is true and the die 
       
   365     has a DW_AT_sibling attribute *has_die_child is set 
       
   366     false to indicate that the children are being skipped.
       
   367 
       
   368     die_info_end  points to the last byte+1 of the cu.
       
   369     
       
   370 */
       
   371 static Dwarf_Byte_Ptr
       
   372 _dwarf_next_die_info_ptr(Dwarf_Byte_Ptr die_info_ptr,
       
   373 			 Dwarf_CU_Context cu_context,
       
   374 			 Dwarf_Byte_Ptr die_info_end,
       
   375 			 Dwarf_Byte_Ptr cu_info_start,
       
   376 			 Dwarf_Bool want_AT_sibling,
       
   377 			 Dwarf_Bool * has_die_child)
       
   378 {
       
   379     Dwarf_Byte_Ptr info_ptr;
       
   380     Dwarf_Byte_Ptr abbrev_ptr;
       
   381     Dwarf_Word abbrev_code;
       
   382     Dwarf_Abbrev_List abbrev_list;
       
   383     Dwarf_Half attr;
       
   384     Dwarf_Half attr_form;
       
   385     Dwarf_Unsigned offset;
       
   386     Dwarf_Word leb128_length;
       
   387     Dwarf_Unsigned utmp;
       
   388     Dwarf_Debug dbg;
       
   389 
       
   390     info_ptr = die_info_ptr;
       
   391     DECODE_LEB128_UWORD(info_ptr, utmp);
       
   392     abbrev_code = (Dwarf_Word) utmp;
       
   393     if (abbrev_code == 0) {
       
   394 	return NULL;
       
   395     }
       
   396 
       
   397     abbrev_list = _dwarf_get_abbrev_for_code(cu_context, abbrev_code);
       
   398     if (abbrev_list == NULL) {
       
   399 	return (NULL);
       
   400     }
       
   401     dbg = cu_context->cc_dbg;
       
   402 
       
   403     *has_die_child = abbrev_list->ab_has_child;
       
   404 
       
   405     abbrev_ptr = abbrev_list->ab_abbrev_ptr;
       
   406     do {
       
   407 	Dwarf_Unsigned utmp2;
       
   408 
       
   409 	DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
       
   410 	attr = (Dwarf_Half) utmp2;
       
   411 	DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
       
   412 	attr_form = (Dwarf_Half) utmp2;
       
   413 	if (attr_form == DW_FORM_indirect) {
       
   414 	    Dwarf_Unsigned utmp6;
       
   415 
       
   416 	    /* READ_UNALIGNED does update info_ptr */
       
   417 	    DECODE_LEB128_UWORD(info_ptr, utmp6);
       
   418 	    attr_form = (Dwarf_Half) utmp6;
       
   419 
       
   420 	}
       
   421 
       
   422 	if (want_AT_sibling && attr == DW_AT_sibling) {
       
   423 	    switch (attr_form) {
       
   424 	    case DW_FORM_ref1:
       
   425 		offset = *(Dwarf_Small *) info_ptr;
       
   426 		break;
       
   427 	    case DW_FORM_ref2:
       
   428 		READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
       
   429 			       info_ptr, sizeof(Dwarf_Half));
       
   430 		break;
       
   431 	    case DW_FORM_ref4:
       
   432 		READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
       
   433 			       info_ptr, sizeof(Dwarf_ufixed));
       
   434 		break;
       
   435 	    case DW_FORM_ref8:
       
   436 		READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
       
   437 			       info_ptr, sizeof(Dwarf_Unsigned));
       
   438 		break;
       
   439 	    case DW_FORM_ref_udata:
       
   440 		offset =
       
   441 		    _dwarf_decode_u_leb128(info_ptr, &leb128_length);
       
   442 		break;
       
   443 	    default:
       
   444 		return (NULL);
       
   445 	    }
       
   446 
       
   447 	    /* Reset *has_die_child to indicate children skipped.  */
       
   448 	    *has_die_child = false;
       
   449 
       
   450 	    /* A value beyond die_info_end indicates an error. Exactly
       
   451 	       at die_info_end means 1-past-cu-end and simply means we
       
   452 	       are at the end, do not return NULL. Higher level code
       
   453 	       will detect that we are at the end. */
       
   454 	    if (cu_info_start + offset > die_info_end) {
       
   455 		/* Error case, bad DWARF. */
       
   456 		return (NULL);
       
   457 	    }
       
   458 	    /* At or before end-of-cu */
       
   459 	    return (cu_info_start + offset);
       
   460 	}
       
   461 
       
   462 	if (attr_form != 0) {
       
   463 	    info_ptr += _dwarf_get_size_of_val(cu_context->cc_dbg,
       
   464 					       attr_form, info_ptr,
       
   465 					       cu_context->
       
   466 					       cc_length_size);
       
   467 	    /* It is ok for info_ptr == die_info_end, as we will test
       
   468 	       later before using a too-large info_ptr */
       
   469 	    if (info_ptr > die_info_end) {
       
   470 		/* More than one-past-end indicates a bug somewhere,
       
   471 		   likely bad dwarf generation. */
       
   472 		return (NULL);
       
   473 	    }
       
   474 	}
       
   475     } while (attr != 0 || attr_form != 0);
       
   476 
       
   477     return (info_ptr);
       
   478 }
       
   479 
       
   480 
       
   481 /*
       
   482     Given a Dwarf_Debug dbg, and a Dwarf_Die die, it returns 
       
   483     a Dwarf_Die for the sibling of die.  In case die is NULL, 
       
   484     it returns (thru ptr) a Dwarf_Die for the first die in the current 
       
   485     cu in dbg.  Returns DW_DLV_ERROR on error.
       
   486 
       
   487     It is assumed that every sibling chain including those with 
       
   488     only one element is terminated with a NULL die, except a 
       
   489     chain with only a NULL die.
       
   490 
       
   491     The algorithm moves from one die to the adjacent one.  It 
       
   492     returns when the depth of children it sees equals the number 
       
   493     of sibling chain terminations.  A single count, child_depth 
       
   494     is used to track the depth of children and sibling terminations 
       
   495     encountered.  Child_depth is incremented when a die has the 
       
   496     Has-Child flag set unless the child happens to be a NULL die.  
       
   497     Child_depth is decremented when a die has Has-Child false, 
       
   498     and the adjacent die is NULL.  Algorithm returns when 
       
   499     child_depth is 0.
       
   500 
       
   501     **NOTE: Do not modify input die, since it is used at the end.
       
   502 */
       
   503 int
       
   504 dwarf_siblingof(Dwarf_Debug dbg,
       
   505 		Dwarf_Die die,
       
   506 		Dwarf_Die * caller_ret_die, Dwarf_Error * error)
       
   507 {
       
   508     Dwarf_Die ret_die;
       
   509     Dwarf_Byte_Ptr die_info_ptr;
       
   510     Dwarf_Byte_Ptr cu_info_start = 0;
       
   511 
       
   512     /* die_info_end points 1-past end of die (once set) */
       
   513     Dwarf_Byte_Ptr die_info_end = 0;
       
   514     Dwarf_Half abbrev_code;
       
   515     Dwarf_Unsigned utmp;
       
   516 
       
   517 
       
   518     if (dbg == NULL) {
       
   519 	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
       
   520 	return (DW_DLV_ERROR);
       
   521     }
       
   522 
       
   523     if (die == NULL) {
       
   524 	/* Find root die of cu */
       
   525 	/* die_info_end is untouched here, need not be set in this
       
   526 	   branch. */
       
   527 	Dwarf_Off off2;
       
   528 
       
   529 	/* If we've not loaded debug_info, de_cu_context will be NULL,
       
   530 	   so no need to laod */
       
   531 
       
   532 	if (dbg->de_cu_context == NULL) {
       
   533 	    _dwarf_error(dbg, error, DW_DLE_DBG_NO_CU_CONTEXT);
       
   534 	    return (DW_DLV_ERROR);
       
   535 	}
       
   536 
       
   537 	off2 = dbg->de_cu_context->cc_debug_info_offset;
       
   538 	die_info_ptr = dbg->de_debug_info +
       
   539 	    off2 + _dwarf_length_of_cu_header(dbg, off2);
       
   540     } else {
       
   541 	/* Find sibling die. */
       
   542 	Dwarf_Bool has_child = false;
       
   543 	Dwarf_Sword child_depth;
       
   544 
       
   545 	/* We cannot have a legal die unless debug_info was loaded, so
       
   546 	   no need to load debug_info here. */
       
   547 	CHECK_DIE(die, DW_DLV_ERROR);
       
   548 
       
   549 	die_info_ptr = die->di_debug_info_ptr;
       
   550 	if (*die_info_ptr == 0) {
       
   551 	    return (DW_DLV_NO_ENTRY);
       
   552 	}
       
   553 	cu_info_start = dbg->de_debug_info +
       
   554 	    die->di_cu_context->cc_debug_info_offset;
       
   555 	die_info_end = cu_info_start + die->di_cu_context->cc_length +
       
   556 	    die->di_cu_context->cc_length_size +
       
   557 	    die->di_cu_context->cc_extension_size;
       
   558 
       
   559 	if ((*die_info_ptr) == 0) {
       
   560 	    return (DW_DLV_NO_ENTRY);
       
   561 	}
       
   562 	child_depth = 0;
       
   563 	do {
       
   564 	    die_info_ptr = _dwarf_next_die_info_ptr(die_info_ptr,
       
   565 						    die->di_cu_context,
       
   566 						    die_info_end,
       
   567 						    cu_info_start, true,
       
   568 						    &has_child);
       
   569 	    if (die_info_ptr == NULL) {
       
   570 		_dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL);
       
   571 		return (DW_DLV_ERROR);
       
   572 	    }
       
   573 
       
   574             /* die_info_end is one past end. Do not read it!  
       
   575                A test for ``!= die_info_end''  would work as well,
       
   576                but perhaps < reads more like the meaning. */
       
   577             if(die_info_ptr < die_info_end) { 
       
   578 	        if ((*die_info_ptr) == 0 && has_child) {
       
   579                     die_info_ptr++;
       
   580                     has_child = false;
       
   581 	        }
       
   582 	    }
       
   583 
       
   584 	    /* die_info_ptr can be one-past-end. */
       
   585 	    if ((die_info_ptr == die_info_end) ||
       
   586 		((*die_info_ptr) == 0)) {
       
   587 		for (; child_depth > 0 && *die_info_ptr == 0;
       
   588 		     child_depth--, die_info_ptr++);
       
   589 	    } else {
       
   590 		child_depth = has_child ? child_depth + 1 : child_depth;
       
   591 	    }
       
   592 
       
   593 	} while (child_depth != 0);
       
   594     }
       
   595 
       
   596     /* die_info_ptr > die_info_end is really a bug (possibly in dwarf
       
   597        generation)(but we are past end, no more DIEs here), whereas
       
   598        die_info_ptr == die_info_end means 'one past end, no more DIEs
       
   599        here'. */
       
   600     if (die != NULL && die_info_ptr >= die_info_end) {
       
   601 	return (DW_DLV_NO_ENTRY);
       
   602     }
       
   603 
       
   604     if ((*die_info_ptr) == 0) {
       
   605 	return (DW_DLV_NO_ENTRY);
       
   606     }
       
   607 
       
   608     ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1);
       
   609     if (ret_die == NULL) {
       
   610 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
       
   611 	return (DW_DLV_ERROR);
       
   612     }
       
   613 
       
   614     ret_die->di_debug_info_ptr = die_info_ptr;
       
   615     ret_die->di_cu_context =
       
   616 	die == NULL ? dbg->de_cu_context : die->di_cu_context;
       
   617 
       
   618     DECODE_LEB128_UWORD(die_info_ptr, utmp);
       
   619     abbrev_code = (Dwarf_Half) utmp;
       
   620     if (abbrev_code == 0) {
       
   621 	/* Zero means a null DIE */
       
   622 	dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
       
   623 	return (DW_DLV_NO_ENTRY);
       
   624     }
       
   625     ret_die->di_abbrev_list =
       
   626 	_dwarf_get_abbrev_for_code(ret_die->di_cu_context, abbrev_code);
       
   627     if (ret_die->di_abbrev_list == NULL || (die == NULL &&
       
   628 					    ret_die->di_abbrev_list->
       
   629 					    ab_tag !=
       
   630 					    DW_TAG_compile_unit)) {
       
   631 	dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
       
   632 	_dwarf_error(dbg, error, DW_DLE_FIRST_DIE_NOT_CU);
       
   633 	return (DW_DLV_ERROR);
       
   634     }
       
   635 
       
   636     *caller_ret_die = ret_die;
       
   637     return (DW_DLV_OK);
       
   638 }
       
   639 
       
   640 
       
   641 int
       
   642 dwarf_child(Dwarf_Die die,
       
   643 	    Dwarf_Die * caller_ret_die, Dwarf_Error * error)
       
   644 {
       
   645     Dwarf_Byte_Ptr die_info_ptr = 0;
       
   646 
       
   647     /* die_info_end points one-past-end of die area. */
       
   648     Dwarf_Byte_Ptr die_info_end = 0;
       
   649     Dwarf_Die ret_die = 0;
       
   650     Dwarf_Bool has_die_child = 0;
       
   651     Dwarf_Debug dbg;
       
   652     Dwarf_Half abbrev_code = 0;
       
   653     Dwarf_Unsigned utmp = 0;
       
   654 
       
   655 
       
   656     CHECK_DIE(die, DW_DLV_ERROR);
       
   657     dbg = die->di_cu_context->cc_dbg;
       
   658     die_info_ptr = die->di_debug_info_ptr;
       
   659 
       
   660     /* NULL die has no child. */
       
   661     if ((*die_info_ptr) == 0)
       
   662 	return (DW_DLV_NO_ENTRY);
       
   663 
       
   664     die_info_end = dbg->de_debug_info +
       
   665 	die->di_cu_context->cc_debug_info_offset +
       
   666 	die->di_cu_context->cc_length +
       
   667 	die->di_cu_context->cc_length_size +
       
   668 	die->di_cu_context->cc_extension_size;
       
   669 
       
   670     die_info_ptr =
       
   671 	_dwarf_next_die_info_ptr(die_info_ptr, die->di_cu_context,
       
   672 				 die_info_end, NULL, false,
       
   673 				 &has_die_child);
       
   674     if (die_info_ptr == NULL) {
       
   675 	_dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL);
       
   676 	return (DW_DLV_ERROR);
       
   677     }
       
   678 
       
   679     if (!has_die_child)
       
   680 	return (DW_DLV_NO_ENTRY);
       
   681 
       
   682     ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1);
       
   683     if (ret_die == NULL) {
       
   684 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
       
   685 	return (DW_DLV_ERROR);
       
   686     }
       
   687     ret_die->di_debug_info_ptr = die_info_ptr;
       
   688     ret_die->di_cu_context = die->di_cu_context;
       
   689 
       
   690     DECODE_LEB128_UWORD(die_info_ptr, utmp);
       
   691     abbrev_code = (Dwarf_Half) utmp;
       
   692     if (abbrev_code == 0) {
       
   693 	/* We have arrived at a null DIE, at the end of a CU or the end 
       
   694 	   of a list of siblings. */
       
   695 	*caller_ret_die = 0;
       
   696 	dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
       
   697 	return DW_DLV_NO_ENTRY;
       
   698     }
       
   699     ret_die->di_abbrev_list =
       
   700 	_dwarf_get_abbrev_for_code(die->di_cu_context, abbrev_code);
       
   701     if (ret_die->di_abbrev_list == NULL) {
       
   702 	dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
       
   703 	_dwarf_error(dbg, error, DW_DLE_DIE_BAD);
       
   704 	return (DW_DLV_ERROR);
       
   705     }
       
   706 
       
   707     *caller_ret_die = ret_die;
       
   708     return (DW_DLV_OK);
       
   709 }
       
   710 
       
   711 /*
       
   712 	Given a die offset, this returns
       
   713 	a pointer to a DIE thru *new_die.
       
   714 	It is up to the caller to do a
       
   715 	dwarf_dealloc(dbg,*new_die,DW_DLE_DIE);
       
   716 */
       
   717 int
       
   718 dwarf_offdie(Dwarf_Debug dbg,
       
   719 	     Dwarf_Off offset, Dwarf_Die * new_die, Dwarf_Error * error)
       
   720 {
       
   721     Dwarf_CU_Context cu_context;
       
   722     Dwarf_Off new_cu_offset = 0;
       
   723     Dwarf_Die die = 0;
       
   724     Dwarf_Byte_Ptr info_ptr = 0;
       
   725     Dwarf_Half abbrev_code = 0;
       
   726     Dwarf_Unsigned utmp = 0;
       
   727 
       
   728     if (dbg == NULL) {
       
   729 	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
       
   730 	return (DW_DLV_ERROR);
       
   731     }
       
   732 
       
   733     cu_context = _dwarf_find_CU_Context(dbg, offset);
       
   734     if (cu_context == NULL)
       
   735 	cu_context = _dwarf_find_offdie_CU_Context(dbg, offset);
       
   736 
       
   737     if (cu_context == NULL) {
       
   738 	int res = _dwarf_load_debug_info(dbg, error);
       
   739 
       
   740 	if (res != DW_DLV_OK) {
       
   741 	    return res;
       
   742 	}
       
   743 
       
   744 	if (dbg->de_offdie_cu_context_end != NULL) {
       
   745 	    Dwarf_CU_Context lcu_context =
       
   746 		dbg->de_offdie_cu_context_end;
       
   747 	    new_cu_offset =
       
   748 		lcu_context->cc_debug_info_offset +
       
   749 		lcu_context->cc_length +
       
   750 		lcu_context->cc_length_size +
       
   751 		lcu_context->cc_extension_size;
       
   752 	}
       
   753 
       
   754 
       
   755 	do {
       
   756 	    if ((new_cu_offset +
       
   757 		 _dwarf_length_of_cu_header_simple(dbg)) >=
       
   758 		dbg->de_debug_info_size) {
       
   759 		_dwarf_error(dbg, error, DW_DLE_OFFSET_BAD);
       
   760 		return (DW_DLV_ERROR);
       
   761 	    }
       
   762 
       
   763 	    cu_context =
       
   764 		_dwarf_make_CU_Context(dbg, new_cu_offset, error);
       
   765 	    if (cu_context == NULL) {
       
   766 		/* Error if CU Context could not be made. Since
       
   767 		   _dwarf_make_CU_Context has already registered an
       
   768 		   error we do not do that here: we let the lower error
       
   769 		   pass thru. */
       
   770 
       
   771 		return (DW_DLV_ERROR);
       
   772 	    }
       
   773 
       
   774 	    if (dbg->de_offdie_cu_context == NULL) {
       
   775 		dbg->de_offdie_cu_context = cu_context;
       
   776 		dbg->de_offdie_cu_context_end = cu_context;
       
   777 	    } else {
       
   778 		dbg->de_offdie_cu_context_end->cc_next = cu_context;
       
   779 		dbg->de_offdie_cu_context_end = cu_context;
       
   780 	    }
       
   781 
       
   782 	    new_cu_offset = new_cu_offset + cu_context->cc_length +
       
   783 		cu_context->cc_length_size;
       
   784 
       
   785 	} while (offset >= new_cu_offset);
       
   786     }
       
   787 
       
   788     die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1);
       
   789     if (die == NULL) {
       
   790 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
       
   791 	return (DW_DLV_ERROR);
       
   792     }
       
   793     die->di_cu_context = cu_context;
       
   794 
       
   795     info_ptr = dbg->de_debug_info + offset;
       
   796     die->di_debug_info_ptr = info_ptr;
       
   797     DECODE_LEB128_UWORD(info_ptr, utmp);
       
   798     abbrev_code = (Dwarf_Half) utmp;
       
   799     if (abbrev_code == 0) {
       
   800 	/* we are at a null DIE (or there is a bug). */
       
   801 	*new_die = 0;
       
   802 	dwarf_dealloc(dbg, die, DW_DLA_DIE);
       
   803 	return DW_DLV_NO_ENTRY;
       
   804     }
       
   805 
       
   806     die->di_abbrev_list =
       
   807 	_dwarf_get_abbrev_for_code(cu_context, abbrev_code);
       
   808     if (die->di_abbrev_list == NULL) {
       
   809 	dwarf_dealloc(dbg, die, DW_DLA_DIE);
       
   810 	_dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_LIST_NULL);
       
   811 	return (DW_DLV_ERROR);
       
   812     }
       
   813 
       
   814     *new_die = die;
       
   815     return (DW_DLV_OK);
       
   816 }