diff options
author | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2013-11-08 15:28:05 -0500 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2013-11-08 15:28:05 -0500 |
commit | bad97817dece759dd6c0b24f862b7d0ed588edda (patch) | |
tree | fcabaa3ae3e2f17236135e60dc875f47e852cc6d /tools | |
parent | 6fe19278ffebdd57e5c5ec10275e6d423404364e (diff) | |
parent | 61e6cfa80de5760bbe406f4e815b7739205754d2 (diff) |
Merge tag 'v3.12-rc5' into stable/for-linus-3.13
Linux 3.12-rc5
Because the Stefano branch (for SWIOTLB ARM changes) is based on that.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
* tag 'v3.12-rc5': (550 commits)
Linux 3.12-rc5
watchdog: sunxi: Fix section mismatch
watchdog: kempld_wdt: Fix bit mask definition
watchdog: ts72xx_wdt: locking bug in ioctl
ARM: exynos: dts: Update 5250 arch timer node with clock frequency
parisc: let probe_kernel_read() capture access to page zero
parisc: optimize variable initialization in do_page_fault
parisc: fix interruption handler to respect pagefault_disable()
parisc: mark parisc_terminate() noreturn and cold.
parisc: remove unused syscall_ipi() function.
parisc: kill SMP single function call interrupt
parisc: Export flush_cache_page() (needed by lustre)
vfs: allow O_PATH file descriptors for fstatfs()
ext4: fix memory leak in xattr
ARC: Ignore ptrace SETREGSET request for synthetic register "stop_pc"
ALSA: hda - Sony VAIO Pro 13 (haswell) now has a working headset jack
ALSA: hda - Add a headset mic model for ALC269 and friends
ALSA: hda - Fix microphone for Sony VAIO Pro 13 (Haswell model)
compiler/gcc4: Add quirk for 'asm goto' miscompilation bug
Revert "i915: Update VGA arbiter support for newer devices"
...
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/Makefile | 1 | ||||
-rw-r--r-- | tools/perf/builtin-kmem.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-stat.c | 1 | ||||
-rw-r--r-- | tools/perf/builtin-trace.c | 1 | ||||
-rw-r--r-- | tools/perf/config/Makefile | 2 | ||||
-rw-r--r-- | tools/perf/config/feature-tests.mak | 2 | ||||
-rw-r--r-- | tools/perf/util/dwarf-aux.c | 25 | ||||
-rw-r--r-- | tools/perf/util/dwarf-aux.h | 6 | ||||
-rw-r--r-- | tools/perf/util/header.c | 12 | ||||
-rw-r--r-- | tools/perf/util/machine.c | 2 | ||||
-rw-r--r-- | tools/perf/util/probe-finder.c | 126 | ||||
-rw-r--r-- | tools/perf/util/probe-finder.h | 3 | ||||
-rw-r--r-- | tools/perf/util/session.c | 4 |
13 files changed, 125 insertions, 62 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 3a0ff7fb71b6..64c043b7a438 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
@@ -770,6 +770,7 @@ check: $(OUTPUT)common-cmds.h | |||
770 | install-bin: all | 770 | install-bin: all |
771 | $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' | 771 | $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' |
772 | $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)' | 772 | $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)' |
773 | $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' | ||
773 | $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' | 774 | $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' |
774 | ifndef NO_LIBPERL | 775 | ifndef NO_LIBPERL |
775 | $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace' | 776 | $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace' |
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index c2dff9cb1f2c..9b5f077fee5b 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c | |||
@@ -101,7 +101,7 @@ static int setup_cpunode_map(void) | |||
101 | 101 | ||
102 | dir1 = opendir(PATH_SYS_NODE); | 102 | dir1 = opendir(PATH_SYS_NODE); |
103 | if (!dir1) | 103 | if (!dir1) |
104 | return -1; | 104 | return 0; |
105 | 105 | ||
106 | while ((dent1 = readdir(dir1)) != NULL) { | 106 | while ((dent1 = readdir(dir1)) != NULL) { |
107 | if (dent1->d_type != DT_DIR || | 107 | if (dent1->d_type != DT_DIR || |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index f686d5ff594e..5098f144b92d 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -457,6 +457,7 @@ static int __run_perf_stat(int argc, const char **argv) | |||
457 | perror("failed to prepare workload"); | 457 | perror("failed to prepare workload"); |
458 | return -1; | 458 | return -1; |
459 | } | 459 | } |
460 | child_pid = evsel_list->workload.pid; | ||
460 | } | 461 | } |
461 | 462 | ||
462 | if (group) | 463 | if (group) |
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index fd4853404727..71aa3e35406b 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -1055,6 +1055,7 @@ static int trace__replay(struct trace *trace) | |||
1055 | 1055 | ||
1056 | trace->tool.sample = trace__process_sample; | 1056 | trace->tool.sample = trace__process_sample; |
1057 | trace->tool.mmap = perf_event__process_mmap; | 1057 | trace->tool.mmap = perf_event__process_mmap; |
1058 | trace->tool.mmap2 = perf_event__process_mmap2; | ||
1058 | trace->tool.comm = perf_event__process_comm; | 1059 | trace->tool.comm = perf_event__process_comm; |
1059 | trace->tool.exit = perf_event__process_exit; | 1060 | trace->tool.exit = perf_event__process_exit; |
1060 | trace->tool.fork = perf_event__process_fork; | 1061 | trace->tool.fork = perf_event__process_fork; |
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 346ee929d250..5f6f9b3271bb 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile | |||
@@ -87,7 +87,7 @@ CFLAGS += -Wall | |||
87 | CFLAGS += -Wextra | 87 | CFLAGS += -Wextra |
88 | CFLAGS += -std=gnu99 | 88 | CFLAGS += -std=gnu99 |
89 | 89 | ||
90 | EXTLIBS = -lelf -lpthread -lrt -lm | 90 | EXTLIBS = -lelf -lpthread -lrt -lm -ldl |
91 | 91 | ||
92 | ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y) | 92 | ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y) |
93 | CFLAGS += -fstack-protector-all | 93 | CFLAGS += -fstack-protector-all |
diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak index d5a8dd44945f..f79305739ecc 100644 --- a/tools/perf/config/feature-tests.mak +++ b/tools/perf/config/feature-tests.mak | |||
@@ -219,7 +219,7 @@ define SOURCE_LIBAUDIT | |||
219 | 219 | ||
220 | int main(void) | 220 | int main(void) |
221 | { | 221 | { |
222 | printf(\"error message: %s\n\", audit_errno_to_name(0)); | 222 | printf(\"error message: %s\", audit_errno_to_name(0)); |
223 | return audit_open(); | 223 | return audit_open(); |
224 | } | 224 | } |
225 | endef | 225 | endef |
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index e23bde19d590..7defd77105d0 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c | |||
@@ -426,7 +426,7 @@ static int __die_search_func_cb(Dwarf_Die *fn_die, void *data) | |||
426 | * @die_mem: a buffer for result DIE | 426 | * @die_mem: a buffer for result DIE |
427 | * | 427 | * |
428 | * Search a non-inlined function DIE which includes @addr. Stores the | 428 | * Search a non-inlined function DIE which includes @addr. Stores the |
429 | * DIE to @die_mem and returns it if found. Returns NULl if failed. | 429 | * DIE to @die_mem and returns it if found. Returns NULL if failed. |
430 | */ | 430 | */ |
431 | Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, | 431 | Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, |
432 | Dwarf_Die *die_mem) | 432 | Dwarf_Die *die_mem) |
@@ -454,15 +454,32 @@ static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data) | |||
454 | } | 454 | } |
455 | 455 | ||
456 | /** | 456 | /** |
457 | * die_find_top_inlinefunc - Search the top inlined function at given address | ||
458 | * @sp_die: a subprogram DIE which including @addr | ||
459 | * @addr: target address | ||
460 | * @die_mem: a buffer for result DIE | ||
461 | * | ||
462 | * Search an inlined function DIE which includes @addr. Stores the | ||
463 | * DIE to @die_mem and returns it if found. Returns NULL if failed. | ||
464 | * Even if several inlined functions are expanded recursively, this | ||
465 | * doesn't trace it down, and returns the topmost one. | ||
466 | */ | ||
467 | Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, | ||
468 | Dwarf_Die *die_mem) | ||
469 | { | ||
470 | return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem); | ||
471 | } | ||
472 | |||
473 | /** | ||
457 | * die_find_inlinefunc - Search an inlined function at given address | 474 | * die_find_inlinefunc - Search an inlined function at given address |
458 | * @cu_die: a CU DIE which including @addr | 475 | * @sp_die: a subprogram DIE which including @addr |
459 | * @addr: target address | 476 | * @addr: target address |
460 | * @die_mem: a buffer for result DIE | 477 | * @die_mem: a buffer for result DIE |
461 | * | 478 | * |
462 | * Search an inlined function DIE which includes @addr. Stores the | 479 | * Search an inlined function DIE which includes @addr. Stores the |
463 | * DIE to @die_mem and returns it if found. Returns NULl if failed. | 480 | * DIE to @die_mem and returns it if found. Returns NULL if failed. |
464 | * If several inlined functions are expanded recursively, this trace | 481 | * If several inlined functions are expanded recursively, this trace |
465 | * it and returns deepest one. | 482 | * it down and returns deepest one. |
466 | */ | 483 | */ |
467 | Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, | 484 | Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, |
468 | Dwarf_Die *die_mem) | 485 | Dwarf_Die *die_mem) |
diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h index 8658d41697d2..b4fe90c6cb2d 100644 --- a/tools/perf/util/dwarf-aux.h +++ b/tools/perf/util/dwarf-aux.h | |||
@@ -79,7 +79,11 @@ extern Dwarf_Die *die_find_child(Dwarf_Die *rt_die, | |||
79 | extern Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, | 79 | extern Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, |
80 | Dwarf_Die *die_mem); | 80 | Dwarf_Die *die_mem); |
81 | 81 | ||
82 | /* Search an inlined function including given address */ | 82 | /* Search the top inlined function including given address */ |
83 | extern Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, | ||
84 | Dwarf_Die *die_mem); | ||
85 | |||
86 | /* Search the deepest inlined function including given address */ | ||
83 | extern Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, | 87 | extern Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, |
84 | Dwarf_Die *die_mem); | 88 | Dwarf_Die *die_mem); |
85 | 89 | ||
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index ce69901176d8..c3e5a3b817ab 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -2768,6 +2768,18 @@ int perf_session__read_header(struct perf_session *session) | |||
2768 | if (perf_file_header__read(&f_header, header, fd) < 0) | 2768 | if (perf_file_header__read(&f_header, header, fd) < 0) |
2769 | return -EINVAL; | 2769 | return -EINVAL; |
2770 | 2770 | ||
2771 | /* | ||
2772 | * Sanity check that perf.data was written cleanly; data size is | ||
2773 | * initialized to 0 and updated only if the on_exit function is run. | ||
2774 | * If data size is still 0 then the file contains only partial | ||
2775 | * information. Just warn user and process it as much as it can. | ||
2776 | */ | ||
2777 | if (f_header.data.size == 0) { | ||
2778 | pr_warning("WARNING: The %s file's data size field is 0 which is unexpected.\n" | ||
2779 | "Was the 'perf record' command properly terminated?\n", | ||
2780 | session->filename); | ||
2781 | } | ||
2782 | |||
2771 | nr_attrs = f_header.attrs.size / f_header.attr_size; | 2783 | nr_attrs = f_header.attrs.size / f_header.attr_size; |
2772 | lseek(fd, f_header.attrs.offset, SEEK_SET); | 2784 | lseek(fd, f_header.attrs.offset, SEEK_SET); |
2773 | 2785 | ||
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 933d14f287ca..6188d2876a71 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -792,7 +792,7 @@ static int machine__create_modules(struct machine *machine) | |||
792 | modules = path; | 792 | modules = path; |
793 | } | 793 | } |
794 | 794 | ||
795 | if (symbol__restricted_filename(path, "/proc/modules")) | 795 | if (symbol__restricted_filename(modules, "/proc/modules")) |
796 | return -1; | 796 | return -1; |
797 | 797 | ||
798 | file = fopen(modules, "r"); | 798 | file = fopen(modules, "r"); |
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 20c7299a9d4e..c09e0a9fdf4c 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
@@ -118,7 +118,6 @@ static const Dwfl_Callbacks offline_callbacks = { | |||
118 | static int debuginfo__init_offline_dwarf(struct debuginfo *self, | 118 | static int debuginfo__init_offline_dwarf(struct debuginfo *self, |
119 | const char *path) | 119 | const char *path) |
120 | { | 120 | { |
121 | Dwfl_Module *mod; | ||
122 | int fd; | 121 | int fd; |
123 | 122 | ||
124 | fd = open(path, O_RDONLY); | 123 | fd = open(path, O_RDONLY); |
@@ -129,11 +128,11 @@ static int debuginfo__init_offline_dwarf(struct debuginfo *self, | |||
129 | if (!self->dwfl) | 128 | if (!self->dwfl) |
130 | goto error; | 129 | goto error; |
131 | 130 | ||
132 | mod = dwfl_report_offline(self->dwfl, "", "", fd); | 131 | self->mod = dwfl_report_offline(self->dwfl, "", "", fd); |
133 | if (!mod) | 132 | if (!self->mod) |
134 | goto error; | 133 | goto error; |
135 | 134 | ||
136 | self->dbg = dwfl_module_getdwarf(mod, &self->bias); | 135 | self->dbg = dwfl_module_getdwarf(self->mod, &self->bias); |
137 | if (!self->dbg) | 136 | if (!self->dbg) |
138 | goto error; | 137 | goto error; |
139 | 138 | ||
@@ -676,37 +675,42 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf) | |||
676 | } | 675 | } |
677 | 676 | ||
678 | /* Convert subprogram DIE to trace point */ | 677 | /* Convert subprogram DIE to trace point */ |
679 | static int convert_to_trace_point(Dwarf_Die *sp_die, Dwarf_Addr paddr, | 678 | static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod, |
680 | bool retprobe, struct probe_trace_point *tp) | 679 | Dwarf_Addr paddr, bool retprobe, |
680 | struct probe_trace_point *tp) | ||
681 | { | 681 | { |
682 | Dwarf_Addr eaddr, highaddr; | 682 | Dwarf_Addr eaddr, highaddr; |
683 | const char *name; | 683 | GElf_Sym sym; |
684 | 684 | const char *symbol; | |
685 | /* Copy the name of probe point */ | 685 | |
686 | name = dwarf_diename(sp_die); | 686 | /* Verify the address is correct */ |
687 | if (name) { | 687 | if (dwarf_entrypc(sp_die, &eaddr) != 0) { |
688 | if (dwarf_entrypc(sp_die, &eaddr) != 0) { | 688 | pr_warning("Failed to get entry address of %s\n", |
689 | pr_warning("Failed to get entry address of %s\n", | 689 | dwarf_diename(sp_die)); |
690 | dwarf_diename(sp_die)); | 690 | return -ENOENT; |
691 | return -ENOENT; | 691 | } |
692 | } | 692 | if (dwarf_highpc(sp_die, &highaddr) != 0) { |
693 | if (dwarf_highpc(sp_die, &highaddr) != 0) { | 693 | pr_warning("Failed to get end address of %s\n", |
694 | pr_warning("Failed to get end address of %s\n", | 694 | dwarf_diename(sp_die)); |
695 | dwarf_diename(sp_die)); | 695 | return -ENOENT; |
696 | return -ENOENT; | 696 | } |
697 | } | 697 | if (paddr > highaddr) { |
698 | if (paddr > highaddr) { | 698 | pr_warning("Offset specified is greater than size of %s\n", |
699 | pr_warning("Offset specified is greater than size of %s\n", | 699 | dwarf_diename(sp_die)); |
700 | dwarf_diename(sp_die)); | 700 | return -EINVAL; |
701 | return -EINVAL; | 701 | } |
702 | } | 702 | |
703 | tp->symbol = strdup(name); | 703 | /* Get an appropriate symbol from symtab */ |
704 | if (tp->symbol == NULL) | 704 | symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL); |
705 | return -ENOMEM; | 705 | if (!symbol) { |
706 | tp->offset = (unsigned long)(paddr - eaddr); | 706 | pr_warning("Failed to find symbol at 0x%lx\n", |
707 | } else | 707 | (unsigned long)paddr); |
708 | /* This function has no name. */ | 708 | return -ENOENT; |
709 | tp->offset = (unsigned long)paddr; | 709 | } |
710 | tp->offset = (unsigned long)(paddr - sym.st_value); | ||
711 | tp->symbol = strdup(symbol); | ||
712 | if (!tp->symbol) | ||
713 | return -ENOMEM; | ||
710 | 714 | ||
711 | /* Return probe must be on the head of a subprogram */ | 715 | /* Return probe must be on the head of a subprogram */ |
712 | if (retprobe) { | 716 | if (retprobe) { |
@@ -1149,7 +1153,7 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf) | |||
1149 | tev = &tf->tevs[tf->ntevs++]; | 1153 | tev = &tf->tevs[tf->ntevs++]; |
1150 | 1154 | ||
1151 | /* Trace point should be converted from subprogram DIE */ | 1155 | /* Trace point should be converted from subprogram DIE */ |
1152 | ret = convert_to_trace_point(&pf->sp_die, pf->addr, | 1156 | ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr, |
1153 | pf->pev->point.retprobe, &tev->point); | 1157 | pf->pev->point.retprobe, &tev->point); |
1154 | if (ret < 0) | 1158 | if (ret < 0) |
1155 | return ret; | 1159 | return ret; |
@@ -1181,7 +1185,7 @@ int debuginfo__find_trace_events(struct debuginfo *self, | |||
1181 | { | 1185 | { |
1182 | struct trace_event_finder tf = { | 1186 | struct trace_event_finder tf = { |
1183 | .pf = {.pev = pev, .callback = add_probe_trace_event}, | 1187 | .pf = {.pev = pev, .callback = add_probe_trace_event}, |
1184 | .max_tevs = max_tevs}; | 1188 | .mod = self->mod, .max_tevs = max_tevs}; |
1185 | int ret; | 1189 | int ret; |
1186 | 1190 | ||
1187 | /* Allocate result tevs array */ | 1191 | /* Allocate result tevs array */ |
@@ -1250,7 +1254,7 @@ static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf) | |||
1250 | vl = &af->vls[af->nvls++]; | 1254 | vl = &af->vls[af->nvls++]; |
1251 | 1255 | ||
1252 | /* Trace point should be converted from subprogram DIE */ | 1256 | /* Trace point should be converted from subprogram DIE */ |
1253 | ret = convert_to_trace_point(&pf->sp_die, pf->addr, | 1257 | ret = convert_to_trace_point(&pf->sp_die, af->mod, pf->addr, |
1254 | pf->pev->point.retprobe, &vl->point); | 1258 | pf->pev->point.retprobe, &vl->point); |
1255 | if (ret < 0) | 1259 | if (ret < 0) |
1256 | return ret; | 1260 | return ret; |
@@ -1289,6 +1293,7 @@ int debuginfo__find_available_vars_at(struct debuginfo *self, | |||
1289 | { | 1293 | { |
1290 | struct available_var_finder af = { | 1294 | struct available_var_finder af = { |
1291 | .pf = {.pev = pev, .callback = add_available_vars}, | 1295 | .pf = {.pev = pev, .callback = add_available_vars}, |
1296 | .mod = self->mod, | ||
1292 | .max_vls = max_vls, .externs = externs}; | 1297 | .max_vls = max_vls, .externs = externs}; |
1293 | int ret; | 1298 | int ret; |
1294 | 1299 | ||
@@ -1322,8 +1327,8 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr, | |||
1322 | struct perf_probe_point *ppt) | 1327 | struct perf_probe_point *ppt) |
1323 | { | 1328 | { |
1324 | Dwarf_Die cudie, spdie, indie; | 1329 | Dwarf_Die cudie, spdie, indie; |
1325 | Dwarf_Addr _addr, baseaddr; | 1330 | Dwarf_Addr _addr = 0, baseaddr = 0; |
1326 | const char *fname = NULL, *func = NULL, *tmp; | 1331 | const char *fname = NULL, *func = NULL, *basefunc = NULL, *tmp; |
1327 | int baseline = 0, lineno = 0, ret = 0; | 1332 | int baseline = 0, lineno = 0, ret = 0; |
1328 | 1333 | ||
1329 | /* Adjust address with bias */ | 1334 | /* Adjust address with bias */ |
@@ -1344,27 +1349,36 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr, | |||
1344 | /* Find a corresponding function (name, baseline and baseaddr) */ | 1349 | /* Find a corresponding function (name, baseline and baseaddr) */ |
1345 | if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) { | 1350 | if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) { |
1346 | /* Get function entry information */ | 1351 | /* Get function entry information */ |
1347 | tmp = dwarf_diename(&spdie); | 1352 | func = basefunc = dwarf_diename(&spdie); |
1348 | if (!tmp || | 1353 | if (!func || |
1349 | dwarf_entrypc(&spdie, &baseaddr) != 0 || | 1354 | dwarf_entrypc(&spdie, &baseaddr) != 0 || |
1350 | dwarf_decl_line(&spdie, &baseline) != 0) | 1355 | dwarf_decl_line(&spdie, &baseline) != 0) { |
1356 | lineno = 0; | ||
1351 | goto post; | 1357 | goto post; |
1352 | func = tmp; | 1358 | } |
1353 | 1359 | ||
1354 | if (addr == (unsigned long)baseaddr) | 1360 | if (addr == (unsigned long)baseaddr) { |
1355 | /* Function entry - Relative line number is 0 */ | 1361 | /* Function entry - Relative line number is 0 */ |
1356 | lineno = baseline; | 1362 | lineno = baseline; |
1357 | else if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr, | 1363 | fname = dwarf_decl_file(&spdie); |
1358 | &indie)) { | 1364 | goto post; |
1365 | } | ||
1366 | |||
1367 | /* Track down the inline functions step by step */ | ||
1368 | while (die_find_top_inlinefunc(&spdie, (Dwarf_Addr)addr, | ||
1369 | &indie)) { | ||
1370 | /* There is an inline function */ | ||
1359 | if (dwarf_entrypc(&indie, &_addr) == 0 && | 1371 | if (dwarf_entrypc(&indie, &_addr) == 0 && |
1360 | _addr == addr) | 1372 | _addr == addr) { |
1361 | /* | 1373 | /* |
1362 | * addr is at an inline function entry. | 1374 | * addr is at an inline function entry. |
1363 | * In this case, lineno should be the call-site | 1375 | * In this case, lineno should be the call-site |
1364 | * line number. | 1376 | * line number. (overwrite lineinfo) |
1365 | */ | 1377 | */ |
1366 | lineno = die_get_call_lineno(&indie); | 1378 | lineno = die_get_call_lineno(&indie); |
1367 | else { | 1379 | fname = die_get_call_file(&indie); |
1380 | break; | ||
1381 | } else { | ||
1368 | /* | 1382 | /* |
1369 | * addr is in an inline function body. | 1383 | * addr is in an inline function body. |
1370 | * Since lineno points one of the lines | 1384 | * Since lineno points one of the lines |
@@ -1372,19 +1386,27 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr, | |||
1372 | * be the entry line of the inline function. | 1386 | * be the entry line of the inline function. |
1373 | */ | 1387 | */ |
1374 | tmp = dwarf_diename(&indie); | 1388 | tmp = dwarf_diename(&indie); |
1375 | if (tmp && | 1389 | if (!tmp || |
1376 | dwarf_decl_line(&spdie, &baseline) == 0) | 1390 | dwarf_decl_line(&indie, &baseline) != 0) |
1377 | func = tmp; | 1391 | break; |
1392 | func = tmp; | ||
1393 | spdie = indie; | ||
1378 | } | 1394 | } |
1379 | } | 1395 | } |
1396 | /* Verify the lineno and baseline are in a same file */ | ||
1397 | tmp = dwarf_decl_file(&spdie); | ||
1398 | if (!tmp || strcmp(tmp, fname) != 0) | ||
1399 | lineno = 0; | ||
1380 | } | 1400 | } |
1381 | 1401 | ||
1382 | post: | 1402 | post: |
1383 | /* Make a relative line number or an offset */ | 1403 | /* Make a relative line number or an offset */ |
1384 | if (lineno) | 1404 | if (lineno) |
1385 | ppt->line = lineno - baseline; | 1405 | ppt->line = lineno - baseline; |
1386 | else if (func) | 1406 | else if (basefunc) { |
1387 | ppt->offset = addr - (unsigned long)baseaddr; | 1407 | ppt->offset = addr - (unsigned long)baseaddr; |
1408 | func = basefunc; | ||
1409 | } | ||
1388 | 1410 | ||
1389 | /* Duplicate strings */ | 1411 | /* Duplicate strings */ |
1390 | if (func) { | 1412 | if (func) { |
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h index 17e94d0c36f9..3b7d63018960 100644 --- a/tools/perf/util/probe-finder.h +++ b/tools/perf/util/probe-finder.h | |||
@@ -23,6 +23,7 @@ static inline int is_c_varname(const char *name) | |||
23 | /* debug information structure */ | 23 | /* debug information structure */ |
24 | struct debuginfo { | 24 | struct debuginfo { |
25 | Dwarf *dbg; | 25 | Dwarf *dbg; |
26 | Dwfl_Module *mod; | ||
26 | Dwfl *dwfl; | 27 | Dwfl *dwfl; |
27 | Dwarf_Addr bias; | 28 | Dwarf_Addr bias; |
28 | }; | 29 | }; |
@@ -77,6 +78,7 @@ struct probe_finder { | |||
77 | 78 | ||
78 | struct trace_event_finder { | 79 | struct trace_event_finder { |
79 | struct probe_finder pf; | 80 | struct probe_finder pf; |
81 | Dwfl_Module *mod; /* For solving symbols */ | ||
80 | struct probe_trace_event *tevs; /* Found trace events */ | 82 | struct probe_trace_event *tevs; /* Found trace events */ |
81 | int ntevs; /* Number of trace events */ | 83 | int ntevs; /* Number of trace events */ |
82 | int max_tevs; /* Max number of trace events */ | 84 | int max_tevs; /* Max number of trace events */ |
@@ -84,6 +86,7 @@ struct trace_event_finder { | |||
84 | 86 | ||
85 | struct available_var_finder { | 87 | struct available_var_finder { |
86 | struct probe_finder pf; | 88 | struct probe_finder pf; |
89 | Dwfl_Module *mod; /* For solving symbols */ | ||
87 | struct variable_list *vls; /* Found variable lists */ | 90 | struct variable_list *vls; /* Found variable lists */ |
88 | int nvls; /* Number of variable lists */ | 91 | int nvls; /* Number of variable lists */ |
89 | int max_vls; /* Max no. of variable lists */ | 92 | int max_vls; /* Max no. of variable lists */ |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 70ffa41518f3..568b750c01f6 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -256,6 +256,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) | |||
256 | tool->sample = process_event_sample_stub; | 256 | tool->sample = process_event_sample_stub; |
257 | if (tool->mmap == NULL) | 257 | if (tool->mmap == NULL) |
258 | tool->mmap = process_event_stub; | 258 | tool->mmap = process_event_stub; |
259 | if (tool->mmap2 == NULL) | ||
260 | tool->mmap2 = process_event_stub; | ||
259 | if (tool->comm == NULL) | 261 | if (tool->comm == NULL) |
260 | tool->comm = process_event_stub; | 262 | tool->comm = process_event_stub; |
261 | if (tool->fork == NULL) | 263 | if (tool->fork == NULL) |
@@ -1310,7 +1312,7 @@ int __perf_session__process_events(struct perf_session *session, | |||
1310 | file_offset = page_offset; | 1312 | file_offset = page_offset; |
1311 | head = data_offset - page_offset; | 1313 | head = data_offset - page_offset; |
1312 | 1314 | ||
1313 | if (data_offset + data_size < file_size) | 1315 | if (data_size && (data_offset + data_size < file_size)) |
1314 | file_size = data_offset + data_size; | 1316 | file_size = data_offset + data_size; |
1315 | 1317 | ||
1316 | progress_next = file_size / 16; | 1318 | progress_next = file_size / 16; |