1*7fd79137SRobert Mustacchi /* 2*7fd79137SRobert Mustacchi 3*7fd79137SRobert Mustacchi Copyright (C) 2000-2005 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 #include <stdio.h> 48*7fd79137SRobert Mustacchi #include "dwarf_global.h" 49*7fd79137SRobert Mustacchi 50*7fd79137SRobert Mustacchi 51*7fd79137SRobert Mustacchi #ifdef __sgi /* __sgi should only be defined for IRIX/MIPS. */ 52*7fd79137SRobert Mustacchi /* The 'fixup' here intended for IRIX targets only. 53*7fd79137SRobert Mustacchi With a 2+GB Elf64 IRIX executable (under 4GB in size), 54*7fd79137SRobert Mustacchi some DIE offsets wrongly 55*7fd79137SRobert Mustacchi got the 32bit upper bit sign extended. For the cu-header 56*7fd79137SRobert Mustacchi offset in the .debug_pubnames section and in the 57*7fd79137SRobert Mustacchi .debug_aranges section. 58*7fd79137SRobert Mustacchi the 'varp' here is a pointer to an offset into .debug_info. 59*7fd79137SRobert Mustacchi We fix up the offset here if it seems advisable.. 60*7fd79137SRobert Mustacchi 61*7fd79137SRobert Mustacchi As of June 2005 we have identified a series of mistakes 62*7fd79137SRobert Mustacchi in ldx64 that can cause this (64 bit values getting passed 63*7fd79137SRobert Mustacchi thru 32-bit signed knothole). 64*7fd79137SRobert Mustacchi */ 65*7fd79137SRobert Mustacchi void 66*7fd79137SRobert Mustacchi _dwarf_fix_up_offset_irix(Dwarf_Debug dbg, 67*7fd79137SRobert Mustacchi Dwarf_Unsigned * varp, char *caller_site_name) 68*7fd79137SRobert Mustacchi { 69*7fd79137SRobert Mustacchi 70*7fd79137SRobert Mustacchi Dwarf_Unsigned var = *varp; 71*7fd79137SRobert Mustacchi 72*7fd79137SRobert Mustacchi #define UPPER33 0xffffffff80000000LL 73*7fd79137SRobert Mustacchi #define LOWER32 0xffffffffLL 74*7fd79137SRobert Mustacchi /* Restrict the hack to the known case. Upper 32 bits erroneously 75*7fd79137SRobert Mustacchi sign extended from lower 32 upper bit. */ 76*7fd79137SRobert Mustacchi if ((var & UPPER33) == UPPER33) { 77*7fd79137SRobert Mustacchi var &= LOWER32; 78*7fd79137SRobert Mustacchi /* Apply the fix. Dreadful hack. */ 79*7fd79137SRobert Mustacchi *varp = var; 80*7fd79137SRobert Mustacchi } 81*7fd79137SRobert Mustacchi #undef UPPER33 82*7fd79137SRobert Mustacchi #undef LOWER32 83*7fd79137SRobert Mustacchi return; 84*7fd79137SRobert Mustacchi } 85*7fd79137SRobert Mustacchi #endif 86*7fd79137SRobert Mustacchi 87*7fd79137SRobert Mustacchi 88*7fd79137SRobert Mustacchi int 89*7fd79137SRobert Mustacchi dwarf_get_globals(Dwarf_Debug dbg, 90*7fd79137SRobert Mustacchi Dwarf_Global ** globals, 91*7fd79137SRobert Mustacchi Dwarf_Signed * return_count, Dwarf_Error * error) 92*7fd79137SRobert Mustacchi { 93*7fd79137SRobert Mustacchi int res = _dwarf_load_section(dbg, &dbg->de_debug_pubnames,error); 94*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 95*7fd79137SRobert Mustacchi return res; 96*7fd79137SRobert Mustacchi } 97*7fd79137SRobert Mustacchi 98*7fd79137SRobert Mustacchi return _dwarf_internal_get_pubnames_like_data(dbg, 99*7fd79137SRobert Mustacchi dbg->de_debug_pubnames.dss_data, 100*7fd79137SRobert Mustacchi dbg->de_debug_pubnames.dss_size, 101*7fd79137SRobert Mustacchi globals, 102*7fd79137SRobert Mustacchi return_count, 103*7fd79137SRobert Mustacchi error, 104*7fd79137SRobert Mustacchi DW_DLA_GLOBAL_CONTEXT, 105*7fd79137SRobert Mustacchi DW_DLA_GLOBAL, 106*7fd79137SRobert Mustacchi DW_DLE_PUBNAMES_LENGTH_BAD, 107*7fd79137SRobert Mustacchi DW_DLE_PUBNAMES_VERSION_ERROR); 108*7fd79137SRobert Mustacchi 109*7fd79137SRobert Mustacchi } 110*7fd79137SRobert Mustacchi 111*7fd79137SRobert Mustacchi /* Deallocating fully requires deallocating the list 112*7fd79137SRobert Mustacchi and all entries. But some internal data is 113*7fd79137SRobert Mustacchi not exposed, so we need a function with internal knowledge. 114*7fd79137SRobert Mustacchi */ 115*7fd79137SRobert Mustacchi 116*7fd79137SRobert Mustacchi void 117*7fd79137SRobert Mustacchi dwarf_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl, 118*7fd79137SRobert Mustacchi Dwarf_Signed count) 119*7fd79137SRobert Mustacchi { 120*7fd79137SRobert Mustacchi _dwarf_internal_globals_dealloc(dbg, dwgl, 121*7fd79137SRobert Mustacchi count, 122*7fd79137SRobert Mustacchi DW_DLA_GLOBAL_CONTEXT, 123*7fd79137SRobert Mustacchi DW_DLA_GLOBAL, DW_DLA_LIST); 124*7fd79137SRobert Mustacchi return; 125*7fd79137SRobert Mustacchi } 126*7fd79137SRobert Mustacchi 127*7fd79137SRobert Mustacchi void 128*7fd79137SRobert Mustacchi _dwarf_internal_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl, 129*7fd79137SRobert Mustacchi Dwarf_Signed count, 130*7fd79137SRobert Mustacchi int context_code, 131*7fd79137SRobert Mustacchi int global_code, int list_code) 132*7fd79137SRobert Mustacchi { 133*7fd79137SRobert Mustacchi Dwarf_Signed i; 134*7fd79137SRobert Mustacchi struct Dwarf_Global_Context_s *gcp = 0; 135*7fd79137SRobert Mustacchi struct Dwarf_Global_Context_s *lastgcp = 0; 136*7fd79137SRobert Mustacchi 137*7fd79137SRobert Mustacchi for (i = 0; i < count; i++) { 138*7fd79137SRobert Mustacchi Dwarf_Global dgb = dwgl[i]; 139*7fd79137SRobert Mustacchi 140*7fd79137SRobert Mustacchi gcp = dgb->gl_context; 141*7fd79137SRobert Mustacchi 142*7fd79137SRobert Mustacchi if (lastgcp != gcp) { 143*7fd79137SRobert Mustacchi lastgcp = gcp; 144*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, gcp, context_code); 145*7fd79137SRobert Mustacchi } 146*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, dgb, global_code); 147*7fd79137SRobert Mustacchi } 148*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, dwgl, list_code); 149*7fd79137SRobert Mustacchi return; 150*7fd79137SRobert Mustacchi } 151*7fd79137SRobert Mustacchi 152*7fd79137SRobert Mustacchi 153*7fd79137SRobert Mustacchi /* Sweeps the complete section. 154*7fd79137SRobert Mustacchi */ 155*7fd79137SRobert Mustacchi int 156*7fd79137SRobert Mustacchi _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg, 157*7fd79137SRobert Mustacchi Dwarf_Small * section_data_ptr, 158*7fd79137SRobert Mustacchi Dwarf_Unsigned section_length, 159*7fd79137SRobert Mustacchi Dwarf_Global ** globals, 160*7fd79137SRobert Mustacchi Dwarf_Signed * return_count, 161*7fd79137SRobert Mustacchi Dwarf_Error * error, 162*7fd79137SRobert Mustacchi int context_code, 163*7fd79137SRobert Mustacchi int global_code, 164*7fd79137SRobert Mustacchi int length_err_num, 165*7fd79137SRobert Mustacchi int version_err_num) 166*7fd79137SRobert Mustacchi { 167*7fd79137SRobert Mustacchi 168*7fd79137SRobert Mustacchi 169*7fd79137SRobert Mustacchi Dwarf_Small *pubnames_like_ptr = 0; 170*7fd79137SRobert Mustacchi 171*7fd79137SRobert Mustacchi 172*7fd79137SRobert Mustacchi 173*7fd79137SRobert Mustacchi /* Points to the context for the current set of global names, and 174*7fd79137SRobert Mustacchi contains information to identify the compilation-unit that the 175*7fd79137SRobert Mustacchi set refers to. */ 176*7fd79137SRobert Mustacchi Dwarf_Global_Context pubnames_context = 0; 177*7fd79137SRobert Mustacchi 178*7fd79137SRobert Mustacchi Dwarf_Half version = 0; 179*7fd79137SRobert Mustacchi 180*7fd79137SRobert Mustacchi /* 181*7fd79137SRobert Mustacchi Offset from the start of compilation-unit for the current 182*7fd79137SRobert Mustacchi global. */ 183*7fd79137SRobert Mustacchi Dwarf_Off die_offset_in_cu = 0; 184*7fd79137SRobert Mustacchi 185*7fd79137SRobert Mustacchi Dwarf_Unsigned global_count = 0; 186*7fd79137SRobert Mustacchi 187*7fd79137SRobert Mustacchi /* Points to the current global read. */ 188*7fd79137SRobert Mustacchi Dwarf_Global global = 0; 189*7fd79137SRobert Mustacchi 190*7fd79137SRobert Mustacchi /* Used to chain the Dwarf_Global_s structs for creating contiguous 191*7fd79137SRobert Mustacchi list of pointers to the structs. */ 192*7fd79137SRobert Mustacchi Dwarf_Chain curr_chain = 0; 193*7fd79137SRobert Mustacchi Dwarf_Chain prev_chain = 0; 194*7fd79137SRobert Mustacchi Dwarf_Chain head_chain = 0; 195*7fd79137SRobert Mustacchi 196*7fd79137SRobert Mustacchi /* Points to contiguous block of Dwarf_Global's to be returned. */ 197*7fd79137SRobert Mustacchi Dwarf_Global *ret_globals = 0; 198*7fd79137SRobert Mustacchi 199*7fd79137SRobert Mustacchi /* Temporary counter. */ 200*7fd79137SRobert Mustacchi Dwarf_Unsigned i = 0; 201*7fd79137SRobert Mustacchi 202*7fd79137SRobert Mustacchi 203*7fd79137SRobert Mustacchi 204*7fd79137SRobert Mustacchi 205*7fd79137SRobert Mustacchi if (dbg == NULL) { 206*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 207*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 208*7fd79137SRobert Mustacchi } 209*7fd79137SRobert Mustacchi /* We will eventually need the .debug_info data. Load it now. */ 210*7fd79137SRobert Mustacchi if (!dbg->de_debug_info.dss_data) { 211*7fd79137SRobert Mustacchi int res = _dwarf_load_debug_info(dbg, error); 212*7fd79137SRobert Mustacchi 213*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 214*7fd79137SRobert Mustacchi return res; 215*7fd79137SRobert Mustacchi } 216*7fd79137SRobert Mustacchi } 217*7fd79137SRobert Mustacchi 218*7fd79137SRobert Mustacchi if (section_data_ptr == NULL) { 219*7fd79137SRobert Mustacchi return (DW_DLV_NO_ENTRY); 220*7fd79137SRobert Mustacchi } 221*7fd79137SRobert Mustacchi 222*7fd79137SRobert Mustacchi pubnames_like_ptr = section_data_ptr; 223*7fd79137SRobert Mustacchi do { 224*7fd79137SRobert Mustacchi Dwarf_Unsigned length = 0; 225*7fd79137SRobert Mustacchi int local_extension_size = 0; 226*7fd79137SRobert Mustacchi int local_length_size = 0; 227*7fd79137SRobert Mustacchi 228*7fd79137SRobert Mustacchi /* Some compilers emit padding at the end of each cu's area. 229*7fd79137SRobert Mustacchi pubnames_ptr_past_end_cu records the true area end for this 230*7fd79137SRobert Mustacchi cu's data. Essentially the length in the header and the 0 231*7fd79137SRobert Mustacchi terminator of the data are redundant information. The 232*7fd79137SRobert Mustacchi dwarf2/3 spec does not mention what to do if the length is 233*7fd79137SRobert Mustacchi past the 0 terminator. So we take any bytes left after the 0 234*7fd79137SRobert Mustacchi as padding and ignore them. */ 235*7fd79137SRobert Mustacchi Dwarf_Small *pubnames_ptr_past_end_cu = 0; 236*7fd79137SRobert Mustacchi 237*7fd79137SRobert Mustacchi 238*7fd79137SRobert Mustacchi pubnames_context = (Dwarf_Global_Context) 239*7fd79137SRobert Mustacchi _dwarf_get_alloc(dbg, context_code, 1); 240*7fd79137SRobert Mustacchi if (pubnames_context == NULL) { 241*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 242*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 243*7fd79137SRobert Mustacchi } 244*7fd79137SRobert Mustacchi /* READ_AREA_LENGTH updates pubnames_like_ptr for consumed 245*7fd79137SRobert Mustacchi bytes. */ 246*7fd79137SRobert Mustacchi READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, 247*7fd79137SRobert Mustacchi pubnames_like_ptr, local_length_size, 248*7fd79137SRobert Mustacchi local_extension_size); 249*7fd79137SRobert Mustacchi pubnames_context->pu_length_size = local_length_size; 250*7fd79137SRobert Mustacchi pubnames_context->pu_extension_size = local_extension_size; 251*7fd79137SRobert Mustacchi pubnames_context->pu_dbg = dbg; 252*7fd79137SRobert Mustacchi 253*7fd79137SRobert Mustacchi pubnames_ptr_past_end_cu = pubnames_like_ptr + length; 254*7fd79137SRobert Mustacchi 255*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, version, Dwarf_Half, 256*7fd79137SRobert Mustacchi pubnames_like_ptr, sizeof(Dwarf_Half)); 257*7fd79137SRobert Mustacchi pubnames_like_ptr += sizeof(Dwarf_Half); 258*7fd79137SRobert Mustacchi if (version != CURRENT_VERSION_STAMP) { 259*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, version_err_num); 260*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 261*7fd79137SRobert Mustacchi } 262*7fd79137SRobert Mustacchi 263*7fd79137SRobert Mustacchi /* Offset of CU header in debug section. */ 264*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, pubnames_context->pu_offset_of_cu_header, 265*7fd79137SRobert Mustacchi Dwarf_Off, pubnames_like_ptr, 266*7fd79137SRobert Mustacchi pubnames_context->pu_length_size); 267*7fd79137SRobert Mustacchi pubnames_like_ptr += pubnames_context->pu_length_size; 268*7fd79137SRobert Mustacchi 269*7fd79137SRobert Mustacchi FIX_UP_OFFSET_IRIX_BUG(dbg, 270*7fd79137SRobert Mustacchi pubnames_context->pu_offset_of_cu_header, 271*7fd79137SRobert Mustacchi "pubnames cu header offset"); 272*7fd79137SRobert Mustacchi 273*7fd79137SRobert Mustacchi 274*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, pubnames_context->pu_info_length, 275*7fd79137SRobert Mustacchi Dwarf_Unsigned, pubnames_like_ptr, 276*7fd79137SRobert Mustacchi pubnames_context->pu_length_size); 277*7fd79137SRobert Mustacchi pubnames_like_ptr += pubnames_context->pu_length_size; 278*7fd79137SRobert Mustacchi 279*7fd79137SRobert Mustacchi if (pubnames_like_ptr > (section_data_ptr + section_length)) { 280*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, length_err_num); 281*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 282*7fd79137SRobert Mustacchi } 283*7fd79137SRobert Mustacchi 284*7fd79137SRobert Mustacchi /* Read initial offset (of DIE within CU) of a pubname, final 285*7fd79137SRobert Mustacchi entry is not a pair, just a zero offset. */ 286*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, die_offset_in_cu, Dwarf_Off, 287*7fd79137SRobert Mustacchi pubnames_like_ptr, 288*7fd79137SRobert Mustacchi pubnames_context->pu_length_size); 289*7fd79137SRobert Mustacchi pubnames_like_ptr += pubnames_context->pu_length_size; 290*7fd79137SRobert Mustacchi FIX_UP_OFFSET_IRIX_BUG(dbg, 291*7fd79137SRobert Mustacchi die_offset_in_cu, "offset of die in cu"); 292*7fd79137SRobert Mustacchi 293*7fd79137SRobert Mustacchi /* Loop thru pairs. DIE off with CU followed by string. */ 294*7fd79137SRobert Mustacchi while (die_offset_in_cu != 0) { 295*7fd79137SRobert Mustacchi 296*7fd79137SRobert Mustacchi /* Already read offset, pubnames_like_ptr now points to the 297*7fd79137SRobert Mustacchi string. */ 298*7fd79137SRobert Mustacchi global = 299*7fd79137SRobert Mustacchi (Dwarf_Global) _dwarf_get_alloc(dbg, global_code, 1); 300*7fd79137SRobert Mustacchi if (global == NULL) { 301*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 302*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 303*7fd79137SRobert Mustacchi } 304*7fd79137SRobert Mustacchi global_count++; 305*7fd79137SRobert Mustacchi 306*7fd79137SRobert Mustacchi global->gl_context = pubnames_context; 307*7fd79137SRobert Mustacchi 308*7fd79137SRobert Mustacchi global->gl_named_die_offset_within_cu = die_offset_in_cu; 309*7fd79137SRobert Mustacchi 310*7fd79137SRobert Mustacchi global->gl_name = pubnames_like_ptr; 311*7fd79137SRobert Mustacchi 312*7fd79137SRobert Mustacchi pubnames_like_ptr = pubnames_like_ptr + 313*7fd79137SRobert Mustacchi strlen((char *) pubnames_like_ptr) + 1; 314*7fd79137SRobert Mustacchi 315*7fd79137SRobert Mustacchi 316*7fd79137SRobert Mustacchi /* finish off current entry chain */ 317*7fd79137SRobert Mustacchi curr_chain = 318*7fd79137SRobert Mustacchi (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); 319*7fd79137SRobert Mustacchi if (curr_chain == NULL) { 320*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 321*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 322*7fd79137SRobert Mustacchi } 323*7fd79137SRobert Mustacchi 324*7fd79137SRobert Mustacchi /* Put current global on singly_linked list. */ 325*7fd79137SRobert Mustacchi curr_chain->ch_item = (Dwarf_Global) global; 326*7fd79137SRobert Mustacchi 327*7fd79137SRobert Mustacchi if (head_chain == NULL) 328*7fd79137SRobert Mustacchi head_chain = prev_chain = curr_chain; 329*7fd79137SRobert Mustacchi else { 330*7fd79137SRobert Mustacchi prev_chain->ch_next = curr_chain; 331*7fd79137SRobert Mustacchi prev_chain = curr_chain; 332*7fd79137SRobert Mustacchi } 333*7fd79137SRobert Mustacchi 334*7fd79137SRobert Mustacchi /* read offset for the *next* entry */ 335*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, die_offset_in_cu, Dwarf_Off, 336*7fd79137SRobert Mustacchi pubnames_like_ptr, 337*7fd79137SRobert Mustacchi pubnames_context->pu_length_size); 338*7fd79137SRobert Mustacchi 339*7fd79137SRobert Mustacchi pubnames_like_ptr += pubnames_context->pu_length_size; 340*7fd79137SRobert Mustacchi FIX_UP_OFFSET_IRIX_BUG(dbg, 341*7fd79137SRobert Mustacchi die_offset_in_cu, 342*7fd79137SRobert Mustacchi "offset of next die in cu"); 343*7fd79137SRobert Mustacchi 344*7fd79137SRobert Mustacchi if (pubnames_like_ptr > (section_data_ptr + section_length)) { 345*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, length_err_num); 346*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 347*7fd79137SRobert Mustacchi } 348*7fd79137SRobert Mustacchi } 349*7fd79137SRobert Mustacchi /* ASSERT: die_offset_in_cu == 0 */ 350*7fd79137SRobert Mustacchi if (pubnames_like_ptr > pubnames_ptr_past_end_cu) { 351*7fd79137SRobert Mustacchi /* This is some kind of error. This simply cannot happen. 352*7fd79137SRobert Mustacchi The encoding is wrong or the length in the header for 353*7fd79137SRobert Mustacchi this cu's contribution is wrong. */ 354*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, length_err_num); 355*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 356*7fd79137SRobert Mustacchi } 357*7fd79137SRobert Mustacchi /* If there is some kind of padding at the end of the section, 358*7fd79137SRobert Mustacchi as emitted by some compilers, skip over that padding and 359*7fd79137SRobert Mustacchi simply ignore the bytes thus passed-over. With most 360*7fd79137SRobert Mustacchi compilers, pubnames_like_ptr == pubnames_ptr_past_end_cu at 361*7fd79137SRobert Mustacchi this point */ 362*7fd79137SRobert Mustacchi pubnames_like_ptr = pubnames_ptr_past_end_cu; 363*7fd79137SRobert Mustacchi 364*7fd79137SRobert Mustacchi } while (pubnames_like_ptr < (section_data_ptr + section_length)); 365*7fd79137SRobert Mustacchi 366*7fd79137SRobert Mustacchi /* Points to contiguous block of Dwarf_Global's. */ 367*7fd79137SRobert Mustacchi ret_globals = (Dwarf_Global *) 368*7fd79137SRobert Mustacchi _dwarf_get_alloc(dbg, DW_DLA_LIST, global_count); 369*7fd79137SRobert Mustacchi if (ret_globals == NULL) { 370*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 371*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 372*7fd79137SRobert Mustacchi } 373*7fd79137SRobert Mustacchi 374*7fd79137SRobert Mustacchi /* 375*7fd79137SRobert Mustacchi Store pointers to Dwarf_Global_s structs in contiguous block, 376*7fd79137SRobert Mustacchi and deallocate the chain. */ 377*7fd79137SRobert Mustacchi curr_chain = head_chain; 378*7fd79137SRobert Mustacchi for (i = 0; i < global_count; i++) { 379*7fd79137SRobert Mustacchi *(ret_globals + i) = curr_chain->ch_item; 380*7fd79137SRobert Mustacchi prev_chain = curr_chain; 381*7fd79137SRobert Mustacchi curr_chain = curr_chain->ch_next; 382*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); 383*7fd79137SRobert Mustacchi } 384*7fd79137SRobert Mustacchi 385*7fd79137SRobert Mustacchi *globals = ret_globals; 386*7fd79137SRobert Mustacchi *return_count = (Dwarf_Signed) global_count; 387*7fd79137SRobert Mustacchi return DW_DLV_OK; 388*7fd79137SRobert Mustacchi } 389*7fd79137SRobert Mustacchi 390*7fd79137SRobert Mustacchi 391*7fd79137SRobert Mustacchi /* 392*7fd79137SRobert Mustacchi Given a pubnames entry (or other like section entry) 393*7fd79137SRobert Mustacchi return thru the ret_name pointer 394*7fd79137SRobert Mustacchi a pointer to the string which is the entry name. 395*7fd79137SRobert Mustacchi 396*7fd79137SRobert Mustacchi */ 397*7fd79137SRobert Mustacchi int 398*7fd79137SRobert Mustacchi dwarf_globname(Dwarf_Global glob, char **ret_name, Dwarf_Error * error) 399*7fd79137SRobert Mustacchi { 400*7fd79137SRobert Mustacchi if (glob == NULL) { 401*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); 402*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 403*7fd79137SRobert Mustacchi } 404*7fd79137SRobert Mustacchi 405*7fd79137SRobert Mustacchi *ret_name = (char *) (glob->gl_name); 406*7fd79137SRobert Mustacchi return DW_DLV_OK; 407*7fd79137SRobert Mustacchi } 408*7fd79137SRobert Mustacchi 409*7fd79137SRobert Mustacchi 410*7fd79137SRobert Mustacchi /* 411*7fd79137SRobert Mustacchi Given a pubnames entry (or other like section entry) 412*7fd79137SRobert Mustacchi return thru the ret_off pointer the 413*7fd79137SRobert Mustacchi global offset of the DIE for this entry. 414*7fd79137SRobert Mustacchi The global offset is the offset within the .debug_info 415*7fd79137SRobert Mustacchi section as a whole. 416*7fd79137SRobert Mustacchi */ 417*7fd79137SRobert Mustacchi int 418*7fd79137SRobert Mustacchi dwarf_global_die_offset(Dwarf_Global global, 419*7fd79137SRobert Mustacchi Dwarf_Off * ret_off, Dwarf_Error * error) 420*7fd79137SRobert Mustacchi { 421*7fd79137SRobert Mustacchi if (global == NULL) { 422*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); 423*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 424*7fd79137SRobert Mustacchi } 425*7fd79137SRobert Mustacchi 426*7fd79137SRobert Mustacchi if (global->gl_context == NULL) { 427*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); 428*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 429*7fd79137SRobert Mustacchi } 430*7fd79137SRobert Mustacchi 431*7fd79137SRobert Mustacchi *ret_off = (global->gl_named_die_offset_within_cu + 432*7fd79137SRobert Mustacchi global->gl_context->pu_offset_of_cu_header); 433*7fd79137SRobert Mustacchi return DW_DLV_OK; 434*7fd79137SRobert Mustacchi } 435*7fd79137SRobert Mustacchi 436*7fd79137SRobert Mustacchi /* 437*7fd79137SRobert Mustacchi Given a pubnames entry (or other like section entry) 438*7fd79137SRobert Mustacchi return thru the ret_off pointer the 439*7fd79137SRobert Mustacchi offset of the compilation unit header of the 440*7fd79137SRobert Mustacchi compilation unit the global is part of. 441*7fd79137SRobert Mustacchi 442*7fd79137SRobert Mustacchi In early versions of this, the value returned was 443*7fd79137SRobert Mustacchi the offset of the compilation unit die, and 444*7fd79137SRobert Mustacchi other cu-local die offsets were faked so adding this to 445*7fd79137SRobert Mustacchi such a cu-local offset got a true section offset. 446*7fd79137SRobert Mustacchi Now things do as they say (adding *cu_header_offset to 447*7fd79137SRobert Mustacchi a cu-local offset gets the section offset). 448*7fd79137SRobert Mustacchi 449*7fd79137SRobert Mustacchi */ 450*7fd79137SRobert Mustacchi int 451*7fd79137SRobert Mustacchi dwarf_global_cu_offset(Dwarf_Global global, 452*7fd79137SRobert Mustacchi Dwarf_Off * cu_header_offset, 453*7fd79137SRobert Mustacchi Dwarf_Error * error) 454*7fd79137SRobert Mustacchi { 455*7fd79137SRobert Mustacchi Dwarf_Global_Context con = 0; 456*7fd79137SRobert Mustacchi 457*7fd79137SRobert Mustacchi if (global == NULL) { 458*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); 459*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 460*7fd79137SRobert Mustacchi } 461*7fd79137SRobert Mustacchi 462*7fd79137SRobert Mustacchi con = global->gl_context; 463*7fd79137SRobert Mustacchi 464*7fd79137SRobert Mustacchi if (con == NULL) { 465*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); 466*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 467*7fd79137SRobert Mustacchi } 468*7fd79137SRobert Mustacchi 469*7fd79137SRobert Mustacchi /* In early libdwarf, this incorrectly returned the offset of the 470*7fd79137SRobert Mustacchi CU DIE. Now correctly returns the header offset. */ 471*7fd79137SRobert Mustacchi *cu_header_offset = con->pu_offset_of_cu_header; 472*7fd79137SRobert Mustacchi 473*7fd79137SRobert Mustacchi return DW_DLV_OK; 474*7fd79137SRobert Mustacchi } 475*7fd79137SRobert Mustacchi 476*7fd79137SRobert Mustacchi /* 477*7fd79137SRobert Mustacchi Give back the pubnames entry (or any other like section) 478*7fd79137SRobert Mustacchi name, symbol DIE offset, and the cu-DIE offset. 479*7fd79137SRobert Mustacchi 480*7fd79137SRobert Mustacchi Various errors are possible. 481*7fd79137SRobert Mustacchi 482*7fd79137SRobert Mustacchi The string pointer returned thru ret_name is not 483*7fd79137SRobert Mustacchi dwarf_get_alloc()ed, so no dwarf_dealloc() 484*7fd79137SRobert Mustacchi DW_DLA_STRING should be applied to it. 485*7fd79137SRobert Mustacchi 486*7fd79137SRobert Mustacchi */ 487*7fd79137SRobert Mustacchi int 488*7fd79137SRobert Mustacchi dwarf_global_name_offsets(Dwarf_Global global, 489*7fd79137SRobert Mustacchi char **ret_name, 490*7fd79137SRobert Mustacchi Dwarf_Off * die_offset, 491*7fd79137SRobert Mustacchi Dwarf_Off * cu_die_offset, 492*7fd79137SRobert Mustacchi Dwarf_Error * error) 493*7fd79137SRobert Mustacchi { 494*7fd79137SRobert Mustacchi Dwarf_Global_Context con = 0; 495*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0; 496*7fd79137SRobert Mustacchi Dwarf_Off off = 0; 497*7fd79137SRobert Mustacchi 498*7fd79137SRobert Mustacchi if (global == NULL) { 499*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); 500*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 501*7fd79137SRobert Mustacchi } 502*7fd79137SRobert Mustacchi 503*7fd79137SRobert Mustacchi con = global->gl_context; 504*7fd79137SRobert Mustacchi 505*7fd79137SRobert Mustacchi if (con == NULL) { 506*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); 507*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 508*7fd79137SRobert Mustacchi } 509*7fd79137SRobert Mustacchi 510*7fd79137SRobert Mustacchi off = con->pu_offset_of_cu_header; 511*7fd79137SRobert Mustacchi /* The offset had better not be too close to the end. If it is, 512*7fd79137SRobert Mustacchi _dwarf_length_of_cu_header() will step off the end and therefore 513*7fd79137SRobert Mustacchi must not be used. 10 is a meaningless heuristic, but no CU 514*7fd79137SRobert Mustacchi header is that small so it is safe. An erroneous offset is due 515*7fd79137SRobert Mustacchi to a bug in the tool chain. A bug like this has been seen on 516*7fd79137SRobert Mustacchi IRIX with MIPSpro 7.3.1.3 and an executable > 2GB in size and 517*7fd79137SRobert Mustacchi with 2 million pubnames entries. */ 518*7fd79137SRobert Mustacchi #define MIN_CU_HDR_SIZE 10 519*7fd79137SRobert Mustacchi dbg = con->pu_dbg; 520*7fd79137SRobert Mustacchi if (dbg == NULL) { 521*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 522*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 523*7fd79137SRobert Mustacchi } 524*7fd79137SRobert Mustacchi if (dbg->de_debug_info.dss_size && 525*7fd79137SRobert Mustacchi ((off + MIN_CU_HDR_SIZE) >= dbg->de_debug_info.dss_size)) { 526*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_OFFSET_BAD); 527*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 528*7fd79137SRobert Mustacchi } 529*7fd79137SRobert Mustacchi #undef MIN_CU_HDR_SIZE 530*7fd79137SRobert Mustacchi if (die_offset != NULL) { 531*7fd79137SRobert Mustacchi *die_offset = global->gl_named_die_offset_within_cu + off; 532*7fd79137SRobert Mustacchi } 533*7fd79137SRobert Mustacchi 534*7fd79137SRobert Mustacchi *ret_name = (char *) global->gl_name; 535*7fd79137SRobert Mustacchi 536*7fd79137SRobert Mustacchi if (cu_die_offset != NULL) { 537*7fd79137SRobert Mustacchi int res = _dwarf_load_debug_info(dbg, error); 538*7fd79137SRobert Mustacchi 539*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 540*7fd79137SRobert Mustacchi return res; 541*7fd79137SRobert Mustacchi } 542*7fd79137SRobert Mustacchi /* The offset had better not be too close to the end. If it is, 543*7fd79137SRobert Mustacchi _dwarf_length_of_cu_header() will step off the end and 544*7fd79137SRobert Mustacchi therefore must not be used. 10 is a meaningless heuristic, 545*7fd79137SRobert Mustacchi but no CU header is that small so it is safe. */ 546*7fd79137SRobert Mustacchi if ((off + 10) >= dbg->de_debug_info.dss_size) { 547*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_OFFSET_BAD); 548*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 549*7fd79137SRobert Mustacchi } 550*7fd79137SRobert Mustacchi *cu_die_offset = off + _dwarf_length_of_cu_header(dbg, off); 551*7fd79137SRobert Mustacchi } 552*7fd79137SRobert Mustacchi 553*7fd79137SRobert Mustacchi 554*7fd79137SRobert Mustacchi return DW_DLV_OK; 555*7fd79137SRobert Mustacchi } 556*7fd79137SRobert Mustacchi 557*7fd79137SRobert Mustacchi /* 558*7fd79137SRobert Mustacchi We have the offset to a CU header. 559*7fd79137SRobert Mustacchi Return thru outFileOffset the offset of the CU DIE. 560*7fd79137SRobert Mustacchi 561*7fd79137SRobert Mustacchi New June, 2001. 562*7fd79137SRobert Mustacchi Used by SGI debuggers. 563*7fd79137SRobert Mustacchi No error is possible. 564*7fd79137SRobert Mustacchi 565*7fd79137SRobert Mustacchi See also dwarf_CU_dieoffset_given_die(). 566*7fd79137SRobert Mustacchi */ 567*7fd79137SRobert Mustacchi 568*7fd79137SRobert Mustacchi /* ARGSUSED */ 569*7fd79137SRobert Mustacchi int 570*7fd79137SRobert Mustacchi dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg, 571*7fd79137SRobert Mustacchi Dwarf_Off in_cu_header_offset, 572*7fd79137SRobert Mustacchi Dwarf_Off * out_cu_die_offset, 573*7fd79137SRobert Mustacchi Dwarf_Error * err) 574*7fd79137SRobert Mustacchi { 575*7fd79137SRobert Mustacchi Dwarf_Off len = 576*7fd79137SRobert Mustacchi _dwarf_length_of_cu_header(dbg, in_cu_header_offset); 577*7fd79137SRobert Mustacchi 578*7fd79137SRobert Mustacchi Dwarf_Off newoff = in_cu_header_offset + len; 579*7fd79137SRobert Mustacchi 580*7fd79137SRobert Mustacchi *out_cu_die_offset = newoff; 581*7fd79137SRobert Mustacchi return DW_DLV_OK; 582*7fd79137SRobert Mustacchi } 583*7fd79137SRobert Mustacchi /* dwarf_CU_dieoffset_given_die returns 584*7fd79137SRobert Mustacchi the global debug_info section offset of the CU die 585*7fd79137SRobert Mustacchi that is the CU containing the given (passed-in) die. 586*7fd79137SRobert Mustacchi This information makes it possible for a consumer to 587*7fd79137SRobert Mustacchi find and print context information for any die. 588*7fd79137SRobert Mustacchi 589*7fd79137SRobert Mustacchi Use dwarf_offdie() passing in the offset this returns 590*7fd79137SRobert Mustacchi to get a die pointer to the CU die. 591*7fd79137SRobert Mustacchi */ 592*7fd79137SRobert Mustacchi int 593*7fd79137SRobert Mustacchi dwarf_CU_dieoffset_given_die(Dwarf_Die die, 594*7fd79137SRobert Mustacchi Dwarf_Off* return_offset, 595*7fd79137SRobert Mustacchi Dwarf_Error* error) 596*7fd79137SRobert Mustacchi { 597*7fd79137SRobert Mustacchi Dwarf_Off dieoff = 0; 598*7fd79137SRobert Mustacchi Dwarf_CU_Context cucontext = 0; 599*7fd79137SRobert Mustacchi 600*7fd79137SRobert Mustacchi CHECK_DIE(die, DW_DLV_ERROR); 601*7fd79137SRobert Mustacchi cucontext = die->di_cu_context; 602*7fd79137SRobert Mustacchi dieoff = cucontext->cc_debug_info_offset; 603*7fd79137SRobert Mustacchi /* The following call cannot fail, so no error check. */ 604*7fd79137SRobert Mustacchi dwarf_get_cu_die_offset_given_cu_header_offset( 605*7fd79137SRobert Mustacchi cucontext->cc_dbg, dieoff, return_offset,error); 606*7fd79137SRobert Mustacchi return DW_DLV_OK; 607*7fd79137SRobert Mustacchi } 608