dwarf1.c revision 130562
1292068Ssjg/* DWARF 1 find nearest line (_bfd_dwarf1_find_nearest_line). 2236769Sobrien Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. 3236769Sobrien 4236769SobrienWritten by Gavin Romig-Koch of Cygnus Solutions (gavin@cygnus.com). 5236769Sobrien 6236769SobrienThis file is part of BFD. 7236769Sobrien 8236769SobrienThis program is free software; you can redistribute it and/or modify 9236769Sobrienit under the terms of the GNU General Public License as published by 10236769Sobrienthe Free Software Foundation; either version 2 of the License, or (at 11236769Sobrienyour option) any later version. 12236769Sobrien 13236769SobrienThis program is distributed in the hope that it will be useful, but 14236769SobrienWITHOUT ANY WARRANTY; without even the implied warranty of 15236769SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16236769SobrienGeneral Public License for more details. 17236769Sobrien 18236769SobrienYou should have received a copy of the GNU General Public License 19236769Sobrienalong with this program; if not, write to the Free Software 20236769SobrienFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 21236769Sobrien 22236769Sobrien#include "bfd.h" 23236769Sobrien#include "sysdep.h" 24236769Sobrien#include "libiberty.h" 25236769Sobrien#include "libbfd.h" 26236769Sobrien#include "elf-bfd.h" 27236769Sobrien#include "elf/dwarf.h" 28236769Sobrien 29236769Sobrien/* dwarf1_debug is the starting point for all dwarf1 info. */ 30236769Sobrien 31236769Sobrienstruct dwarf1_debug { 32236769Sobrien 33236769Sobrien /* The bfd we are working with. */ 34236769Sobrien bfd* abfd; 35236769Sobrien 36236769Sobrien /* List of already parsed compilation units. */ 37236769Sobrien struct dwarf1_unit* lastUnit; 38236769Sobrien 39236769Sobrien /* The buffer for the .debug section. 40236769Sobrien Zero indicates that the .debug section failed to load. */ 41236769Sobrien char* debug_section; 42236769Sobrien 43236769Sobrien /* Pointer to the end of the .debug_info section memory buffer. */ 44236769Sobrien char* debug_section_end; 45236769Sobrien 46236769Sobrien /* The buffer for the .line section. */ 47236769Sobrien char* line_section; 48236769Sobrien 49236769Sobrien /* End of that buffer. */ 50236769Sobrien char* line_section_end; 51236769Sobrien 52236769Sobrien /* The current or next unread die within the .debug section. */ 53236769Sobrien char* currentDie; 54236769Sobrien}; 55236769Sobrien 56236769Sobrien/* One dwarf1_unit for each parsed compilation unit die. */ 57236769Sobrien 58236769Sobrienstruct dwarf1_unit { 59236769Sobrien /* Linked starting from stash->lastUnit. */ 60236769Sobrien struct dwarf1_unit* prev; 61236769Sobrien 62236769Sobrien /* Name of the compilation unit. */ 63236769Sobrien char* name; 64236769Sobrien 65236769Sobrien /* The highest and lowest address used in the compilation unit. */ 66236769Sobrien unsigned long low_pc; 67236769Sobrien unsigned long high_pc; 68236769Sobrien 69236769Sobrien /* Does this unit have a statement list? */ 70236769Sobrien int has_stmt_list; 71236769Sobrien 72236769Sobrien /* If any, the offset of the line number table in the .line section. */ 73236769Sobrien unsigned long stmt_list_offset; 74236769Sobrien 75236769Sobrien /* If non-zero, a pointer to the first child of this unit. */ 76236769Sobrien char* first_child; 77236769Sobrien 78236769Sobrien /* How many line entries? */ 79236769Sobrien unsigned long line_count; 80236769Sobrien 81236769Sobrien /* The decoded line number table (line_count entries). */ 82236769Sobrien struct linenumber* linenumber_table; 83236769Sobrien 84236769Sobrien /* The list of functions in this unit. */ 85236769Sobrien struct dwarf1_func* func_list; 86236769Sobrien}; 87236769Sobrien 88236769Sobrien/* One dwarf1_func for each parsed function die. */ 89236769Sobrien 90236769Sobrienstruct dwarf1_func { 91236769Sobrien /* Linked starting from aUnit->func_list. */ 92236769Sobrien struct dwarf1_func* prev; 93236769Sobrien 94236769Sobrien /* Name of function. */ 95236769Sobrien char* name; 96236769Sobrien 97236769Sobrien /* The highest and lowest address used in the compilation unit. */ 98236769Sobrien unsigned long low_pc; 99236769Sobrien unsigned long high_pc; 100236769Sobrien}; 101236769Sobrien 102237578Sobrien/* Used to return info about a parsed die. */ 103236769Sobrienstruct die_info { 104236769Sobrien unsigned long length; 105236769Sobrien unsigned long sibling; 106249033Ssjg unsigned long low_pc; 107236769Sobrien unsigned long high_pc; 108236769Sobrien unsigned long stmt_list_offset; 109237578Sobrien 110237578Sobrien char* name; 111236769Sobrien 112237578Sobrien int has_stmt_list; 113236769Sobrien 114237578Sobrien unsigned short tag; 115237578Sobrien}; 116237578Sobrien 117237578Sobrien/* Parsed line number information. */ 118237578Sobrienstruct linenumber { 119237578Sobrien /* First address in the line. */ 120237578Sobrien unsigned long addr; 121236769Sobrien 122236769Sobrien /* The line number. */ 123237578Sobrien unsigned long linenumber; 124237578Sobrien}; 125237578Sobrien 126237578Sobrien/* Find the form of an attr, from the attr field. */ 127237578Sobrien#define FORM_FROM_ATTR(attr) ((attr) & 0xF) /* Implicitly specified */ 128236769Sobrien 129236769Sobrienstatic struct dwarf1_unit *alloc_dwarf1_unit 130236769Sobrien PARAMS ((struct dwarf1_debug *)); 131236769Sobrienstatic struct dwarf1_func *alloc_dwarf1_func 132236769Sobrien PARAMS ((struct dwarf1_debug *, struct dwarf1_unit *)); 133236769Sobrienstatic bfd_boolean parse_die 134236769Sobrien PARAMS ((bfd *, struct die_info *, char *, char *)); 135236769Sobrienstatic bfd_boolean parse_line_table 136236769Sobrien PARAMS ((struct dwarf1_debug *, struct dwarf1_unit *)); 137236769Sobrienstatic bfd_boolean parse_functions_in_unit 138236769Sobrien PARAMS ((struct dwarf1_debug *, struct dwarf1_unit *)); 139236769Sobrienstatic bfd_boolean dwarf1_unit_find_nearest_line 140236769Sobrien PARAMS ((struct dwarf1_debug *, struct dwarf1_unit *, unsigned long, 141236769Sobrien const char **, const char **, unsigned int *)); 142236769Sobrien 143236769Sobrien/* Return a newly allocated dwarf1_unit. It should be cleared and 144236769Sobrien then attached into the 'stash' at 'stash->lastUnit'. */ 145236769Sobrien 146236769Sobrienstatic struct dwarf1_unit* 147236769Sobrienalloc_dwarf1_unit (stash) 148236769Sobrien struct dwarf1_debug* stash; 149236769Sobrien{ 150236769Sobrien bfd_size_type amt = sizeof (struct dwarf1_unit); 151236769Sobrien 152236769Sobrien struct dwarf1_unit* x = (struct dwarf1_unit*) bfd_zalloc (stash->abfd, amt); 153236769Sobrien x->prev = stash->lastUnit; 154236769Sobrien stash->lastUnit = x; 155236769Sobrien 156236769Sobrien return x; 157236769Sobrien} 158236769Sobrien 159236769Sobrien/* Return a newly allocated dwarf1_func. It must be cleared and 160236769Sobrien attached into 'aUnit' at 'aUnit->func_list'. */ 161236769Sobrien 162236769Sobrienstatic struct dwarf1_func* 163236769Sobrienalloc_dwarf1_func (stash, aUnit) 164236769Sobrien struct dwarf1_debug* stash; 165236769Sobrien struct dwarf1_unit* aUnit; 166236769Sobrien{ 167236769Sobrien bfd_size_type amt = sizeof (struct dwarf1_func); 168236769Sobrien 169236769Sobrien struct dwarf1_func* x = (struct dwarf1_func*) bfd_zalloc (stash->abfd, amt); 170236769Sobrien x->prev = aUnit->func_list; 171236769Sobrien aUnit->func_list = x; 172236769Sobrien 173236769Sobrien return x; 174236769Sobrien} 175236769Sobrien 176236769Sobrien/* parse_die - parse a Dwarf1 die. 177236769Sobrien Parse the die starting at 'aDiePtr' into 'aDieInfo'. 178236769Sobrien 'abfd' must be the bfd from which the section that 'aDiePtr' 179236769Sobrien points to was pulled from. 180236769Sobrien 181236769Sobrien Return FALSE if the die is invalidly formatted; TRUE otherwise. */ 182236769Sobrien 183236769Sobrienstatic bfd_boolean 184236769Sobrienparse_die (abfd, aDieInfo, aDiePtr, aDiePtrEnd) 185236769Sobrien bfd* abfd; 186236769Sobrien struct die_info* aDieInfo; 187236769Sobrien char* aDiePtr; 188236769Sobrien char* aDiePtrEnd; 189236769Sobrien{ 190236769Sobrien char* this_die = aDiePtr; 191236769Sobrien char* xptr = this_die; 192236769Sobrien 193236769Sobrien memset (aDieInfo,0,sizeof (*aDieInfo)); 194236769Sobrien 195236769Sobrien /* First comes the length. */ 196236769Sobrien aDieInfo->length = bfd_get_32 (abfd, (bfd_byte *) xptr); 197236769Sobrien xptr += 4; 198236769Sobrien if (aDieInfo->length == 0 199236769Sobrien || (this_die + aDieInfo->length) >= aDiePtrEnd) 200236769Sobrien return FALSE; 201236769Sobrien if (aDieInfo->length < 6) 202236769Sobrien { 203236769Sobrien /* Just padding bytes. */ 204236769Sobrien aDieInfo->tag = TAG_padding; 205236769Sobrien return TRUE; 206236769Sobrien } 207236769Sobrien 208236769Sobrien /* Then the tag. */ 209236769Sobrien aDieInfo->tag = bfd_get_16 (abfd, (bfd_byte *) xptr); 210236769Sobrien xptr += 2; 211236769Sobrien 212236769Sobrien /* Then the attributes. */ 213236769Sobrien while (xptr < (this_die + aDieInfo->length)) 214236769Sobrien { 215236769Sobrien unsigned short attr; 216236769Sobrien 217236769Sobrien /* Parse the attribute based on its form. This section 218236769Sobrien must handle all dwarf1 forms, but need only handle the 219236769Sobrien actual attributes that we care about. */ 220236769Sobrien 221236769Sobrien attr = bfd_get_16 (abfd, (bfd_byte *) xptr); 222236769Sobrien xptr += 2; 223236769Sobrien 224236769Sobrien switch (FORM_FROM_ATTR (attr)) 225236769Sobrien { 226236769Sobrien case FORM_DATA2: 227236769Sobrien xptr += 2; 228236769Sobrien break; 229236769Sobrien case FORM_DATA4: 230236769Sobrien case FORM_REF: 231236769Sobrien if (attr == AT_sibling) 232236769Sobrien aDieInfo->sibling = bfd_get_32 (abfd, (bfd_byte *) xptr); 233236769Sobrien else if (attr == AT_stmt_list) 234236769Sobrien { 235236769Sobrien aDieInfo->stmt_list_offset = bfd_get_32 (abfd, (bfd_byte *) xptr); 236236769Sobrien aDieInfo->has_stmt_list = 1; 237236769Sobrien } 238236769Sobrien xptr += 4; 239236769Sobrien break; 240236769Sobrien case FORM_DATA8: 241236769Sobrien xptr += 8; 242236769Sobrien break; 243236769Sobrien case FORM_ADDR: 244236769Sobrien if (attr == AT_low_pc) 245236769Sobrien aDieInfo->low_pc = bfd_get_32 (abfd, (bfd_byte *) xptr); 246236769Sobrien else if (attr == AT_high_pc) 247236769Sobrien aDieInfo->high_pc = bfd_get_32 (abfd, (bfd_byte *) xptr); 248236769Sobrien xptr += 4; 249236769Sobrien break; 250236769Sobrien case FORM_BLOCK2: 251236769Sobrien xptr += 2 + bfd_get_16 (abfd, (bfd_byte *) xptr); 252236769Sobrien break; 253236769Sobrien case FORM_BLOCK4: 254236769Sobrien xptr += 4 + bfd_get_32 (abfd, (bfd_byte *) xptr); 255236769Sobrien break; 256236769Sobrien case FORM_STRING: 257236769Sobrien if (attr == AT_name) 258236769Sobrien aDieInfo->name = xptr; 259236769Sobrien xptr += strlen (xptr) + 1; 260236769Sobrien break; 261236769Sobrien } 262236769Sobrien } 263236769Sobrien 264236769Sobrien return TRUE; 265236769Sobrien} 266236769Sobrien 267236769Sobrien/* Parse a dwarf1 line number table for 'aUnit->stmt_list_offset' 268236769Sobrien into 'aUnit->linenumber_table'. Return FALSE if an error 269236769Sobrien occurs; TRUE otherwise. */ 270236769Sobrien 271236769Sobrienstatic bfd_boolean 272236769Sobrienparse_line_table (stash, aUnit) 273236769Sobrien struct dwarf1_debug* stash; 274236769Sobrien struct dwarf1_unit* aUnit; 275236769Sobrien{ 276236769Sobrien char* xptr; 277236769Sobrien 278236769Sobrien /* Load the ".line" section from the bfd if we haven't already. */ 279236769Sobrien if (stash->line_section == 0) 280236769Sobrien { 281236769Sobrien asection *msec; 282236769Sobrien bfd_size_type size; 283236769Sobrien 284236769Sobrien msec = bfd_get_section_by_name (stash->abfd, ".line"); 285236769Sobrien if (! msec) 286236769Sobrien return FALSE; 287236769Sobrien 288236769Sobrien size = bfd_get_section_size_before_reloc (msec); 289236769Sobrien stash->line_section = (char *) bfd_alloc (stash->abfd, size); 290236769Sobrien 291236769Sobrien if (! stash->line_section) 292292068Ssjg return FALSE; 293236769Sobrien 294236769Sobrien if (! bfd_get_section_contents (stash->abfd, msec, stash->line_section, 295236769Sobrien (bfd_vma) 0, size)) 296236769Sobrien { 297236769Sobrien stash->line_section = 0; 298236769Sobrien return FALSE; 299236769Sobrien } 300236769Sobrien 301236769Sobrien stash->line_section_end = stash->line_section + size; 302236769Sobrien } 303236769Sobrien 304236769Sobrien xptr = stash->line_section + aUnit->stmt_list_offset; 305236769Sobrien if (xptr < stash->line_section_end) 306236769Sobrien { 307236769Sobrien unsigned long eachLine; 308236769Sobrien char *tblend; 309236769Sobrien unsigned long base; 310236769Sobrien bfd_size_type amt; 311236769Sobrien 312236769Sobrien /* First comes the length. */ 313236769Sobrien tblend = bfd_get_32 (stash->abfd, (bfd_byte *) xptr) + xptr; 314236769Sobrien xptr += 4; 315236769Sobrien 316236769Sobrien /* Then the base address for each address in the table. */ 317236769Sobrien base = bfd_get_32 (stash->abfd, (bfd_byte *) xptr); 318236769Sobrien xptr += 4; 319236769Sobrien 320236769Sobrien /* How many line entrys? 321236769Sobrien 10 = 4 (line number) + 2 (pos in line) + 4 (address in line) */ 322236769Sobrien aUnit->line_count = (tblend - xptr) / 10; 323236769Sobrien 324236769Sobrien /* Allocate an array for the entries. */ 325236769Sobrien amt = sizeof (struct linenumber) * aUnit->line_count; 326236769Sobrien aUnit->linenumber_table = ((struct linenumber *) 327236769Sobrien bfd_alloc (stash->abfd, amt)); 328236769Sobrien 329236769Sobrien for (eachLine = 0; eachLine < aUnit->line_count; eachLine++) 330236769Sobrien { 331236769Sobrien /* A line number. */ 332236769Sobrien aUnit->linenumber_table[eachLine].linenumber 333236769Sobrien = bfd_get_32 (stash->abfd, (bfd_byte *) xptr); 334236769Sobrien xptr += 4; 335236769Sobrien 336236769Sobrien /* Skip the position within the line. */ 337236769Sobrien xptr += 2; 338236769Sobrien 339236769Sobrien /* And finally the address. */ 340236769Sobrien aUnit->linenumber_table[eachLine].addr 341236769Sobrien = base + bfd_get_32 (stash->abfd, (bfd_byte *) xptr); 342236769Sobrien xptr += 4; 343236769Sobrien } 344236769Sobrien } 345236769Sobrien 346236769Sobrien return TRUE; 347236769Sobrien} 348236769Sobrien 349236769Sobrien/* Parse each function die in a compilation unit 'aUnit'. 350236769Sobrien The first child die of 'aUnit' should be in 'aUnit->first_child', 351236769Sobrien the result is placed in 'aUnit->func_list'. 352236769Sobrien Return FALSE if error; TRUE otherwise. */ 353236769Sobrien 354236769Sobrienstatic bfd_boolean 355236769Sobrienparse_functions_in_unit (stash, aUnit) 356236769Sobrien struct dwarf1_debug* stash; 357236769Sobrien struct dwarf1_unit* aUnit; 358236769Sobrien{ 359236769Sobrien char* eachDie; 360236769Sobrien 361236769Sobrien if (aUnit->first_child) 362236769Sobrien for (eachDie = aUnit->first_child; 363236769Sobrien eachDie < stash->debug_section_end; 364236769Sobrien ) 365236769Sobrien { 366236769Sobrien struct die_info eachDieInfo; 367236769Sobrien 368236769Sobrien if (! parse_die (stash->abfd, &eachDieInfo, eachDie, 369236769Sobrien stash->debug_section_end)) 370236769Sobrien return FALSE; 371236769Sobrien 372236769Sobrien if (eachDieInfo.tag == TAG_global_subroutine 373236769Sobrien || eachDieInfo.tag == TAG_subroutine 374236769Sobrien || eachDieInfo.tag == TAG_inlined_subroutine 375236769Sobrien || eachDieInfo.tag == TAG_entry_point) 376236769Sobrien { 377236769Sobrien struct dwarf1_func* aFunc = alloc_dwarf1_func (stash,aUnit); 378236769Sobrien 379236769Sobrien aFunc->name = eachDieInfo.name; 380236769Sobrien aFunc->low_pc = eachDieInfo.low_pc; 381236769Sobrien aFunc->high_pc = eachDieInfo.high_pc; 382236769Sobrien } 383236769Sobrien 384236769Sobrien /* Move to next sibling, if none, end loop */ 385236769Sobrien if (eachDieInfo.sibling) 386236769Sobrien eachDie = stash->debug_section + eachDieInfo.sibling; 387236769Sobrien else 388236769Sobrien break; 389236769Sobrien } 390236769Sobrien 391236769Sobrien return TRUE; 392236769Sobrien} 393236769Sobrien 394236769Sobrien/* Find the nearest line to 'addr' in 'aUnit'. 395236769Sobrien Return whether we found the line (or a function) without error. */ 396236769Sobrien 397236769Sobrienstatic bfd_boolean 398236769Sobriendwarf1_unit_find_nearest_line (stash, aUnit, addr, 399236769Sobrien filename_ptr, functionname_ptr, 400236769Sobrien linenumber_ptr) 401236769Sobrien struct dwarf1_debug* stash; 402236769Sobrien struct dwarf1_unit* aUnit; 403236769Sobrien unsigned long addr; 404236769Sobrien const char **filename_ptr; 405236769Sobrien const char **functionname_ptr; 406236769Sobrien unsigned int *linenumber_ptr; 407236769Sobrien{ 408255253Ssjg int line_p = FALSE; 409255253Ssjg int func_p = FALSE; 410255253Ssjg 411255253Ssjg if (aUnit->low_pc <= addr && addr < aUnit->high_pc) 412236769Sobrien { 413236769Sobrien if (aUnit->has_stmt_list) 414236769Sobrien { 415236769Sobrien unsigned long i; 416236769Sobrien struct dwarf1_func* eachFunc; 417236769Sobrien 418236769Sobrien if (! aUnit->linenumber_table) 419236769Sobrien { 420236769Sobrien if (! parse_line_table (stash, aUnit)) 421236769Sobrien return FALSE; 422236769Sobrien } 423236769Sobrien 424236769Sobrien if (! aUnit->func_list) 425236769Sobrien { 426236769Sobrien if (! parse_functions_in_unit (stash, aUnit)) 427236769Sobrien return FALSE; 428236769Sobrien } 429236769Sobrien 430236769Sobrien for (i = 0; i < aUnit->line_count; i++) 431236769Sobrien { 432236769Sobrien if (aUnit->linenumber_table[i].addr <= addr 433236769Sobrien && addr < aUnit->linenumber_table[i+1].addr) 434236769Sobrien { 435236769Sobrien *filename_ptr = aUnit->name; 436236769Sobrien *linenumber_ptr = aUnit->linenumber_table[i].linenumber; 437236769Sobrien line_p = TRUE; 438236769Sobrien break; 439236769Sobrien } 440236769Sobrien } 441236769Sobrien 442236769Sobrien for (eachFunc = aUnit->func_list; 443236769Sobrien eachFunc; 444236769Sobrien eachFunc = eachFunc->prev) 445236769Sobrien { 446236769Sobrien if (eachFunc->low_pc <= addr 447236769Sobrien && addr < eachFunc->high_pc) 448236769Sobrien { 449236769Sobrien *functionname_ptr = eachFunc->name; 450253883Ssjg func_p = TRUE; 451253883Ssjg break; 452236769Sobrien } 453236769Sobrien } 454236769Sobrien } 455236769Sobrien } 456236769Sobrien 457236769Sobrien return line_p || func_p; 458236769Sobrien} 459236769Sobrien 460236769Sobrien/* The DWARF 1 version of find_nearest line. 461236769Sobrien Return TRUE if the line is found without error. */ 462236769Sobrien 463236769Sobrienbfd_boolean 464236769Sobrien_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset, 465236769Sobrien filename_ptr, functionname_ptr, linenumber_ptr) 466236769Sobrien bfd *abfd; 467236769Sobrien asection *section; 468236769Sobrien asymbol **symbols ATTRIBUTE_UNUSED; 469236769Sobrien bfd_vma offset; 470236769Sobrien const char **filename_ptr; 471236769Sobrien const char **functionname_ptr; 472236769Sobrien unsigned int *linenumber_ptr; 473236769Sobrien{ 474236769Sobrien struct dwarf1_debug *stash = elf_tdata (abfd)->dwarf1_find_line_info; 475236769Sobrien 476236769Sobrien struct dwarf1_unit* eachUnit; 477236769Sobrien 478236769Sobrien /* What address are we looking for? */ 479236769Sobrien unsigned long addr = (unsigned long)(offset + section->vma); 480236769Sobrien 481236769Sobrien *filename_ptr = NULL; 482236769Sobrien *functionname_ptr = NULL; 483236769Sobrien *linenumber_ptr = 0; 484236769Sobrien 485236769Sobrien if (! stash) 486236769Sobrien { 487236769Sobrien asection *msec; 488236769Sobrien bfd_size_type size = sizeof (struct dwarf1_debug); 489236769Sobrien 490236769Sobrien stash = elf_tdata (abfd)->dwarf1_find_line_info 491236769Sobrien = (struct dwarf1_debug *) bfd_zalloc (abfd, size); 492236769Sobrien 493236769Sobrien if (! stash) 494236769Sobrien return FALSE; 495236769Sobrien 496236769Sobrien msec = bfd_get_section_by_name (abfd, ".debug"); 497236769Sobrien if (! msec) 498236769Sobrien { 499236769Sobrien /* No dwarf1 info. Note that at this point the stash 500236769Sobrien has been allocated, but contains zeros, this lets 501236769Sobrien future calls to this function fail quicker. */ 502236769Sobrien return FALSE; 503236769Sobrien } 504236769Sobrien 505236769Sobrien size = bfd_get_section_size_before_reloc (msec); 506236769Sobrien stash->debug_section = (char *) bfd_alloc (abfd, size); 507236769Sobrien 508236769Sobrien if (! stash->debug_section) 509236769Sobrien return FALSE; 510236769Sobrien 511236769Sobrien if (! bfd_get_section_contents (abfd, msec, stash->debug_section, 512236769Sobrien (bfd_vma) 0, size)) 513236769Sobrien { 514236769Sobrien stash->debug_section = 0; 515236769Sobrien return FALSE; 516236769Sobrien } 517236769Sobrien 518236769Sobrien stash->debug_section_end = stash->debug_section + size; 519236769Sobrien stash->currentDie = stash->debug_section; 520236769Sobrien stash->abfd = abfd; 521236769Sobrien } 522292068Ssjg 523292068Ssjg /* A null debug_section indicates that there was no dwarf1 info 524292068Ssjg or that an error occured while setting up the stash. */ 525292068Ssjg 526276305Sngie if (! stash->debug_section) 527292068Ssjg return FALSE; 528276305Sngie 529292068Ssjg /* Look at the previously parsed units to see if any contain 530292068Ssjg the addr. */ 531292068Ssjg for (eachUnit = stash->lastUnit; eachUnit; eachUnit = eachUnit->prev) 532276305Sngie { 533236769Sobrien if (eachUnit->low_pc <= addr && addr < eachUnit->high_pc) 534 return dwarf1_unit_find_nearest_line (stash, eachUnit, addr, 535 filename_ptr, 536 functionname_ptr, 537 linenumber_ptr); 538 } 539 540 while (stash->currentDie < stash->debug_section_end) 541 { 542 struct die_info aDieInfo; 543 544 if (! parse_die (stash->abfd, &aDieInfo, stash->currentDie, 545 stash->debug_section_end)) 546 return FALSE; 547 548 if (aDieInfo.tag == TAG_compile_unit) 549 { 550 struct dwarf1_unit* aUnit 551 = alloc_dwarf1_unit (stash); 552 553 aUnit->name = aDieInfo.name; 554 aUnit->low_pc = aDieInfo.low_pc; 555 aUnit->high_pc = aDieInfo.high_pc; 556 aUnit->has_stmt_list = aDieInfo.has_stmt_list; 557 aUnit->stmt_list_offset = aDieInfo.stmt_list_offset; 558 559 /* A die has a child if it's followed by a die that is 560 not it's sibling. */ 561 if (aDieInfo.sibling 562 && stash->currentDie + aDieInfo.length 563 < stash->debug_section_end 564 && stash->currentDie + aDieInfo.length 565 != stash->debug_section + aDieInfo.sibling) 566 aUnit->first_child = stash->currentDie + aDieInfo.length; 567 else 568 aUnit->first_child = 0; 569 570 if (aUnit->low_pc <= addr && addr < aUnit->high_pc) 571 return dwarf1_unit_find_nearest_line (stash, aUnit, addr, 572 filename_ptr, 573 functionname_ptr, 574 linenumber_ptr); 575 } 576 577 if (aDieInfo.sibling != 0) 578 stash->currentDie = stash->debug_section + aDieInfo.sibling; 579 else 580 stash->currentDie += aDieInfo.length; 581 } 582 583 return FALSE; 584} 585 586/* EOF */ 587