diff options
Diffstat (limited to 'tools/perf/util/annotate.c')
| -rw-r--r-- | tools/perf/util/annotate.c | 23 | 
1 files changed, 16 insertions, 7 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index ea7e0de4b9c1..06cc04e5806a 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -223,13 +223,19 @@ bool ins__is_call(const struct ins *ins)  static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map *map __maybe_unused)  {  	const char *s = strchr(ops->raw, '+'); +	const char *c = strchr(ops->raw, ','); -	ops->target.addr = strtoull(ops->raw, NULL, 16); +	if (c++ != NULL) +		ops->target.addr = strtoull(c, NULL, 16); +	else +		ops->target.addr = strtoull(ops->raw, NULL, 16); -	if (s++ != NULL) +	if (s++ != NULL) {  		ops->target.offset = strtoull(s, NULL, 16); -	else -		ops->target.offset = UINT64_MAX; +		ops->target.offset_avail = true; +	} else { +		ops->target.offset_avail = false; +	}  	return 0;  } @@ -237,7 +243,7 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op  static int jump__scnprintf(struct ins *ins, char *bf, size_t size,  			   struct ins_operands *ops)  { -	if (!ops->target.addr) +	if (!ops->target.addr || ops->target.offset < 0)  		return ins__raw_scnprintf(ins, bf, size, ops);  	return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset); @@ -641,7 +647,8 @@ static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map,  	pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); -	if (addr < sym->start || addr >= sym->end) { +	if ((addr < sym->start || addr >= sym->end) && +	    (addr != sym->end || sym->start != sym->end)) {  		pr_debug("%s(%d): ERANGE! sym->name=%s, start=%#" PRIx64 ", addr=%#" PRIx64 ", end=%#" PRIx64 "\n",  		       __func__, __LINE__, sym->name, sym->start, addr, sym->end);  		return -ERANGE; @@ -1205,9 +1212,11 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,  	if (dl == NULL)  		return -1; -	if (dl->ops.target.offset == UINT64_MAX) +	if (!disasm_line__has_offset(dl)) {  		dl->ops.target.offset = dl->ops.target.addr -  					map__rip_2objdump(map, sym->start); +		dl->ops.target.offset_avail = true; +	}  	/* kcore has no symbols, so add the call target name */  	if (dl->ins.ops && ins__is_call(&dl->ins) && !dl->ops.target.name) {  | 
