1*7fd79137SRobert Mustacchi /* 2*7fd79137SRobert Mustacchi 3*7fd79137SRobert Mustacchi Copyright (C) 2000-2004 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 46*7fd79137SRobert Mustacchi 47*7fd79137SRobert Mustacchi #include "config.h" 48*7fd79137SRobert Mustacchi #include "dwarf_incl.h" 49*7fd79137SRobert Mustacchi #include <stdio.h> 50*7fd79137SRobert Mustacchi #include "dwarf_arange.h" 51*7fd79137SRobert Mustacchi #include "dwarf_global.h" /* for _dwarf_fixup_* */ 52*7fd79137SRobert Mustacchi 53*7fd79137SRobert Mustacchi 54*7fd79137SRobert Mustacchi /* Common code for two user-visible routines to share. 55*7fd79137SRobert Mustacchi Errors here result in memory leaks, but errors here 56*7fd79137SRobert Mustacchi are serious (making aranges unusable) so we assume 57*7fd79137SRobert Mustacchi callers will not repeat the error often or mind the leaks. 58*7fd79137SRobert Mustacchi */ 59*7fd79137SRobert Mustacchi static int 60*7fd79137SRobert Mustacchi dwarf_get_aranges_list(Dwarf_Debug dbg, 61*7fd79137SRobert Mustacchi Dwarf_Chain * chain_out, 62*7fd79137SRobert Mustacchi Dwarf_Signed * chain_count_out, 63*7fd79137SRobert Mustacchi Dwarf_Error * error) 64*7fd79137SRobert Mustacchi { 65*7fd79137SRobert Mustacchi /* Sweeps through the arange. */ 66*7fd79137SRobert Mustacchi Dwarf_Small *arange_ptr = 0; 67*7fd79137SRobert Mustacchi Dwarf_Small *arange_ptr_start = 0; 68*7fd79137SRobert Mustacchi 69*7fd79137SRobert Mustacchi /* Start of arange header. Used for rounding offset of arange_ptr 70*7fd79137SRobert Mustacchi to twice the tuple size. Libdwarf requirement. */ 71*7fd79137SRobert Mustacchi Dwarf_Small *header_ptr = 0; 72*7fd79137SRobert Mustacchi 73*7fd79137SRobert Mustacchi /* Version of .debug_aranges header. */ 74*7fd79137SRobert Mustacchi Dwarf_Half version = 0; 75*7fd79137SRobert Mustacchi 76*7fd79137SRobert Mustacchi /* Offset of current set of aranges into .debug_info. */ 77*7fd79137SRobert Mustacchi Dwarf_Off info_offset = 0; 78*7fd79137SRobert Mustacchi 79*7fd79137SRobert Mustacchi /* Size in bytes of addresses in target. */ 80*7fd79137SRobert Mustacchi Dwarf_Small address_size = 0; 81*7fd79137SRobert Mustacchi 82*7fd79137SRobert Mustacchi /* Size in bytes of segment offsets in target. */ 83*7fd79137SRobert Mustacchi Dwarf_Small segment_size = 0; 84*7fd79137SRobert Mustacchi 85*7fd79137SRobert Mustacchi /* Count of total number of aranges. */ 86*7fd79137SRobert Mustacchi Dwarf_Unsigned arange_count = 0; 87*7fd79137SRobert Mustacchi 88*7fd79137SRobert Mustacchi Dwarf_Arange arange = 0; 89*7fd79137SRobert Mustacchi 90*7fd79137SRobert Mustacchi /* Used to chain Dwarf_Aranges structs. */ 91*7fd79137SRobert Mustacchi Dwarf_Chain curr_chain = NULL; 92*7fd79137SRobert Mustacchi Dwarf_Chain prev_chain = NULL; 93*7fd79137SRobert Mustacchi Dwarf_Chain head_chain = NULL; 94*7fd79137SRobert Mustacchi 95*7fd79137SRobert Mustacchi arange_ptr = dbg->de_debug_aranges.dss_data; 96*7fd79137SRobert Mustacchi arange_ptr_start = arange_ptr; 97*7fd79137SRobert Mustacchi do { 98*7fd79137SRobert Mustacchi /* Length of current set of aranges. */ 99*7fd79137SRobert Mustacchi Dwarf_Unsigned length = 0; 100*7fd79137SRobert Mustacchi Dwarf_Small remainder = 0; 101*7fd79137SRobert Mustacchi Dwarf_Small *arange_ptr_past_end = 0; 102*7fd79137SRobert Mustacchi Dwarf_Unsigned range_entry_size = 0; 103*7fd79137SRobert Mustacchi 104*7fd79137SRobert Mustacchi int local_length_size; 105*7fd79137SRobert Mustacchi 106*7fd79137SRobert Mustacchi /*REFERENCED*/ /* Not used in this instance of the macro */ 107*7fd79137SRobert Mustacchi int local_extension_size = 0; 108*7fd79137SRobert Mustacchi 109*7fd79137SRobert Mustacchi header_ptr = arange_ptr; 110*7fd79137SRobert Mustacchi 111*7fd79137SRobert Mustacchi /* READ_AREA_LENGTH updates arange_ptr for consumed bytes */ 112*7fd79137SRobert Mustacchi READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, 113*7fd79137SRobert Mustacchi arange_ptr, local_length_size, 114*7fd79137SRobert Mustacchi local_extension_size); 115*7fd79137SRobert Mustacchi arange_ptr_past_end = arange_ptr + length; 116*7fd79137SRobert Mustacchi 117*7fd79137SRobert Mustacchi 118*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, version, Dwarf_Half, 119*7fd79137SRobert Mustacchi arange_ptr, sizeof(Dwarf_Half)); 120*7fd79137SRobert Mustacchi arange_ptr += sizeof(Dwarf_Half); 121*7fd79137SRobert Mustacchi length = length - sizeof(Dwarf_Half); 122*7fd79137SRobert Mustacchi if (version != CURRENT_VERSION_STAMP) { 123*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); 124*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 125*7fd79137SRobert Mustacchi } 126*7fd79137SRobert Mustacchi 127*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, info_offset, Dwarf_Off, 128*7fd79137SRobert Mustacchi arange_ptr, local_length_size); 129*7fd79137SRobert Mustacchi arange_ptr += local_length_size; 130*7fd79137SRobert Mustacchi length = length - local_length_size; 131*7fd79137SRobert Mustacchi if (info_offset >= dbg->de_debug_info.dss_size) { 132*7fd79137SRobert Mustacchi FIX_UP_OFFSET_IRIX_BUG(dbg, info_offset, 133*7fd79137SRobert Mustacchi "arange info offset.a"); 134*7fd79137SRobert Mustacchi if (info_offset >= dbg->de_debug_info.dss_size) { 135*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD); 136*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 137*7fd79137SRobert Mustacchi } 138*7fd79137SRobert Mustacchi } 139*7fd79137SRobert Mustacchi 140*7fd79137SRobert Mustacchi address_size = *(Dwarf_Small *) arange_ptr; 141*7fd79137SRobert Mustacchi /* It is not an error if the sizes differ. 142*7fd79137SRobert Mustacchi Unusual, but not an error. */ 143*7fd79137SRobert Mustacchi arange_ptr = arange_ptr + sizeof(Dwarf_Small); 144*7fd79137SRobert Mustacchi length = length - sizeof(Dwarf_Small); 145*7fd79137SRobert Mustacchi 146*7fd79137SRobert Mustacchi segment_size = *(Dwarf_Small *) arange_ptr; 147*7fd79137SRobert Mustacchi arange_ptr = arange_ptr + sizeof(Dwarf_Small); 148*7fd79137SRobert Mustacchi length = length - sizeof(Dwarf_Small); 149*7fd79137SRobert Mustacchi if (segment_size != 0) { 150*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD); 151*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 152*7fd79137SRobert Mustacchi } 153*7fd79137SRobert Mustacchi 154*7fd79137SRobert Mustacchi range_entry_size = 2*address_size + segment_size; 155*7fd79137SRobert Mustacchi /* Round arange_ptr offset to next multiple of address_size. */ 156*7fd79137SRobert Mustacchi remainder = (Dwarf_Unsigned) (arange_ptr - header_ptr) % 157*7fd79137SRobert Mustacchi (range_entry_size); 158*7fd79137SRobert Mustacchi if (remainder != 0) { 159*7fd79137SRobert Mustacchi arange_ptr = arange_ptr + (2 * address_size) - remainder; 160*7fd79137SRobert Mustacchi length = length - ((2 * address_size) - remainder); 161*7fd79137SRobert Mustacchi } 162*7fd79137SRobert Mustacchi do { 163*7fd79137SRobert Mustacchi Dwarf_Addr range_address = 0; 164*7fd79137SRobert Mustacchi Dwarf_Unsigned segment_selector = 0; 165*7fd79137SRobert Mustacchi Dwarf_Unsigned range_length = 0; 166*7fd79137SRobert Mustacchi /* For segmented address spaces, the first field to 167*7fd79137SRobert Mustacchi read is a segment selector (new in DWARF4) */ 168*7fd79137SRobert Mustacchi if(version == 4 && segment_size != 0) { 169*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, segment_selector, Dwarf_Unsigned, 170*7fd79137SRobert Mustacchi arange_ptr, segment_size); 171*7fd79137SRobert Mustacchi arange_ptr += address_size; 172*7fd79137SRobert Mustacchi length = length - address_size; 173*7fd79137SRobert Mustacchi } 174*7fd79137SRobert Mustacchi 175*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, range_address, Dwarf_Addr, 176*7fd79137SRobert Mustacchi arange_ptr, address_size); 177*7fd79137SRobert Mustacchi arange_ptr += address_size; 178*7fd79137SRobert Mustacchi length = length - address_size; 179*7fd79137SRobert Mustacchi 180*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, range_length, Dwarf_Unsigned, 181*7fd79137SRobert Mustacchi arange_ptr, address_size); 182*7fd79137SRobert Mustacchi arange_ptr += address_size; 183*7fd79137SRobert Mustacchi length = length - address_size; 184*7fd79137SRobert Mustacchi 185*7fd79137SRobert Mustacchi { /* We used to suppress all-zero entries, but 186*7fd79137SRobert Mustacchi now we return all aranges entries so we show 187*7fd79137SRobert Mustacchi the entire content. March 31, 2010. */ 188*7fd79137SRobert Mustacchi 189*7fd79137SRobert Mustacchi arange = (Dwarf_Arange) 190*7fd79137SRobert Mustacchi _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1); 191*7fd79137SRobert Mustacchi if (arange == NULL) { 192*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 193*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 194*7fd79137SRobert Mustacchi } 195*7fd79137SRobert Mustacchi 196*7fd79137SRobert Mustacchi arange->ar_segment_selector = segment_selector; 197*7fd79137SRobert Mustacchi arange->ar_segment_selector_size = segment_size; 198*7fd79137SRobert Mustacchi arange->ar_address = range_address; 199*7fd79137SRobert Mustacchi arange->ar_length = range_length; 200*7fd79137SRobert Mustacchi arange->ar_info_offset = info_offset; 201*7fd79137SRobert Mustacchi arange->ar_dbg = dbg; 202*7fd79137SRobert Mustacchi arange_count++; 203*7fd79137SRobert Mustacchi 204*7fd79137SRobert Mustacchi curr_chain = (Dwarf_Chain) 205*7fd79137SRobert Mustacchi _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); 206*7fd79137SRobert Mustacchi if (curr_chain == NULL) { 207*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 208*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 209*7fd79137SRobert Mustacchi } 210*7fd79137SRobert Mustacchi 211*7fd79137SRobert Mustacchi curr_chain->ch_item = arange; 212*7fd79137SRobert Mustacchi if (head_chain == NULL) 213*7fd79137SRobert Mustacchi head_chain = prev_chain = curr_chain; 214*7fd79137SRobert Mustacchi else { 215*7fd79137SRobert Mustacchi prev_chain->ch_next = curr_chain; 216*7fd79137SRobert Mustacchi prev_chain = curr_chain; 217*7fd79137SRobert Mustacchi } 218*7fd79137SRobert Mustacchi } 219*7fd79137SRobert Mustacchi /* The current set of ranges is terminated by 220*7fd79137SRobert Mustacchi range_address 0 and range_length 0, but that 221*7fd79137SRobert Mustacchi does not necessarily terminate the ranges for this CU! 222*7fd79137SRobert Mustacchi There can be multiple sets in that DWARF 223*7fd79137SRobert Mustacchi does not explicitly forbid multiple sets. 224*7fd79137SRobert Mustacchi DWARF2,3,4 section 7.20 225*7fd79137SRobert Mustacchi We stop short to avoid overrun of the end of the CU. 226*7fd79137SRobert Mustacchi */ 227*7fd79137SRobert Mustacchi 228*7fd79137SRobert Mustacchi } while (arange_ptr_past_end >= (arange_ptr + range_entry_size)); 229*7fd79137SRobert Mustacchi 230*7fd79137SRobert Mustacchi /* A compiler could emit some padding bytes here. dwarf2/3 231*7fd79137SRobert Mustacchi (dwarf4 sec 7.20) does not clearly make extra padding 232*7fd79137SRobert Mustacchi bytes illegal. */ 233*7fd79137SRobert Mustacchi if (arange_ptr_past_end < arange_ptr) { 234*7fd79137SRobert Mustacchi char buf[200]; 235*7fd79137SRobert Mustacchi Dwarf_Unsigned pad_count = arange_ptr - arange_ptr_past_end; 236*7fd79137SRobert Mustacchi Dwarf_Unsigned offset = arange_ptr - arange_ptr_start; 237*7fd79137SRobert Mustacchi snprintf(buf,sizeof(buf),"DW_DLE_ARANGE_LENGTH_BAD." 238*7fd79137SRobert Mustacchi " 0x%" DW_PR_DUx 239*7fd79137SRobert Mustacchi " pad bytes at offset 0x%" DW_PR_DUx 240*7fd79137SRobert Mustacchi " in .debug_aranges", 241*7fd79137SRobert Mustacchi pad_count, offset); 242*7fd79137SRobert Mustacchi dwarf_insert_harmless_error(dbg,buf); 243*7fd79137SRobert Mustacchi } 244*7fd79137SRobert Mustacchi /* For most compilers, arange_ptr == arange_ptr_past_end at 245*7fd79137SRobert Mustacchi this point. But not if there were padding bytes */ 246*7fd79137SRobert Mustacchi arange_ptr = arange_ptr_past_end; 247*7fd79137SRobert Mustacchi } while (arange_ptr < 248*7fd79137SRobert Mustacchi dbg->de_debug_aranges.dss_data + dbg->de_debug_aranges.dss_size); 249*7fd79137SRobert Mustacchi 250*7fd79137SRobert Mustacchi if (arange_ptr != 251*7fd79137SRobert Mustacchi dbg->de_debug_aranges.dss_data + dbg->de_debug_aranges.dss_size) { 252*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ARANGE_DECODE_ERROR); 253*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 254*7fd79137SRobert Mustacchi } 255*7fd79137SRobert Mustacchi *chain_out = head_chain; 256*7fd79137SRobert Mustacchi *chain_count_out = arange_count; 257*7fd79137SRobert Mustacchi return DW_DLV_OK; 258*7fd79137SRobert Mustacchi } 259*7fd79137SRobert Mustacchi 260*7fd79137SRobert Mustacchi /* 261*7fd79137SRobert Mustacchi This function returns the count of the number of 262*7fd79137SRobert Mustacchi aranges in the .debug_aranges section. It sets 263*7fd79137SRobert Mustacchi aranges to point to a block of Dwarf_Arange's 264*7fd79137SRobert Mustacchi describing the arange's. It returns DW_DLV_ERROR 265*7fd79137SRobert Mustacchi on error. 266*7fd79137SRobert Mustacchi 267*7fd79137SRobert Mustacchi Must be identical in most aspects to 268*7fd79137SRobert Mustacchi dwarf_get_aranges_addr_offsets! 269*7fd79137SRobert Mustacchi 270*7fd79137SRobert Mustacchi */ 271*7fd79137SRobert Mustacchi int 272*7fd79137SRobert Mustacchi dwarf_get_aranges(Dwarf_Debug dbg, 273*7fd79137SRobert Mustacchi Dwarf_Arange ** aranges, 274*7fd79137SRobert Mustacchi Dwarf_Signed * returned_count, Dwarf_Error * error) 275*7fd79137SRobert Mustacchi { 276*7fd79137SRobert Mustacchi /* Count of total number of aranges. */ 277*7fd79137SRobert Mustacchi Dwarf_Signed arange_count = 0; 278*7fd79137SRobert Mustacchi 279*7fd79137SRobert Mustacchi Dwarf_Arange *arange_block = 0; 280*7fd79137SRobert Mustacchi 281*7fd79137SRobert Mustacchi /* Used to chain Dwarf_Aranges structs. */ 282*7fd79137SRobert Mustacchi Dwarf_Chain curr_chain = NULL; 283*7fd79137SRobert Mustacchi Dwarf_Chain prev_chain = NULL; 284*7fd79137SRobert Mustacchi Dwarf_Chain head_chain = NULL; 285*7fd79137SRobert Mustacchi Dwarf_Unsigned i = 0; 286*7fd79137SRobert Mustacchi int res = DW_DLV_ERROR; 287*7fd79137SRobert Mustacchi 288*7fd79137SRobert Mustacchi /* ***** BEGIN CODE ***** */ 289*7fd79137SRobert Mustacchi 290*7fd79137SRobert Mustacchi if (dbg == NULL) { 291*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 292*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 293*7fd79137SRobert Mustacchi } 294*7fd79137SRobert Mustacchi 295*7fd79137SRobert Mustacchi res = _dwarf_load_section(dbg, &dbg->de_debug_aranges, error); 296*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 297*7fd79137SRobert Mustacchi return res; 298*7fd79137SRobert Mustacchi } 299*7fd79137SRobert Mustacchi 300*7fd79137SRobert Mustacchi res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error); 301*7fd79137SRobert Mustacchi if(res != DW_DLV_OK) { 302*7fd79137SRobert Mustacchi return res; 303*7fd79137SRobert Mustacchi } 304*7fd79137SRobert Mustacchi 305*7fd79137SRobert Mustacchi arange_block = (Dwarf_Arange *) 306*7fd79137SRobert Mustacchi _dwarf_get_alloc(dbg, DW_DLA_LIST, arange_count); 307*7fd79137SRobert Mustacchi if (arange_block == NULL) { 308*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 309*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 310*7fd79137SRobert Mustacchi } 311*7fd79137SRobert Mustacchi 312*7fd79137SRobert Mustacchi curr_chain = head_chain; 313*7fd79137SRobert Mustacchi for (i = 0; i < arange_count; i++) { 314*7fd79137SRobert Mustacchi *(arange_block + i) = curr_chain->ch_item; 315*7fd79137SRobert Mustacchi prev_chain = curr_chain; 316*7fd79137SRobert Mustacchi curr_chain = curr_chain->ch_next; 317*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); 318*7fd79137SRobert Mustacchi } 319*7fd79137SRobert Mustacchi 320*7fd79137SRobert Mustacchi *aranges = arange_block; 321*7fd79137SRobert Mustacchi *returned_count = (arange_count); 322*7fd79137SRobert Mustacchi return DW_DLV_OK; 323*7fd79137SRobert Mustacchi } 324*7fd79137SRobert Mustacchi 325*7fd79137SRobert Mustacchi /* 326*7fd79137SRobert Mustacchi This function returns DW_DLV_OK if it succeeds 327*7fd79137SRobert Mustacchi and DW_DLV_ERR or DW_DLV_OK otherwise. 328*7fd79137SRobert Mustacchi count is set to the number of addresses in the 329*7fd79137SRobert Mustacchi .debug_aranges section. 330*7fd79137SRobert Mustacchi For each address, the corresponding element in 331*7fd79137SRobert Mustacchi an array is set to the address itself(aranges) and 332*7fd79137SRobert Mustacchi the section offset (offsets). 333*7fd79137SRobert Mustacchi Must be identical in most aspects to 334*7fd79137SRobert Mustacchi dwarf_get_aranges! 335*7fd79137SRobert Mustacchi */ 336*7fd79137SRobert Mustacchi int 337*7fd79137SRobert Mustacchi _dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg, 338*7fd79137SRobert Mustacchi Dwarf_Addr ** addrs, 339*7fd79137SRobert Mustacchi Dwarf_Off ** offsets, 340*7fd79137SRobert Mustacchi Dwarf_Signed * count, 341*7fd79137SRobert Mustacchi Dwarf_Error * error) 342*7fd79137SRobert Mustacchi { 343*7fd79137SRobert Mustacchi Dwarf_Unsigned i = 0; 344*7fd79137SRobert Mustacchi 345*7fd79137SRobert Mustacchi /* Used to chain Dwarf_Aranges structs. */ 346*7fd79137SRobert Mustacchi Dwarf_Chain curr_chain = NULL; 347*7fd79137SRobert Mustacchi Dwarf_Chain prev_chain = NULL; 348*7fd79137SRobert Mustacchi Dwarf_Chain head_chain = NULL; 349*7fd79137SRobert Mustacchi 350*7fd79137SRobert Mustacchi Dwarf_Signed arange_count = 0; 351*7fd79137SRobert Mustacchi Dwarf_Addr *arange_addrs = 0; 352*7fd79137SRobert Mustacchi Dwarf_Off *arange_offsets = 0; 353*7fd79137SRobert Mustacchi 354*7fd79137SRobert Mustacchi int res = DW_DLV_ERROR; 355*7fd79137SRobert Mustacchi 356*7fd79137SRobert Mustacchi /* ***** BEGIN CODE ***** */ 357*7fd79137SRobert Mustacchi 358*7fd79137SRobert Mustacchi if (error != NULL) 359*7fd79137SRobert Mustacchi *error = NULL; 360*7fd79137SRobert Mustacchi 361*7fd79137SRobert Mustacchi if (dbg == NULL) { 362*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 363*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 364*7fd79137SRobert Mustacchi } 365*7fd79137SRobert Mustacchi 366*7fd79137SRobert Mustacchi res = _dwarf_load_section(dbg, &dbg->de_debug_aranges,error); 367*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 368*7fd79137SRobert Mustacchi return res; 369*7fd79137SRobert Mustacchi } 370*7fd79137SRobert Mustacchi 371*7fd79137SRobert Mustacchi res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error); 372*7fd79137SRobert Mustacchi if(res != DW_DLV_OK) { 373*7fd79137SRobert Mustacchi return res; 374*7fd79137SRobert Mustacchi } 375*7fd79137SRobert Mustacchi 376*7fd79137SRobert Mustacchi arange_addrs = (Dwarf_Addr *) 377*7fd79137SRobert Mustacchi _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count); 378*7fd79137SRobert Mustacchi if (arange_addrs == NULL) { 379*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 380*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 381*7fd79137SRobert Mustacchi } 382*7fd79137SRobert Mustacchi arange_offsets = (Dwarf_Off *) 383*7fd79137SRobert Mustacchi _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count); 384*7fd79137SRobert Mustacchi if (arange_offsets == NULL) { 385*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 386*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 387*7fd79137SRobert Mustacchi } 388*7fd79137SRobert Mustacchi 389*7fd79137SRobert Mustacchi curr_chain = head_chain; 390*7fd79137SRobert Mustacchi for (i = 0; i < arange_count; i++) { 391*7fd79137SRobert Mustacchi Dwarf_Arange ar = curr_chain->ch_item; 392*7fd79137SRobert Mustacchi 393*7fd79137SRobert Mustacchi arange_addrs[i] = ar->ar_address; 394*7fd79137SRobert Mustacchi arange_offsets[i] = ar->ar_info_offset; 395*7fd79137SRobert Mustacchi prev_chain = curr_chain; 396*7fd79137SRobert Mustacchi curr_chain = curr_chain->ch_next; 397*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, ar, DW_DLA_ARANGE); 398*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); 399*7fd79137SRobert Mustacchi } 400*7fd79137SRobert Mustacchi *count = arange_count; 401*7fd79137SRobert Mustacchi *offsets = arange_offsets; 402*7fd79137SRobert Mustacchi *addrs = arange_addrs; 403*7fd79137SRobert Mustacchi return (DW_DLV_OK); 404*7fd79137SRobert Mustacchi } 405*7fd79137SRobert Mustacchi 406*7fd79137SRobert Mustacchi 407*7fd79137SRobert Mustacchi /* 408*7fd79137SRobert Mustacchi This function takes a pointer to a block 409*7fd79137SRobert Mustacchi of Dwarf_Arange's, and a count of the 410*7fd79137SRobert Mustacchi length of the block. It checks if the 411*7fd79137SRobert Mustacchi given address is within the range of an 412*7fd79137SRobert Mustacchi address range in the block. If yes, it 413*7fd79137SRobert Mustacchi returns the appropriate Dwarf_Arange. 414*7fd79137SRobert Mustacchi Otherwise, it returns DW_DLV_ERROR. 415*7fd79137SRobert Mustacchi */ 416*7fd79137SRobert Mustacchi int 417*7fd79137SRobert Mustacchi dwarf_get_arange(Dwarf_Arange * aranges, 418*7fd79137SRobert Mustacchi Dwarf_Unsigned arange_count, 419*7fd79137SRobert Mustacchi Dwarf_Addr address, 420*7fd79137SRobert Mustacchi Dwarf_Arange * returned_arange, Dwarf_Error * error) 421*7fd79137SRobert Mustacchi { 422*7fd79137SRobert Mustacchi Dwarf_Arange curr_arange = 0; 423*7fd79137SRobert Mustacchi Dwarf_Unsigned i = 0; 424*7fd79137SRobert Mustacchi 425*7fd79137SRobert Mustacchi if (aranges == NULL) { 426*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ARANGES_NULL); 427*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 428*7fd79137SRobert Mustacchi } 429*7fd79137SRobert Mustacchi for (i = 0; i < arange_count; i++) { 430*7fd79137SRobert Mustacchi curr_arange = *(aranges + i); 431*7fd79137SRobert Mustacchi if (address >= curr_arange->ar_address && 432*7fd79137SRobert Mustacchi address < 433*7fd79137SRobert Mustacchi curr_arange->ar_address + curr_arange->ar_length) { 434*7fd79137SRobert Mustacchi *returned_arange = curr_arange; 435*7fd79137SRobert Mustacchi return (DW_DLV_OK); 436*7fd79137SRobert Mustacchi } 437*7fd79137SRobert Mustacchi } 438*7fd79137SRobert Mustacchi 439*7fd79137SRobert Mustacchi return (DW_DLV_NO_ENTRY); 440*7fd79137SRobert Mustacchi } 441*7fd79137SRobert Mustacchi 442*7fd79137SRobert Mustacchi 443*7fd79137SRobert Mustacchi /* 444*7fd79137SRobert Mustacchi This function takes an Dwarf_Arange, 445*7fd79137SRobert Mustacchi and returns the offset of the first 446*7fd79137SRobert Mustacchi die in the compilation-unit that the 447*7fd79137SRobert Mustacchi arange belongs to. Returns DW_DLV_ERROR 448*7fd79137SRobert Mustacchi on error. 449*7fd79137SRobert Mustacchi */ 450*7fd79137SRobert Mustacchi int 451*7fd79137SRobert Mustacchi dwarf_get_cu_die_offset(Dwarf_Arange arange, 452*7fd79137SRobert Mustacchi Dwarf_Off * returned_offset, 453*7fd79137SRobert Mustacchi Dwarf_Error * error) 454*7fd79137SRobert Mustacchi { 455*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0; 456*7fd79137SRobert Mustacchi Dwarf_Off offset = 0; 457*7fd79137SRobert Mustacchi 458*7fd79137SRobert Mustacchi if (arange == NULL) { 459*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); 460*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 461*7fd79137SRobert Mustacchi } 462*7fd79137SRobert Mustacchi dbg = arange->ar_dbg; 463*7fd79137SRobert Mustacchi offset = arange->ar_info_offset; 464*7fd79137SRobert Mustacchi if (!dbg->de_debug_info.dss_data) { 465*7fd79137SRobert Mustacchi int res = _dwarf_load_debug_info(dbg, error); 466*7fd79137SRobert Mustacchi 467*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 468*7fd79137SRobert Mustacchi return res; 469*7fd79137SRobert Mustacchi } 470*7fd79137SRobert Mustacchi } 471*7fd79137SRobert Mustacchi *returned_offset = offset + _dwarf_length_of_cu_header(dbg, offset); 472*7fd79137SRobert Mustacchi return DW_DLV_OK; 473*7fd79137SRobert Mustacchi } 474*7fd79137SRobert Mustacchi 475*7fd79137SRobert Mustacchi /* 476*7fd79137SRobert Mustacchi This function takes an Dwarf_Arange, 477*7fd79137SRobert Mustacchi and returns the offset of the CU header 478*7fd79137SRobert Mustacchi in the compilation-unit that the 479*7fd79137SRobert Mustacchi arange belongs to. Returns DW_DLV_ERROR 480*7fd79137SRobert Mustacchi on error. 481*7fd79137SRobert Mustacchi Ensures .debug_info loaded so 482*7fd79137SRobert Mustacchi the cu_offset is meaningful. 483*7fd79137SRobert Mustacchi */ 484*7fd79137SRobert Mustacchi int 485*7fd79137SRobert Mustacchi dwarf_get_arange_cu_header_offset(Dwarf_Arange arange, 486*7fd79137SRobert Mustacchi Dwarf_Off * cu_header_offset_returned, 487*7fd79137SRobert Mustacchi Dwarf_Error * error) 488*7fd79137SRobert Mustacchi { 489*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0; 490*7fd79137SRobert Mustacchi if (arange == NULL) { 491*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); 492*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 493*7fd79137SRobert Mustacchi } 494*7fd79137SRobert Mustacchi dbg = arange->ar_dbg; 495*7fd79137SRobert Mustacchi /* Like dwarf_get_arange_info this ensures debug_info loaded: 496*7fd79137SRobert Mustacchi the cu_header is in debug_info and will be used else 497*7fd79137SRobert Mustacchi we would not call dwarf_get_arange_cu_header_offset. */ 498*7fd79137SRobert Mustacchi if (!dbg->de_debug_info.dss_data) { 499*7fd79137SRobert Mustacchi int res = _dwarf_load_debug_info(dbg, error); 500*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 501*7fd79137SRobert Mustacchi return res; 502*7fd79137SRobert Mustacchi } 503*7fd79137SRobert Mustacchi } 504*7fd79137SRobert Mustacchi *cu_header_offset_returned = arange->ar_info_offset; 505*7fd79137SRobert Mustacchi return DW_DLV_OK; 506*7fd79137SRobert Mustacchi } 507*7fd79137SRobert Mustacchi 508*7fd79137SRobert Mustacchi 509*7fd79137SRobert Mustacchi 510*7fd79137SRobert Mustacchi 511*7fd79137SRobert Mustacchi /* 512*7fd79137SRobert Mustacchi This function takes a Dwarf_Arange, and returns 513*7fd79137SRobert Mustacchi true if it is not NULL. It also stores the start 514*7fd79137SRobert Mustacchi address of the range in *start, the length of the 515*7fd79137SRobert Mustacchi range in *length, and the offset of the first die 516*7fd79137SRobert Mustacchi in the compilation-unit in *cu_die_offset. It 517*7fd79137SRobert Mustacchi returns false on error. 518*7fd79137SRobert Mustacchi If cu_die_offset returned ensures .debug_info loaded so 519*7fd79137SRobert Mustacchi the cu_die_offset is meaningful. 520*7fd79137SRobert Mustacchi */ 521*7fd79137SRobert Mustacchi int 522*7fd79137SRobert Mustacchi dwarf_get_arange_info(Dwarf_Arange arange, 523*7fd79137SRobert Mustacchi Dwarf_Addr * start, 524*7fd79137SRobert Mustacchi Dwarf_Unsigned * length, 525*7fd79137SRobert Mustacchi Dwarf_Off * cu_die_offset, Dwarf_Error * error) 526*7fd79137SRobert Mustacchi { 527*7fd79137SRobert Mustacchi if (arange == NULL) { 528*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); 529*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 530*7fd79137SRobert Mustacchi } 531*7fd79137SRobert Mustacchi 532*7fd79137SRobert Mustacchi if (start != NULL) 533*7fd79137SRobert Mustacchi *start = arange->ar_address; 534*7fd79137SRobert Mustacchi if (length != NULL) 535*7fd79137SRobert Mustacchi *length = arange->ar_length; 536*7fd79137SRobert Mustacchi if (cu_die_offset != NULL) { 537*7fd79137SRobert Mustacchi Dwarf_Debug dbg = arange->ar_dbg; 538*7fd79137SRobert Mustacchi Dwarf_Off offset = arange->ar_info_offset; 539*7fd79137SRobert Mustacchi 540*7fd79137SRobert Mustacchi if (!dbg->de_debug_info.dss_data) { 541*7fd79137SRobert Mustacchi int res = _dwarf_load_debug_info(dbg, error); 542*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 543*7fd79137SRobert Mustacchi return res; 544*7fd79137SRobert Mustacchi } 545*7fd79137SRobert Mustacchi } 546*7fd79137SRobert Mustacchi *cu_die_offset = 547*7fd79137SRobert Mustacchi offset + _dwarf_length_of_cu_header(dbg, offset); 548*7fd79137SRobert Mustacchi } 549*7fd79137SRobert Mustacchi return (DW_DLV_OK); 550*7fd79137SRobert Mustacchi } 551*7fd79137SRobert Mustacchi 552*7fd79137SRobert Mustacchi 553*7fd79137SRobert Mustacchi /* New for DWARF4, entries may have segment information. 554*7fd79137SRobert Mustacchi *segment is only meaningful if *segment_entry_size is non-zero. */ 555*7fd79137SRobert Mustacchi int 556*7fd79137SRobert Mustacchi dwarf_get_arange_info_b(Dwarf_Arange arange, 557*7fd79137SRobert Mustacchi Dwarf_Unsigned* segment, 558*7fd79137SRobert Mustacchi Dwarf_Unsigned* segment_entry_size, 559*7fd79137SRobert Mustacchi Dwarf_Addr * start, 560*7fd79137SRobert Mustacchi Dwarf_Unsigned* length, 561*7fd79137SRobert Mustacchi Dwarf_Off * cu_die_offset, 562*7fd79137SRobert Mustacchi Dwarf_Error * error) 563*7fd79137SRobert Mustacchi { 564*7fd79137SRobert Mustacchi if (arange == NULL) { 565*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); 566*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 567*7fd79137SRobert Mustacchi } 568*7fd79137SRobert Mustacchi 569*7fd79137SRobert Mustacchi if(segment != NULL) { 570*7fd79137SRobert Mustacchi *segment = arange->ar_segment_selector; 571*7fd79137SRobert Mustacchi } 572*7fd79137SRobert Mustacchi if(segment_entry_size != NULL) { 573*7fd79137SRobert Mustacchi *segment_entry_size = arange->ar_segment_selector_size; 574*7fd79137SRobert Mustacchi } 575*7fd79137SRobert Mustacchi if (start != NULL) 576*7fd79137SRobert Mustacchi *start = arange->ar_address; 577*7fd79137SRobert Mustacchi if (length != NULL) 578*7fd79137SRobert Mustacchi *length = arange->ar_length; 579*7fd79137SRobert Mustacchi if (cu_die_offset != NULL) { 580*7fd79137SRobert Mustacchi Dwarf_Debug dbg = arange->ar_dbg; 581*7fd79137SRobert Mustacchi Dwarf_Off offset = arange->ar_info_offset; 582*7fd79137SRobert Mustacchi 583*7fd79137SRobert Mustacchi if (!dbg->de_debug_info.dss_data) { 584*7fd79137SRobert Mustacchi int res = _dwarf_load_debug_info(dbg, error); 585*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 586*7fd79137SRobert Mustacchi return res; 587*7fd79137SRobert Mustacchi } 588*7fd79137SRobert Mustacchi } 589*7fd79137SRobert Mustacchi *cu_die_offset = 590*7fd79137SRobert Mustacchi offset + _dwarf_length_of_cu_header(dbg, offset); 591*7fd79137SRobert Mustacchi } 592*7fd79137SRobert Mustacchi return (DW_DLV_OK); 593*7fd79137SRobert Mustacchi } 594