linenr_info const find_nearest_line(bfd_info const & b, op_bfd_symbol const & sym, unsigned int offset) { char const * function = ""; char const * cfilename = ""; unsigned int linenr = 0; linenr_info info; bfd * abfd; asymbol ** syms; asection * section; bfd_vma pc; bool ret; if (!b.valid()) goto fail; // take care about artificial symbol if (!sym.symbol()) goto fail; abfd = b.abfd; syms = b.syms.get(); section = sym.symbol()->section; pc = (sym.value() + offset) - sym.filepos(); if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0) goto fail; if (pc >= bfd_section_size(abfd, section)) goto fail; ret = bfd_find_nearest_line(abfd, section, syms, pc, &cfilename, &function, &linenr); if (!ret || !cfilename || !function) goto fail; if (!is_correct_function(function, sym.name())) goto fail; if (linenr == 0) { fixup_linenr(abfd, section, syms, sym.name(), pc, &cfilename, &linenr); } info.found = true; info.filename = cfilename; info.line = linenr; return info; fail: info.found = false; // some stl lacks string::clear() info.filename.erase(info.filename.begin(), info.filename.end()); info.line = 0; return info; }
linenr_info const find_nearest_line(bfd_info const & b, op_bfd_symbol const & sym, bfd_vma offset, bool anon_obj) { char const * function = ""; char const * cfilename = ""; unsigned int linenr = 0; linenr_info info; bfd * abfd; asymbol ** syms; asection * section = NULL; asymbol * empty_syms[1]; bfd_vma pc; bool ret; if (!b.valid()) goto fail; // take care about artificial symbol if (!sym.symbol()) goto fail; abfd = b.abfd; syms = b.syms.get(); if (!syms) { // If this bfd_info object has no syms, that implies that we're // using a debuginfo bfd_info object that has only debug data. // This also implies that the passed sym is from the runtime binary, // and thus it's section is also from the runtime binary. And // since section VMA can be different for a runtime binary (prelinked) // and its associated debuginfo, we need to obtain the debuginfo // section to pass to the libbfd functions. asection * sect_candidate; bfd_vma vma_adj = b.get_image_bfd_info()->abfd->start_address - abfd->start_address; if (vma_adj == 0) section = sym.symbol()->section; for (sect_candidate = abfd->sections; (sect_candidate != NULL) && (section == NULL); sect_candidate = sect_candidate->next) { if (sect_candidate->vma + vma_adj == sym.symbol()->section->vma) { section = sect_candidate; } } if (section == NULL) { cerr << "ERROR: Unable to find section for symbol " << sym.symbol()->name << endl; goto fail; } syms = empty_syms; syms[0] = NULL; } else { section = sym.symbol()->section; } if (anon_obj) pc = offset - sym.symbol()->section->vma; else pc = (sym.value() + offset) - sym.filepos(); if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0) goto fail; if (pc >= bfd_section_size(abfd, section)) goto fail; ret = bfd_find_nearest_line(abfd, section, syms, pc, &cfilename, &function, &linenr); if (!ret || !cfilename || !function) goto fail; /* * is_correct_function does not handle the case of static inlines, * but if the linenr is non-zero in the inline case, it is the correct * line number. */ if (linenr == 0 && !is_correct_function(function, sym.name())) goto fail; if (linenr == 0) { fixup_linenr(abfd, section, syms, sym.name(), pc, &cfilename, &linenr); } info.found = true; info.filename = cfilename; info.line = linenr; return info; fail: info.found = false; // some stl lacks string::clear() info.filename.erase(info.filename.begin(), info.filename.end()); info.line = 0; return info; }
linenr_info const find_nearest_line(bfd_info const & b, op_bfd_symbol const & sym, bfd_vma offset, bool anon_obj) { char const * function = ""; char const * cfilename = ""; unsigned int linenr = 0; linenr_info info; bfd * abfd; asymbol ** syms; asection * section; bfd_vma pc; bool ret; if (!b.valid()) goto fail; // take care about artificial symbol if (!sym.symbol()) goto fail; abfd = b.abfd; syms = b.syms.get(); if (!syms) goto fail; section = sym.symbol()->section; if (anon_obj) pc = offset - sym.symbol()->section->vma; else pc = (sym.value() + offset) - sym.filepos(); if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0) goto fail; if (pc >= bfd_section_size(abfd, section)) goto fail; ret = bfd_find_nearest_line(abfd, section, syms, pc, &cfilename, &function, &linenr); if (!ret || !cfilename || !function) goto fail; /* * is_correct_function does not handle the case of static inlines, * but if the linenr is non-zero in the inline case, it is the correct * line number. */ if (linenr == 0 && !is_correct_function(function, sym.name())) goto fail; if (linenr == 0) { fixup_linenr(abfd, section, syms, sym.name(), pc, &cfilename, &linenr); } info.found = true; info.filename = cfilename; info.line = linenr; return info; fail: info.found = false; // some stl lacks string::clear() info.filename.erase(info.filename.begin(), info.filename.end()); info.line = 0; return info; }