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