Esempio n. 1
0
static char *
demangle(char *name, int strict, size_t *pos)
{
	static char dem[STRBUFSZ];
	char nb[STRBUFSZ];
	size_t p, t;

	if (stripus && *name == '_') {
		strncpy(nb, name + 1, sizeof(nb) - 1);
		t = 1;
	} else {
		strncpy(nb, name, sizeof(nb) - 1);
		t = 0;
	}
	nb[sizeof(nb) - 1] = '\0';

	p = strlen(nb);
	if (p == 0)
		return NULL;

	while (elftc_demangle(nb, dem, sizeof(dem), (unsigned) format) < 0) {
		if (!strict && p > 1) {
			nb[--p] = '\0';
			continue;
		} else
			return (NULL);
	}

	if (pos != NULL)
		*pos = t ? p + 1 : p;

	return (dem);
}
Esempio n. 2
0
static char *
demangle(char *name)
{
	static char dem[STRBUFSZ];

	if (stripus && *name == '_')
		name++;

	if (strlen(name) == 0)
		return (NULL);

	if (elftc_demangle(name, dem, sizeof(dem), (unsigned) format) < 0)
		return (NULL);

	return (dem);
}
Esempio n. 3
0
static void
translate(Dwarf_Debug dbg, const char* addrstr)
{
	Dwarf_Die die, ret_die;
	Dwarf_Line *lbuf;
	Dwarf_Error de;
	Dwarf_Half tag;
	Dwarf_Unsigned lopc, hipc, addr, lineno, plineno;
	Dwarf_Signed lcount;
	Dwarf_Addr lineaddr, plineaddr;
	char *funcname;
	char *file, *file0, *pfile;
	char demangled[1024];
	int i, ret;

	addr = strtoull(addrstr, NULL, 16);
	addr += section_base;
	lineno = 0;
	file = unknown;
	die = NULL;
	lbuf = NULL;
	lcount = 0;

	while ((ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL,
	    &de)) ==  DW_DLV_OK) {
		die = NULL;
		while (dwarf_siblingof(dbg, die, &ret_die, &de) == DW_DLV_OK) {
			if (die != NULL)
				dwarf_dealloc(dbg, die, DW_DLA_DIE);
			die = ret_die;
			if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) {
				warnx("dwarf_tag failed: %s",
				    dwarf_errmsg(de));
				goto next_cu;
			}

			/* XXX: What about DW_TAG_partial_unit? */
			if (tag == DW_TAG_compile_unit)
				break;
		}
		if (ret_die == NULL) {
			warnx("could not find DW_TAG_compile_unit die");
			goto next_cu;
		}
		if (!dwarf_attrval_unsigned(die, DW_AT_low_pc, &lopc, &de) &&
		    !dwarf_attrval_unsigned(die, DW_AT_high_pc, &hipc, &de)) {
			/*
			 * Check if the address falls into the PC range of
			 * this CU.
			 */
			if (handle_high_pc(die, lopc, &hipc) != DW_DLV_OK)
				goto next_cu;
			if (addr < lopc || addr >= hipc)
				goto next_cu;
		}

		switch (dwarf_srclines(die, &lbuf, &lcount, &de)) {
		case DW_DLV_OK:
			break;
		case DW_DLV_NO_ENTRY:
			/* If a CU lacks debug info, just skip it. */
			goto next_cu;
		default:
			warnx("dwarf_srclines: %s", dwarf_errmsg(de));
			goto out;
		}

		plineaddr = ~0ULL;
		plineno = 0;
		pfile = unknown;
		for (i = 0; i < lcount; i++) {
			if (dwarf_lineaddr(lbuf[i], &lineaddr, &de)) {
				warnx("dwarf_lineaddr: %s",
				    dwarf_errmsg(de));
				goto out;
			}
			if (dwarf_lineno(lbuf[i], &lineno, &de)) {
				warnx("dwarf_lineno: %s",
				    dwarf_errmsg(de));
				goto out;
			}
			if (dwarf_linesrc(lbuf[i], &file0, &de)) {
				warnx("dwarf_linesrc: %s",
				    dwarf_errmsg(de));
			} else
				file = file0;
			if (addr == lineaddr)
				goto out;
			else if (addr < lineaddr && addr > plineaddr) {
				lineno = plineno;
				file = pfile;
				goto out;
			}
			plineaddr = lineaddr;
			plineno = lineno;
			pfile = file;
		}
	next_cu:
		if (die != NULL) {
			dwarf_dealloc(dbg, die, DW_DLA_DIE);
			die = NULL;
		}
	}

out:
	funcname = NULL;
	if (ret == DW_DLV_OK && func) {
		search_func(dbg, die, addr, &funcname);
		die = NULL;
	}

	if (func) {
		if (funcname == NULL)
			if ((funcname = strdup(unknown)) == NULL)
				err(EXIT_FAILURE, "strdup");
		if (demangle &&
		    !elftc_demangle(funcname, demangled, sizeof(demangled), 0))
			printf("%s\n", demangled);
		else
			printf("%s\n", funcname);
		free(funcname);
	}

	(void) printf("%s:%ju\n", base ? basename(file) : file, lineno);

	if (die != NULL)
		dwarf_dealloc(dbg, die, DW_DLA_DIE);

	/*
	 * Reset internal CU pointer, so we will start from the first CU
	 * next round.
	 */
	while (ret != DW_DLV_NO_ENTRY) {
		if (ret == DW_DLV_ERROR)
			errx(EXIT_FAILURE, "dwarf_next_cu_header: %s",
			    dwarf_errmsg(de));
		ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL,
		    &de);
	}
}