aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/annotate.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2015-02-10 14:35:36 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2015-02-10 14:35:36 -0500
commit4ba24fef3eb3b142197135223b90ced2f319cd53 (patch)
treea20c125b27740ec7b4c761b11d801108e1b316b2 /tools/perf/util/annotate.c
parent47c1ffb2b6b630894e9a16442611c056ab21c057 (diff)
parent98a4a59ee31a12105a2b84f5b8b515ac2cb208ef (diff)
Merge branch 'next' into for-linus
Prepare first round of input updates for 3.20.
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r--tools/perf/util/annotate.c63
1 files changed, 44 insertions, 19 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 809b4c50beae..79999ceaf2be 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -17,11 +17,13 @@
17#include "debug.h" 17#include "debug.h"
18#include "annotate.h" 18#include "annotate.h"
19#include "evsel.h" 19#include "evsel.h"
20#include <regex.h>
20#include <pthread.h> 21#include <pthread.h>
21#include <linux/bitops.h> 22#include <linux/bitops.h>
22 23
23const char *disassembler_style; 24const char *disassembler_style;
24const char *objdump_path; 25const char *objdump_path;
26static regex_t file_lineno;
25 27
26static struct ins *ins__find(const char *name); 28static struct ins *ins__find(const char *name);
27static int disasm_line__parse(char *line, char **namep, char **rawp); 29static int disasm_line__parse(char *line, char **namep, char **rawp);
@@ -232,9 +234,16 @@ static int mov__parse(struct ins_operands *ops)
232 return -1; 234 return -1;
233 235
234 target = ++s; 236 target = ++s;
237 comment = strchr(s, '#');
235 238
236 while (s[0] != '\0' && !isspace(s[0])) 239 if (comment != NULL)
237 ++s; 240 s = comment - 1;
241 else
242 s = strchr(s, '\0') - 1;
243
244 while (s > target && isspace(s[0]))
245 --s;
246 s++;
238 prev = *s; 247 prev = *s;
239 *s = '\0'; 248 *s = '\0';
240 249
@@ -244,7 +253,6 @@ static int mov__parse(struct ins_operands *ops)
244 if (ops->target.raw == NULL) 253 if (ops->target.raw == NULL)
245 goto out_free_source; 254 goto out_free_source;
246 255
247 comment = strchr(s, '#');
248 if (comment == NULL) 256 if (comment == NULL)
249 return 0; 257 return 0;
250 258
@@ -472,7 +480,7 @@ static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map,
472 480
473 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); 481 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr));
474 482
475 if (addr < sym->start || addr > sym->end) 483 if (addr < sym->start || addr >= sym->end)
476 return -ERANGE; 484 return -ERANGE;
477 485
478 offset = addr - sym->start; 486 offset = addr - sym->start;
@@ -564,13 +572,15 @@ out_free_name:
564 return -1; 572 return -1;
565} 573}
566 574
567static struct disasm_line *disasm_line__new(s64 offset, char *line, size_t privsize) 575static struct disasm_line *disasm_line__new(s64 offset, char *line,
576 size_t privsize, int line_nr)
568{ 577{
569 struct disasm_line *dl = zalloc(sizeof(*dl) + privsize); 578 struct disasm_line *dl = zalloc(sizeof(*dl) + privsize);
570 579
571 if (dl != NULL) { 580 if (dl != NULL) {
572 dl->offset = offset; 581 dl->offset = offset;
573 dl->line = strdup(line); 582 dl->line = strdup(line);
583 dl->line_nr = line_nr;
574 if (dl->line == NULL) 584 if (dl->line == NULL)
575 goto out_delete; 585 goto out_delete;
576 586
@@ -782,13 +792,15 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st
782 * The ops.raw part will be parsed further according to type of the instruction. 792 * The ops.raw part will be parsed further according to type of the instruction.
783 */ 793 */
784static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, 794static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
785 FILE *file, size_t privsize) 795 FILE *file, size_t privsize,
796 int *line_nr)
786{ 797{
787 struct annotation *notes = symbol__annotation(sym); 798 struct annotation *notes = symbol__annotation(sym);
788 struct disasm_line *dl; 799 struct disasm_line *dl;
789 char *line = NULL, *parsed_line, *tmp, *tmp2, *c; 800 char *line = NULL, *parsed_line, *tmp, *tmp2, *c;
790 size_t line_len; 801 size_t line_len;
791 s64 line_ip, offset = -1; 802 s64 line_ip, offset = -1;
803 regmatch_t match[2];
792 804
793 if (getline(&line, &line_len, file) < 0) 805 if (getline(&line, &line_len, file) < 0)
794 return -1; 806 return -1;
@@ -806,6 +818,12 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
806 line_ip = -1; 818 line_ip = -1;
807 parsed_line = line; 819 parsed_line = line;
808 820
821 /* /filename:linenr ? Save line number and ignore. */
822 if (regexec(&file_lineno, line, 2, match, 0) == 0) {
823 *line_nr = atoi(line + match[1].rm_so);
824 return 0;
825 }
826
809 /* 827 /*
810 * Strip leading spaces: 828 * Strip leading spaces:
811 */ 829 */
@@ -830,14 +848,15 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
830 end = map__rip_2objdump(map, sym->end); 848 end = map__rip_2objdump(map, sym->end);
831 849
832 offset = line_ip - start; 850 offset = line_ip - start;
833 if ((u64)line_ip < start || (u64)line_ip > end) 851 if ((u64)line_ip < start || (u64)line_ip >= end)
834 offset = -1; 852 offset = -1;
835 else 853 else
836 parsed_line = tmp2 + 1; 854 parsed_line = tmp2 + 1;
837 } 855 }
838 856
839 dl = disasm_line__new(offset, parsed_line, privsize); 857 dl = disasm_line__new(offset, parsed_line, privsize, *line_nr);
840 free(line); 858 free(line);
859 (*line_nr)++;
841 860
842 if (dl == NULL) 861 if (dl == NULL)
843 return -1; 862 return -1;
@@ -863,6 +882,11 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
863 return 0; 882 return 0;
864} 883}
865 884
885static __attribute__((constructor)) void symbol__init_regexpr(void)
886{
887 regcomp(&file_lineno, "^/[^:]+:([0-9]+)", REG_EXTENDED);
888}
889
866static void delete_last_nop(struct symbol *sym) 890static void delete_last_nop(struct symbol *sym)
867{ 891{
868 struct annotation *notes = symbol__annotation(sym); 892 struct annotation *notes = symbol__annotation(sym);
@@ -898,11 +922,10 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
898 char symfs_filename[PATH_MAX]; 922 char symfs_filename[PATH_MAX];
899 struct kcore_extract kce; 923 struct kcore_extract kce;
900 bool delete_extract = false; 924 bool delete_extract = false;
925 int lineno = 0;
901 926
902 if (filename) { 927 if (filename)
903 snprintf(symfs_filename, sizeof(symfs_filename), "%s%s", 928 symbol__join_symfs(symfs_filename, filename);
904 symbol_conf.symfs, filename);
905 }
906 929
907 if (filename == NULL) { 930 if (filename == NULL) {
908 if (dso->has_build_id) { 931 if (dso->has_build_id) {
@@ -911,6 +934,8 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
911 return -ENOMEM; 934 return -ENOMEM;
912 } 935 }
913 goto fallback; 936 goto fallback;
937 } else if (dso__is_kcore(dso)) {
938 goto fallback;
914 } else if (readlink(symfs_filename, command, sizeof(command)) < 0 || 939 } else if (readlink(symfs_filename, command, sizeof(command)) < 0 ||
915 strstr(command, "[kernel.kallsyms]") || 940 strstr(command, "[kernel.kallsyms]") ||
916 access(symfs_filename, R_OK)) { 941 access(symfs_filename, R_OK)) {
@@ -922,8 +947,7 @@ fallback:
922 * DSO is the same as when 'perf record' ran. 947 * DSO is the same as when 'perf record' ran.
923 */ 948 */
924 filename = (char *)dso->long_name; 949 filename = (char *)dso->long_name;
925 snprintf(symfs_filename, sizeof(symfs_filename), "%s%s", 950 symbol__join_symfs(symfs_filename, filename);
926 symbol_conf.symfs, filename);
927 free_filename = false; 951 free_filename = false;
928 } 952 }
929 953
@@ -963,7 +987,7 @@ fallback:
963 kce.kcore_filename = symfs_filename; 987 kce.kcore_filename = symfs_filename;
964 kce.addr = map__rip_2objdump(map, sym->start); 988 kce.addr = map__rip_2objdump(map, sym->start);
965 kce.offs = sym->start; 989 kce.offs = sym->start;
966 kce.len = sym->end + 1 - sym->start; 990 kce.len = sym->end - sym->start;
967 if (!kcore_extract__create(&kce)) { 991 if (!kcore_extract__create(&kce)) {
968 delete_extract = true; 992 delete_extract = true;
969 strlcpy(symfs_filename, kce.extract_filename, 993 strlcpy(symfs_filename, kce.extract_filename,
@@ -979,12 +1003,12 @@ fallback:
979 snprintf(command, sizeof(command), 1003 snprintf(command, sizeof(command),
980 "%s %s%s --start-address=0x%016" PRIx64 1004 "%s %s%s --start-address=0x%016" PRIx64
981 " --stop-address=0x%016" PRIx64 1005 " --stop-address=0x%016" PRIx64
982 " -d %s %s -C %s 2>/dev/null|grep -v %s|expand", 1006 " -l -d %s %s -C %s 2>/dev/null|grep -v %s|expand",
983 objdump_path ? objdump_path : "objdump", 1007 objdump_path ? objdump_path : "objdump",
984 disassembler_style ? "-M " : "", 1008 disassembler_style ? "-M " : "",
985 disassembler_style ? disassembler_style : "", 1009 disassembler_style ? disassembler_style : "",
986 map__rip_2objdump(map, sym->start), 1010 map__rip_2objdump(map, sym->start),
987 map__rip_2objdump(map, sym->end+1), 1011 map__rip_2objdump(map, sym->end),
988 symbol_conf.annotate_asm_raw ? "" : "--no-show-raw", 1012 symbol_conf.annotate_asm_raw ? "" : "--no-show-raw",
989 symbol_conf.annotate_src ? "-S" : "", 1013 symbol_conf.annotate_src ? "-S" : "",
990 symfs_filename, filename); 1014 symfs_filename, filename);
@@ -996,7 +1020,8 @@ fallback:
996 goto out_free_filename; 1020 goto out_free_filename;
997 1021
998 while (!feof(file)) 1022 while (!feof(file))
999 if (symbol__parse_objdump_line(sym, map, file, privsize) < 0) 1023 if (symbol__parse_objdump_line(sym, map, file, privsize,
1024 &lineno) < 0)
1000 break; 1025 break;
1001 1026
1002 /* 1027 /*
@@ -1167,7 +1192,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
1167 goto next; 1192 goto next;
1168 1193
1169 offset = start + i; 1194 offset = start + i;
1170 src_line->path = get_srcline(map->dso, offset); 1195 src_line->path = get_srcline(map->dso, offset, NULL, false);
1171 insert_source_line(&tmp_root, src_line); 1196 insert_source_line(&tmp_root, src_line);
1172 1197
1173 next: 1198 next: