perf annotate: Fix objdump comment parsing for Intel mov dissassembly
authorThomas Richter <tmricht@linux.vnet.ibm.com>
Tue, 28 Nov 2017 07:56:32 +0000 (08:56 +0100)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 5 Dec 2017 13:24:30 +0000 (10:24 -0300)
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 <tmricht@linux.vnet.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Acked-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Fixes: 6de783b6f50f ("perf annotate: Resolve symbols using objdump comment")
Link: http://lkml.kernel.org/r/20171128075632.72182-1-tmricht@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/annotate.c

index 22ea793..facad1e 100644 (file)
@@ -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;
 }