1 #include <linux/kernel.h>
10 static int perf_session__open(struct perf_session
*self
, bool force
)
12 struct stat input_stat
;
14 self
->fd
= open(self
->filename
, O_RDONLY
);
16 pr_err("failed to open file: %s", self
->filename
);
17 if (!strcmp(self
->filename
, "perf.data"))
18 pr_err(" (try 'perf record' first)");
23 if (fstat(self
->fd
, &input_stat
) < 0)
26 if (!force
&& input_stat
.st_uid
&& (input_stat
.st_uid
!= geteuid())) {
27 pr_err("file %s not owned by current user or root\n",
32 if (!input_stat
.st_size
) {
33 pr_info("zero-sized file (%s), nothing to do!\n",
38 if (perf_header__read(&self
->header
, self
->fd
) < 0) {
39 pr_err("incompatible file format");
43 self
->size
= input_stat
.st_size
;
52 struct perf_session
*perf_session__new(const char *filename
, int mode
, bool force
)
54 size_t len
= filename
? strlen(filename
) + 1 : 0;
55 struct perf_session
*self
= zalloc(sizeof(*self
) + len
);
60 if (perf_header__init(&self
->header
) < 0)
63 memcpy(self
->filename
, filename
, len
);
64 self
->threads
= RB_ROOT
;
65 self
->last_match
= NULL
;
66 self
->mmap_window
= 32;
69 map_groups__init(&self
->kmaps
);
71 if (perf_session__create_kernel_maps(self
) < 0)
74 if (mode
== O_RDONLY
&& perf_session__open(self
, force
) < 0)
82 perf_session__delete(self
);
86 void perf_session__delete(struct perf_session
*self
)
88 perf_header__exit(&self
->header
);
94 static bool symbol__match_parent_regex(struct symbol
*sym
)
96 if (sym
->name
&& !regexec(&parent_regex
, sym
->name
, 0, NULL
, 0))
102 struct symbol
**perf_session__resolve_callchain(struct perf_session
*self
,
103 struct thread
*thread
,
104 struct ip_callchain
*chain
,
105 struct symbol
**parent
)
107 u8 cpumode
= PERF_RECORD_MISC_USER
;
108 struct symbol
**syms
= NULL
;
111 if (symbol_conf
.use_callchain
) {
112 syms
= calloc(chain
->nr
, sizeof(*syms
));
114 fprintf(stderr
, "Can't allocate memory for symbols\n");
119 for (i
= 0; i
< chain
->nr
; i
++) {
120 u64 ip
= chain
->ips
[i
];
121 struct addr_location al
;
123 if (ip
>= PERF_CONTEXT_MAX
) {
125 case PERF_CONTEXT_HV
:
126 cpumode
= PERF_RECORD_MISC_HYPERVISOR
; break;
127 case PERF_CONTEXT_KERNEL
:
128 cpumode
= PERF_RECORD_MISC_KERNEL
; break;
129 case PERF_CONTEXT_USER
:
130 cpumode
= PERF_RECORD_MISC_USER
; break;
137 thread__find_addr_location(thread
, self
, cpumode
,
138 MAP__FUNCTION
, ip
, &al
, NULL
);
139 if (al
.sym
!= NULL
) {
140 if (sort__has_parent
&& !*parent
&&
141 symbol__match_parent_regex(al
.sym
))
143 if (!symbol_conf
.use_callchain
)