diff options
Diffstat (limited to 'tools/perf/util/annotate.c')
| -rw-r--r-- | tools/perf/util/annotate.c | 32 | 
1 files changed, 29 insertions, 3 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 20061cf42288..28cd6a17491b 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -246,8 +246,14 @@ find_target:  indirect_call:  	tok = strchr(endptr, '*'); -	if (tok != NULL) -		ops->target.addr = strtoull(tok + 1, NULL, 16); +	if (tok != NULL) { +		endptr++; + +		/* Indirect call can use a non-rip register and offset: callq  *0x8(%rbx). +		 * Do not parse such instruction.  */ +		if (strstr(endptr, "(%r") == NULL) +			ops->target.addr = strtoull(endptr, NULL, 16); +	}  	goto find_target;  } @@ -276,7 +282,19 @@ bool ins__is_call(const struct ins *ins)  	return ins->ops == &call_ops || ins->ops == &s390_call_ops;  } -static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map_symbol *ms) +/* + * Prevents from matching commas in the comment section, e.g.: + * ffff200008446e70:       b.cs    ffff2000084470f4 <generic_exec_single+0x314>  // b.hs, b.nlast + */ +static inline const char *validate_comma(const char *c, struct ins_operands *ops) +{ +	if (ops->raw_comment && c > ops->raw_comment) +		return NULL; + +	return c; +} + +static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms)  {  	struct map *map = ms->map;  	struct symbol *sym = ms->sym; @@ -285,6 +303,10 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op  	};  	const char *c = strchr(ops->raw, ',');  	u64 start, end; + +	ops->raw_comment = strchr(ops->raw, arch->objdump.comment_char); +	c = validate_comma(c, ops); +  	/*  	 * Examples of lines to parse for the _cpp_lex_token@@Base  	 * function: @@ -304,6 +326,7 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op  		ops->target.addr = strtoull(c, NULL, 16);  		if (!ops->target.addr) {  			c = strchr(c, ','); +			c = validate_comma(c, ops);  			if (c++ != NULL)  				ops->target.addr = strtoull(c, NULL, 16);  		} @@ -361,9 +384,12 @@ static int jump__scnprintf(struct ins *ins, char *bf, size_t size,  		return scnprintf(bf, size, "%-6s %s", ins->name, ops->target.sym->name);  	c = strchr(ops->raw, ','); +	c = validate_comma(c, ops); +  	if (c != NULL) {  		const char *c2 = strchr(c + 1, ','); +		c2 = validate_comma(c2, ops);  		/* check for 3-op insn */  		if (c2 != NULL)  			c = c2;  |