aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r--tools/perf/util/session.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index fe87a2f2e5a5..ecd54bedfb1c 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -4,6 +4,7 @@
4#include <sys/types.h> 4#include <sys/types.h>
5 5
6#include "session.h" 6#include "session.h"
7#include "sort.h"
7#include "util.h" 8#include "util.h"
8 9
9static int perf_session__open(struct perf_session *self, bool force) 10static int perf_session__open(struct perf_session *self, bool force)
@@ -90,3 +91,61 @@ void perf_session__delete(struct perf_session *self)
90 free(self->cwd); 91 free(self->cwd);
91 free(self); 92 free(self);
92} 93}
94
95static bool symbol__match_parent_regex(struct symbol *sym)
96{
97 if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0))
98 return 1;
99
100 return 0;
101}
102
103struct symbol **perf_session__resolve_callchain(struct perf_session *self,
104 struct thread *thread,
105 struct ip_callchain *chain,
106 struct symbol **parent)
107{
108 u8 cpumode = PERF_RECORD_MISC_USER;
109 struct symbol **syms = NULL;
110 unsigned int i;
111
112 if (self->use_callchain) {
113 syms = calloc(chain->nr, sizeof(*syms));
114 if (!syms) {
115 fprintf(stderr, "Can't allocate memory for symbols\n");
116 exit(-1);
117 }
118 }
119
120 for (i = 0; i < chain->nr; i++) {
121 u64 ip = chain->ips[i];
122 struct addr_location al;
123
124 if (ip >= PERF_CONTEXT_MAX) {
125 switch (ip) {
126 case PERF_CONTEXT_HV:
127 cpumode = PERF_RECORD_MISC_HYPERVISOR; break;
128 case PERF_CONTEXT_KERNEL:
129 cpumode = PERF_RECORD_MISC_KERNEL; break;
130 case PERF_CONTEXT_USER:
131 cpumode = PERF_RECORD_MISC_USER; break;
132 default:
133 break;
134 }
135 continue;
136 }
137
138 thread__find_addr_location(thread, self, cpumode,
139 MAP__FUNCTION, ip, &al, NULL);
140 if (al.sym != NULL) {
141 if (sort__has_parent && !*parent &&
142 symbol__match_parent_regex(al.sym))
143 *parent = al.sym;
144 if (!self->use_callchain)
145 break;
146 syms[i] = al.sym;
147 }
148 }
149
150 return syms;
151}