Example #1
0
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;
}
Example #2
0
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;
}