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