From: Thomas Richter <tmri...@linux.vnet.ibm.com> [ Upstream commit 35a8a148d8c1ee9e5ae18f9565a880490f816f89 ]
The command 'perf annotate' parses the output of objdump and also investigates the comments produced by objdump. For example the output of objdump produces (on x86): 23eee: 4c 8b 3d 13 01 21 00 mov 0x210113(%rip),%r15 # 234008 <stderr@@GLIBC_2.2.5+0x9a8> and the function mov__parse() is called to investigate the complete line. Mov__parse() breaks this line into several parts and finally calls function comment__symbol() to parse the data after the comment character '#'. Comment__symbol() expects a hexadecimal address followed by a symbol in '<' and '>' brackets. However the 2nd parameter given to function comment__symbol() always points to the comment character '#'. The address parsing always returns 0 because the character '#' is not a digit and strtoull() fails without being noticed. Fix this by advancing the second parameter to function comment__symbol() by one byte before invocation and add an error check after strtoull() has been called. Signed-off-by: Thomas Richter <tmri...@linux.vnet.ibm.com> Reviewed-by: Hendrik Brueckner <brueck...@linux.vnet.ibm.com> Acked-by: Ravi Bangoria <ravi.bango...@linux.vnet.ibm.com> Cc: Heiko Carstens <heiko.carst...@de.ibm.com> Cc: Martin Schwidefsky <schwidef...@de.ibm.com> Fixes: 6de783b6f50f ("perf annotate: Resolve symbols using objdump comment") Link: http://lkml.kernel.org/r/20171128075632.72182-1-tmri...@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com> Signed-off-by: Sasha Levin <alexander.le...@microsoft.com> --- tools/perf/util/annotate.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 3369c7830260..6a631acf8bb7 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -322,6 +322,8 @@ static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep) return 0; *addrp = strtoull(comment, &endptr, 16); + if (endptr == comment) + return 0; name = strchr(endptr, '<'); if (name == NULL) return -1; @@ -435,8 +437,8 @@ static int mov__parse(struct arch *arch, struct ins_operands *ops, struct map *m return 0; comment = ltrim(comment); - comment__symbol(ops->source.raw, comment, &ops->source.addr, &ops->source.name); - comment__symbol(ops->target.raw, comment, &ops->target.addr, &ops->target.name); + comment__symbol(ops->source.raw, comment + 1, &ops->source.addr, &ops->source.name); + comment__symbol(ops->target.raw, comment + 1, &ops->target.addr, &ops->target.name); return 0; @@ -480,7 +482,7 @@ static int dec__parse(struct arch *arch __maybe_unused, struct ins_operands *ops return 0; comment = ltrim(comment); - comment__symbol(ops->target.raw, comment, &ops->target.addr, &ops->target.name); + comment__symbol(ops->target.raw, comment + 1, &ops->target.addr, &ops->target.name); return 0; } -- 2.14.1