static bfd_byte * macho_symfile_relocate (struct objfile *objfile, asection *sectp, bfd_byte *buf) { bfd *abfd = objfile->obfd; /* We're only interested in sections with relocation information. */ if ((sectp->flags & SEC_RELOC) == 0) return NULL; if (mach_o_debug_level > 0) printf_unfiltered (_("Relocate section '%s' of %s\n"), sectp->name, objfile_name (objfile)); return bfd_simple_get_relocated_section_contents (abfd, sectp, buf, NULL); }
bfd_boolean _bfd_dwarf1_find_nearest_line (bfd *abfd, asection *section, asymbol **symbols, bfd_vma offset, const char **filename_ptr, const char **functionname_ptr, unsigned int *linenumber_ptr) { struct dwarf1_debug *stash = elf_tdata (abfd)->dwarf1_find_line_info; struct dwarf1_unit* eachUnit; /* What address are we looking for? */ unsigned long addr = (unsigned long)(offset + section->vma); *filename_ptr = NULL; *functionname_ptr = NULL; *linenumber_ptr = 0; if (! stash) { asection *msec; bfd_size_type size = sizeof (struct dwarf1_debug); stash = elf_tdata (abfd)->dwarf1_find_line_info = (struct dwarf1_debug *) bfd_zalloc (abfd, size); if (! stash) return FALSE; msec = bfd_get_section_by_name (abfd, ".debug"); if (! msec) /* No dwarf1 info. Note that at this point the stash has been allocated, but contains zeros, this lets future calls to this function fail quicker. */ return FALSE; size = msec->rawsize ? msec->rawsize : msec->size; stash->debug_section = bfd_simple_get_relocated_section_contents (abfd, msec, NULL, symbols); if (! stash->debug_section) return FALSE; stash->debug_section_end = stash->debug_section + size; stash->currentDie = stash->debug_section; stash->abfd = abfd; stash->syms = symbols; } /* A null debug_section indicates that there was no dwarf1 info or that an error occured while setting up the stash. */ if (! stash->debug_section) return FALSE; /* Look at the previously parsed units to see if any contain the addr. */ for (eachUnit = stash->lastUnit; eachUnit; eachUnit = eachUnit->prev) if (eachUnit->low_pc <= addr && addr < eachUnit->high_pc) return dwarf1_unit_find_nearest_line (stash, eachUnit, addr, filename_ptr, functionname_ptr, linenumber_ptr); while (stash->currentDie < stash->debug_section_end) { struct die_info aDieInfo; if (! parse_die (stash->abfd, &aDieInfo, stash->currentDie, stash->debug_section_end)) return FALSE; if (aDieInfo.tag == TAG_compile_unit) { struct dwarf1_unit* aUnit = alloc_dwarf1_unit (stash); if (!aUnit) return FALSE; aUnit->name = aDieInfo.name; aUnit->low_pc = aDieInfo.low_pc; aUnit->high_pc = aDieInfo.high_pc; aUnit->has_stmt_list = aDieInfo.has_stmt_list; aUnit->stmt_list_offset = aDieInfo.stmt_list_offset; /* A die has a child if it's followed by a die that is not it's sibling. */ if (aDieInfo.sibling && stash->currentDie + aDieInfo.length < stash->debug_section_end && stash->currentDie + aDieInfo.length != stash->debug_section + aDieInfo.sibling) aUnit->first_child = stash->currentDie + aDieInfo.length; else aUnit->first_child = 0; if (aUnit->low_pc <= addr && addr < aUnit->high_pc) return dwarf1_unit_find_nearest_line (stash, aUnit, addr, filename_ptr, functionname_ptr, linenumber_ptr); } if (aDieInfo.sibling != 0) stash->currentDie = stash->debug_section + aDieInfo.sibling; else stash->currentDie += aDieInfo.length; } return FALSE; }
static bfd_boolean parse_line_table (struct dwarf1_debug* stash, struct dwarf1_unit* aUnit) { bfd_byte *xptr; /* Load the ".line" section from the bfd if we haven't already. */ if (stash->line_section == 0) { asection *msec; bfd_size_type size; msec = bfd_get_section_by_name (stash->abfd, ".line"); if (! msec) return FALSE; size = msec->rawsize ? msec->rawsize : msec->size; stash->line_section = bfd_simple_get_relocated_section_contents (stash->abfd, msec, NULL, stash->syms); if (! stash->line_section) return FALSE; stash->line_section_end = stash->line_section + size; } xptr = stash->line_section + aUnit->stmt_list_offset; if (xptr < stash->line_section_end) { unsigned long eachLine; bfd_byte *tblend; unsigned long base; bfd_size_type amt; /* First comes the length. */ tblend = bfd_get_32 (stash->abfd, (bfd_byte *) xptr) + xptr; xptr += 4; /* Then the base address for each address in the table. */ base = bfd_get_32 (stash->abfd, (bfd_byte *) xptr); xptr += 4; /* How many line entrys? 10 = 4 (line number) + 2 (pos in line) + 4 (address in line). */ aUnit->line_count = (tblend - xptr) / 10; /* Allocate an array for the entries. */ amt = sizeof (struct linenumber) * aUnit->line_count; aUnit->linenumber_table = (struct linenumber *) bfd_alloc (stash->abfd, amt); if (!aUnit->linenumber_table) return FALSE; for (eachLine = 0; eachLine < aUnit->line_count; eachLine++) { /* A line number. */ aUnit->linenumber_table[eachLine].linenumber = bfd_get_32 (stash->abfd, (bfd_byte *) xptr); xptr += 4; /* Skip the position within the line. */ xptr += 2; /* And finally the address. */ aUnit->linenumber_table[eachLine].addr = base + bfd_get_32 (stash->abfd, (bfd_byte *) xptr); xptr += 4; } } return TRUE; }