event.c 23.8 KB
Newer Older
1
#include <linux/types.h>
2
#include <sys/mman.h>
3 4
#include "event.h"
#include "debug.h"
5
#include "hist.h"
6
#include "machine.h"
7
#include "sort.h"
8
#include "string.h"
9
#include "strlist.h"
10
#include "thread.h"
11
#include "thread_map.h"
12
#include "symbol/kallsyms.h"
13

14
static const char *perf_event__names[] = {
15 16
	[0]					= "TOTAL",
	[PERF_RECORD_MMAP]			= "MMAP",
17
	[PERF_RECORD_MMAP2]			= "MMAP2",
18 19 20 21 22 23 24 25 26 27 28 29 30
	[PERF_RECORD_LOST]			= "LOST",
	[PERF_RECORD_COMM]			= "COMM",
	[PERF_RECORD_EXIT]			= "EXIT",
	[PERF_RECORD_THROTTLE]			= "THROTTLE",
	[PERF_RECORD_UNTHROTTLE]		= "UNTHROTTLE",
	[PERF_RECORD_FORK]			= "FORK",
	[PERF_RECORD_READ]			= "READ",
	[PERF_RECORD_SAMPLE]			= "SAMPLE",
	[PERF_RECORD_HEADER_ATTR]		= "ATTR",
	[PERF_RECORD_HEADER_EVENT_TYPE]		= "EVENT_TYPE",
	[PERF_RECORD_HEADER_TRACING_DATA]	= "TRACING_DATA",
	[PERF_RECORD_HEADER_BUILD_ID]		= "BUILD_ID",
	[PERF_RECORD_FINISHED_ROUND]		= "FINISHED_ROUND",
A
Adrian Hunter 已提交
31
	[PERF_RECORD_ID_INDEX]			= "ID_INDEX",
32 33
};

34
const char *perf_event__name(unsigned int id)
35
{
36
	if (id >= ARRAY_SIZE(perf_event__names))
37
		return "INVALID";
38
	if (!perf_event__names[id])
39
		return "UNKNOWN";
40
	return perf_event__names[id];
41 42
}

43
static struct perf_sample synth_sample = {
44 45 46 47 48 49 50 51
	.pid	   = -1,
	.tid	   = -1,
	.time	   = -1,
	.stream_id = -1,
	.cpu	   = -1,
	.period	   = 1,
};

52 53 54 55
/*
 * Assumes that the first 4095 bytes of /proc/pid/stat contains
 * the comm and tgid.
 */
56
static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len)
57 58
{
	char filename[PATH_MAX];
59 60 61
	char bf[4096];
	int fd;
	size_t size = 0, n;
62
	pid_t tgid = -1;
63
	char *nl, *name, *tgids;
64 65 66

	snprintf(filename, sizeof(filename), "/proc/%d/status", pid);

67 68
	fd = open(filename, O_RDONLY);
	if (fd < 0) {
69 70 71 72
		pr_debug("couldn't open %s\n", filename);
		return 0;
	}

73 74 75 76 77 78
	n = read(fd, bf, sizeof(bf) - 1);
	close(fd);
	if (n <= 0) {
		pr_warning("Couldn't get COMM and tgid for pid %d\n",
			   pid);
		return -1;
79
	}
80
	bf[n] = '\0';
81

82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
	name = strstr(bf, "Name:");
	tgids = strstr(bf, "Tgid:");

	if (name) {
		name += 5;  /* strlen("Name:") */

		while (*name && isspace(*name))
			++name;

		nl = strchr(name, '\n');
		if (nl)
			*nl = '\0';

		size = strlen(name);
		if (size >= len)
			size = len - 1;
		memcpy(comm, name, size);
		comm[size] = '\0';
	} else {
		pr_debug("Name: string not found for pid %d\n", pid);
	}

	if (tgids) {
		tgids += 5;  /* strlen("Tgid:") */
		tgid = atoi(tgids);
	} else {
		pr_debug("Tgid: string not found for pid %d\n", pid);
	}
110 111 112 113

	return tgid;
}

114
static pid_t perf_event__prepare_comm(union perf_event *event, pid_t pid,
115 116 117 118 119 120 121
					 struct machine *machine)
{
	size_t size;
	pid_t tgid;

	memset(&event->comm, 0, sizeof(event->comm));

122 123 124 125 126 127
	if (machine__is_host(machine))
		tgid = perf_event__get_comm_tgid(pid, event->comm.comm,
						 sizeof(event->comm.comm));
	else
		tgid = machine->pid;

128 129 130 131
	if (tgid < 0)
		goto out;

	event->comm.pid = tgid;
132
	event->comm.header.type = PERF_RECORD_COMM;
133 134

	size = strlen(event->comm.comm) + 1;
135
	size = PERF_ALIGN(size, sizeof(u64));
136
	memset(event->comm.comm + size, 0, machine->id_hdr_size);
137 138
	event->comm.header.size = (sizeof(event->comm) -
				(sizeof(event->comm.comm) - size) +
139
				machine->id_hdr_size);
140
	event->comm.tid = pid;
141 142 143 144 145 146 147 148 149 150 151 152 153
out:
	return tgid;
}

static pid_t perf_event__synthesize_comm(struct perf_tool *tool,
					 union perf_event *event, pid_t pid,
					 perf_event__handler_t process,
					 struct machine *machine)
{
	pid_t tgid = perf_event__prepare_comm(event, pid, machine);

	if (tgid == -1)
		goto out;
154

155 156
	if (process(tool, event, &synth_sample, machine) != 0)
		return -1;
157

158 159
out:
	return tgid;
160 161
}

162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
static int perf_event__synthesize_fork(struct perf_tool *tool,
				       union perf_event *event, pid_t pid,
				       pid_t tgid, perf_event__handler_t process,
				       struct machine *machine)
{
	memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size);

	event->fork.ppid = tgid;
	event->fork.ptid = tgid;
	event->fork.pid  = tgid;
	event->fork.tid  = pid;
	event->fork.header.type = PERF_RECORD_FORK;

	event->fork.header.size = (sizeof(event->fork) + machine->id_hdr_size);

	if (process(tool, event, &synth_sample, machine) != 0)
		return -1;

	return 0;
}

183 184 185 186 187 188
int perf_event__synthesize_mmap_events(struct perf_tool *tool,
				       union perf_event *event,
				       pid_t pid, pid_t tgid,
				       perf_event__handler_t process,
				       struct machine *machine,
				       bool mmap_data)
189 190 191
{
	char filename[PATH_MAX];
	FILE *fp;
192
	int rc = 0;
193

194 195 196
	if (machine__is_default_guest(machine))
		return 0;

197 198
	snprintf(filename, sizeof(filename), "%s/proc/%d/maps",
		 machine->root_dir, pid);
199 200 201 202 203 204 205 206 207 208

	fp = fopen(filename, "r");
	if (fp == NULL) {
		/*
		 * We raced with a task exiting - just return:
		 */
		pr_debug("couldn't open %s\n", filename);
		return -1;
	}

209
	event->header.type = PERF_RECORD_MMAP2;
210

211
	while (1) {
212 213 214 215
		char bf[BUFSIZ];
		char prot[5];
		char execname[PATH_MAX];
		char anonstr[] = "//anon";
216
		unsigned int ino;
217
		size_t size;
218
		ssize_t n;
219

220 221 222
		if (fgets(bf, sizeof(bf), fp) == NULL)
			break;

223 224 225
		/* ensure null termination since stack will be reused. */
		strcpy(execname, "");

226
		/* 00400000-0040c000 r-xp 00000000 fd:01 41038  /bin/cat */
227 228 229 230 231 232
		n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %x:%x %u %s\n",
		       &event->mmap2.start, &event->mmap2.len, prot,
		       &event->mmap2.pgoff, &event->mmap2.maj,
		       &event->mmap2.min,
		       &ino, execname);

233 234 235
		/*
 		 * Anon maps don't have the execname.
 		 */
236
		if (n < 7)
237
			continue;
238 239 240

		event->mmap2.ino = (u64)ino;

241 242 243
		/*
		 * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c
		 */
244 245 246 247
		if (machine__is_host(machine))
			event->header.misc = PERF_RECORD_MISC_USER;
		else
			event->header.misc = PERF_RECORD_MISC_GUEST_USER;
248

249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
		/* map protection and flags bits */
		event->mmap2.prot = 0;
		event->mmap2.flags = 0;
		if (prot[0] == 'r')
			event->mmap2.prot |= PROT_READ;
		if (prot[1] == 'w')
			event->mmap2.prot |= PROT_WRITE;
		if (prot[2] == 'x')
			event->mmap2.prot |= PROT_EXEC;

		if (prot[3] == 's')
			event->mmap2.flags |= MAP_SHARED;
		else
			event->mmap2.flags |= MAP_PRIVATE;

264 265 266 267 268 269
		if (prot[2] != 'x') {
			if (!mmap_data || prot[0] != 'r')
				continue;

			event->header.misc |= PERF_RECORD_MISC_MMAP_DATA;
		}
270 271 272 273 274

		if (!strcmp(execname, ""))
			strcpy(execname, anonstr);

		size = strlen(execname) + 1;
275
		memcpy(event->mmap2.filename, execname, size);
276
		size = PERF_ALIGN(size, sizeof(u64));
277 278 279 280 281 282 283
		event->mmap2.len -= event->mmap.start;
		event->mmap2.header.size = (sizeof(event->mmap2) -
					(sizeof(event->mmap2.filename) - size));
		memset(event->mmap2.filename + size, 0, machine->id_hdr_size);
		event->mmap2.header.size += machine->id_hdr_size;
		event->mmap2.pid = tgid;
		event->mmap2.tid = pid;
284 285 286 287

		if (process(tool, event, &synth_sample, machine) != 0) {
			rc = -1;
			break;
288 289 290 291
		}
	}

	fclose(fp);
292
	return rc;
293 294
}

295
int perf_event__synthesize_modules(struct perf_tool *tool,
296
				   perf_event__handler_t process,
297
				   struct machine *machine)
298
{
299
	int rc = 0;
300
	struct rb_node *nd;
301
	struct map_groups *kmaps = &machine->kmaps;
302
	union perf_event *event = zalloc((sizeof(event->mmap) +
303
					  machine->id_hdr_size));
304 305 306 307 308 309 310
	if (event == NULL) {
		pr_debug("Not enough memory synthesizing mmap event "
			 "for kernel modules\n");
		return -1;
	}

	event->header.type = PERF_RECORD_MMAP;
311

312 313 314 315
	/*
	 * kernel uses 0 for user space maps, see kernel/perf_event.c
	 * __perf_event_mmap
	 */
316
	if (machine__is_host(machine))
317
		event->header.misc = PERF_RECORD_MISC_KERNEL;
318
	else
319
		event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL;
320 321

	for (nd = rb_first(&kmaps->maps[MAP__FUNCTION]);
322 323 324 325 326 327 328
	     nd; nd = rb_next(nd)) {
		size_t size;
		struct map *pos = rb_entry(nd, struct map, rb_node);

		if (pos->dso->kernel)
			continue;

329
		size = PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64));
330 331 332
		event->mmap.header.type = PERF_RECORD_MMAP;
		event->mmap.header.size = (sizeof(event->mmap) -
				        (sizeof(event->mmap.filename) - size));
333 334
		memset(event->mmap.filename + size, 0, machine->id_hdr_size);
		event->mmap.header.size += machine->id_hdr_size;
335 336 337 338 339
		event->mmap.start = pos->start;
		event->mmap.len   = pos->end - pos->start;
		event->mmap.pid   = machine->pid;

		memcpy(event->mmap.filename, pos->dso->long_name,
340
		       pos->dso->long_name_len + 1);
341 342 343 344
		if (process(tool, event, &synth_sample, machine) != 0) {
			rc = -1;
			break;
		}
345 346
	}

347
	free(event);
348
	return rc;
349 350
}

351 352
static int __event__synthesize_thread(union perf_event *comm_event,
				      union perf_event *mmap_event,
353
				      union perf_event *fork_event,
354 355
				      pid_t pid, int full,
					  perf_event__handler_t process,
356
				      struct perf_tool *tool,
357
				      struct machine *machine, bool mmap_data)
358
{
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
	char filename[PATH_MAX];
	DIR *tasks;
	struct dirent dirent, *next;
	pid_t tgid;

	/* special case: only send one comm event using passed in pid */
	if (!full) {
		tgid = perf_event__synthesize_comm(tool, comm_event, pid,
						   process, machine);

		if (tgid == -1)
			return -1;

		return perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
							  process, machine, mmap_data);
	}

	if (machine__is_default_guest(machine))
		return 0;

	snprintf(filename, sizeof(filename), "%s/proc/%d/task",
		 machine->root_dir, pid);

	tasks = opendir(filename);
	if (tasks == NULL) {
		pr_debug("couldn't open %s\n", filename);
		return 0;
	}

	while (!readdir_r(tasks, &dirent, &next) && next) {
		char *end;
		int rc = 0;
		pid_t _pid;

		_pid = strtol(dirent.d_name, &end, 10);
		if (*end)
			continue;

397
		tgid = perf_event__prepare_comm(comm_event, _pid, machine);
398 399 400
		if (tgid == -1)
			return -1;

401 402 403 404 405 406 407 408 409
		if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid,
						process, machine) < 0)
			return -1;
		/*
		 * Send the prepared comm event
		 */
		if (process(tool, comm_event, &synth_sample, machine) != 0)
			return -1;

410 411 412 413 414
		if (_pid == pid) {
			/* process the parent's maps too */
			rc = perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
						process, machine, mmap_data);
		}
415 416 417 418 419 420 421

		if (rc)
			return rc;
	}

	closedir(tasks);
	return 0;
422 423
}

424
int perf_event__synthesize_thread_map(struct perf_tool *tool,
425
				      struct thread_map *threads,
426
				      perf_event__handler_t process,
427 428
				      struct machine *machine,
				      bool mmap_data)
429
{
430
	union perf_event *comm_event, *mmap_event, *fork_event;
431
	int err = -1, thread, j;
432

433
	comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size);
434 435 436
	if (comm_event == NULL)
		goto out;

437
	mmap_event = malloc(sizeof(mmap_event->mmap) + machine->id_hdr_size);
438 439 440
	if (mmap_event == NULL)
		goto out_free_comm;

441 442 443 444
	fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size);
	if (fork_event == NULL)
		goto out_free_mmap;

445 446 447
	err = 0;
	for (thread = 0; thread < threads->nr; ++thread) {
		if (__event__synthesize_thread(comm_event, mmap_event,
448
					       fork_event,
449
					       threads->map[thread], 0,
450 451
					       process, tool, machine,
					       mmap_data)) {
452 453 454
			err = -1;
			break;
		}
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472

		/*
		 * comm.pid is set to thread group id by
		 * perf_event__synthesize_comm
		 */
		if ((int) comm_event->comm.pid != threads->map[thread]) {
			bool need_leader = true;

			/* is thread group leader in thread_map? */
			for (j = 0; j < threads->nr; ++j) {
				if ((int) comm_event->comm.pid == threads->map[j]) {
					need_leader = false;
					break;
				}
			}

			/* if not, generate events for it */
			if (need_leader &&
473
			    __event__synthesize_thread(comm_event, mmap_event,
474
						       fork_event,
475 476 477
						       comm_event->comm.pid, 0,
						       process, tool, machine,
						       mmap_data)) {
478 479 480 481
				err = -1;
				break;
			}
		}
482
	}
483 484
	free(fork_event);
out_free_mmap:
485 486 487 488 489 490 491
	free(mmap_event);
out_free_comm:
	free(comm_event);
out:
	return err;
}

492
int perf_event__synthesize_threads(struct perf_tool *tool,
493
				   perf_event__handler_t process,
494
				   struct machine *machine, bool mmap_data)
495 496
{
	DIR *proc;
497
	char proc_path[PATH_MAX];
498
	struct dirent dirent, *next;
499
	union perf_event *comm_event, *mmap_event, *fork_event;
500 501
	int err = -1;

502 503 504
	if (machine__is_default_guest(machine))
		return 0;

505
	comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size);
506 507 508
	if (comm_event == NULL)
		goto out;

509
	mmap_event = malloc(sizeof(mmap_event->mmap) + machine->id_hdr_size);
510 511
	if (mmap_event == NULL)
		goto out_free_comm;
512

513 514 515 516
	fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size);
	if (fork_event == NULL)
		goto out_free_mmap;

517 518 519
	snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir);
	proc = opendir(proc_path);

520
	if (proc == NULL)
521
		goto out_free_fork;
522 523 524 525 526 527 528

	while (!readdir_r(proc, &dirent, &next) && next) {
		char *end;
		pid_t pid = strtol(dirent.d_name, &end, 10);

		if (*end) /* only interested in proper numerical dirents */
			continue;
529 530 531 532
		/*
 		 * We may race with exiting thread, so don't stop just because
 		 * one thread couldn't be synthesized.
 		 */
533 534
		__event__synthesize_thread(comm_event, mmap_event, fork_event, pid,
					   1, process, tool, machine, mmap_data);
535 536
	}

537
	err = 0;
538
	closedir(proc);
539 540
out_free_fork:
	free(fork_event);
541 542 543 544 545 546
out_free_mmap:
	free(mmap_event);
out_free_comm:
	free(comm_event);
out:
	return err;
547
}
548

549 550 551 552 553
struct process_symbol_args {
	const char *name;
	u64	   start;
};

554
static int find_symbol_cb(void *arg, const char *name, char type,
555
			  u64 start)
556 557 558
{
	struct process_symbol_args *args = arg;

559 560 561 562 563 564
	/*
	 * Must be a function or at least an alias, as in PARISC64, where "_text" is
	 * an 'A' to the same address as "_stext".
	 */
	if (!(symbol_type__is_a(type, MAP__FUNCTION) ||
	      type == 'A') || strcmp(name, args->name))
565 566 567 568 569 570
		return 0;

	args->start = start;
	return 1;
}

571 572 573 574 575 576 577 578 579 580 581
u64 kallsyms__get_function_start(const char *kallsyms_filename,
				 const char *symbol_name)
{
	struct process_symbol_args args = { .name = symbol_name, };

	if (kallsyms__parse(kallsyms_filename, &args, find_symbol_cb) <= 0)
		return 0;

	return args.start;
}

582
int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
583
				       perf_event__handler_t process,
584
				       struct machine *machine)
585 586
{
	size_t size;
587
	const char *mmap_name;
588 589
	char name_buff[PATH_MAX];
	struct map *map;
590
	struct kmap *kmap;
591
	int err;
592 593 594 595 596
	union perf_event *event;

	if (machine->vmlinux_maps[0] == NULL)
		return -1;

597 598 599 600 601
	/*
	 * We should get this from /sys/kernel/sections/.text, but till that is
	 * available use this, and after it is use this as a fallback for older
	 * kernels.
	 */
602
	event = zalloc((sizeof(event->mmap) + machine->id_hdr_size));
603 604 605 606 607
	if (event == NULL) {
		pr_debug("Not enough memory synthesizing mmap event "
			 "for kernel modules\n");
		return -1;
	}
608

609
	mmap_name = machine__mmap_name(machine, name_buff, sizeof(name_buff));
610
	if (machine__is_host(machine)) {
611 612 613 614
		/*
		 * kernel uses PERF_RECORD_MISC_USER for user space maps,
		 * see kernel/perf_event.c __perf_event_mmap
		 */
615
		event->header.misc = PERF_RECORD_MISC_KERNEL;
616
	} else {
617
		event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL;
618
	}
619

620
	map = machine->vmlinux_maps[MAP__FUNCTION];
621
	kmap = map__kmap(map);
622
	size = snprintf(event->mmap.filename, sizeof(event->mmap.filename),
623
			"%s%s", mmap_name, kmap->ref_reloc_sym->name) + 1;
624
	size = PERF_ALIGN(size, sizeof(u64));
625 626
	event->mmap.header.type = PERF_RECORD_MMAP;
	event->mmap.header.size = (sizeof(event->mmap) -
627
			(sizeof(event->mmap.filename) - size) + machine->id_hdr_size);
628
	event->mmap.pgoff = kmap->ref_reloc_sym->addr;
629 630 631 632
	event->mmap.start = map->start;
	event->mmap.len   = map->end - event->mmap.start;
	event->mmap.pid   = machine->pid;

633
	err = process(tool, event, &synth_sample, machine);
634 635 636
	free(event);

	return err;
637 638
}

639 640
size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp)
{
641 642 643 644 645 646 647
	const char *s;

	if (event->header.misc & PERF_RECORD_MISC_COMM_EXEC)
		s = " exec";
	else
		s = "";

648
	return fprintf(fp, "%s: %s:%d/%d\n", s, event->comm.comm, event->comm.pid, event->comm.tid);
649 650
}

651
int perf_event__process_comm(struct perf_tool *tool __maybe_unused,
652
			     union perf_event *event,
653
			     struct perf_sample *sample,
654
			     struct machine *machine)
655
{
656
	return machine__process_comm_event(machine, event, sample);
657 658
}

659
int perf_event__process_lost(struct perf_tool *tool __maybe_unused,
660
			     union perf_event *event,
661
			     struct perf_sample *sample,
662
			     struct machine *machine)
663
{
664
	return machine__process_lost_event(machine, event, sample);
665
}
666

667 668
size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp)
{
669
	return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %c %s\n",
670
		       event->mmap.pid, event->mmap.tid, event->mmap.start,
671 672 673
		       event->mmap.len, event->mmap.pgoff,
		       (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x',
		       event->mmap.filename);
674 675
}

676 677 678
size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp)
{
	return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64
679
			   " %02x:%02x %"PRIu64" %"PRIu64"]: %c%c%c%c %s\n",
680 681 682 683
		       event->mmap2.pid, event->mmap2.tid, event->mmap2.start,
		       event->mmap2.len, event->mmap2.pgoff, event->mmap2.maj,
		       event->mmap2.min, event->mmap2.ino,
		       event->mmap2.ino_generation,
684 685 686 687
		       (event->mmap2.prot & PROT_READ) ? 'r' : '-',
		       (event->mmap2.prot & PROT_WRITE) ? 'w' : '-',
		       (event->mmap2.prot & PROT_EXEC) ? 'x' : '-',
		       (event->mmap2.flags & MAP_SHARED) ? 's' : 'p',
688 689 690
		       event->mmap2.filename);
}

691
int perf_event__process_mmap(struct perf_tool *tool __maybe_unused,
692
			     union perf_event *event,
693
			     struct perf_sample *sample,
694
			     struct machine *machine)
695
{
696
	return machine__process_mmap_event(machine, event, sample);
697 698
}

699 700
int perf_event__process_mmap2(struct perf_tool *tool __maybe_unused,
			     union perf_event *event,
701
			     struct perf_sample *sample,
702 703
			     struct machine *machine)
{
704
	return machine__process_mmap2_event(machine, event, sample);
705 706
}

707 708 709 710 711 712 713
size_t perf_event__fprintf_task(union perf_event *event, FILE *fp)
{
	return fprintf(fp, "(%d:%d):(%d:%d)\n",
		       event->fork.pid, event->fork.tid,
		       event->fork.ppid, event->fork.ptid);
}

714
int perf_event__process_fork(struct perf_tool *tool __maybe_unused,
715
			     union perf_event *event,
716
			     struct perf_sample *sample,
717
			     struct machine *machine)
718
{
719
	return machine__process_fork_event(machine, event, sample);
720
}
721

722 723
int perf_event__process_exit(struct perf_tool *tool __maybe_unused,
			     union perf_event *event,
724
			     struct perf_sample *sample,
725 726
			     struct machine *machine)
{
727
	return machine__process_exit_event(machine, event, sample);
728 729
}

730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745
size_t perf_event__fprintf(union perf_event *event, FILE *fp)
{
	size_t ret = fprintf(fp, "PERF_RECORD_%s",
			     perf_event__name(event->header.type));

	switch (event->header.type) {
	case PERF_RECORD_COMM:
		ret += perf_event__fprintf_comm(event, fp);
		break;
	case PERF_RECORD_FORK:
	case PERF_RECORD_EXIT:
		ret += perf_event__fprintf_task(event, fp);
		break;
	case PERF_RECORD_MMAP:
		ret += perf_event__fprintf_mmap(event, fp);
		break;
746 747 748
	case PERF_RECORD_MMAP2:
		ret += perf_event__fprintf_mmap2(event, fp);
		break;
749 750 751 752 753 754 755
	default:
		ret += fprintf(fp, "\n");
	}

	return ret;
}

756 757
int perf_event__process(struct perf_tool *tool __maybe_unused,
			union perf_event *event,
758
			struct perf_sample *sample,
759
			struct machine *machine)
760
{
761
	return machine__process_event(machine, event, sample);
762 763
}

764
void thread__find_addr_map(struct thread *thread, u8 cpumode,
765
			   enum map_type type, u64 addr,
766
			   struct addr_location *al)
767
{
768
	struct map_groups *mg = thread->mg;
769
	struct machine *machine = mg->machine;
770
	bool load_map = false;
771

772
	al->machine = machine;
773
	al->thread = thread;
774
	al->addr = addr;
775
	al->cpumode = cpumode;
776
	al->filtered = 0;
777

778 779 780 781 782
	if (machine == NULL) {
		al->map = NULL;
		return;
	}

783
	if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) {
784
		al->level = 'k';
785
		mg = &machine->kmaps;
786
		load_map = true;
787
	} else if (cpumode == PERF_RECORD_MISC_USER && perf_host) {
788
		al->level = '.';
789 790
	} else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) {
		al->level = 'g';
791
		mg = &machine->kmaps;
792
		load_map = true;
793 794
	} else if (cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest) {
		al->level = 'u';
795
	} else {
796
		al->level = 'H';
797
		al->map = NULL;
798 799 800 801

		if ((cpumode == PERF_RECORD_MISC_GUEST_USER ||
			cpumode == PERF_RECORD_MISC_GUEST_KERNEL) &&
			!perf_guest)
802
			al->filtered |= (1 << HIST_FILTER__GUEST);
803 804 805
		if ((cpumode == PERF_RECORD_MISC_USER ||
			cpumode == PERF_RECORD_MISC_KERNEL) &&
			!perf_host)
806
			al->filtered |= (1 << HIST_FILTER__HOST);
807

808 809 810
		return;
	}
try_again:
811
	al->map = map_groups__find(mg, type, al->addr);
812 813 814 815 816 817 818 819 820 821
	if (al->map == NULL) {
		/*
		 * If this is outside of all known maps, and is a negative
		 * address, try to look it up in the kernel dso, as it might be
		 * a vsyscall or vdso (which executes in user-mode).
		 *
		 * XXX This is nasty, we should have a symbol list in the
		 * "[vdso]" dso, but for now lets use the old trick of looking
		 * in the whole kernel symbol list.
		 */
822 823 824
		if (cpumode == PERF_RECORD_MISC_USER && machine &&
		    mg != &machine->kmaps &&
		    machine__kernel_ip(machine, al->addr)) {
825
			mg = &machine->kmaps;
826
			load_map = true;
827 828
			goto try_again;
		}
829 830 831 832 833 834
	} else {
		/*
		 * Kernel maps might be changed when loading symbols so loading
		 * must be done prior to using kernel maps.
		 */
		if (load_map)
835
			map__load(al->map, machine->symbol_filter);
836
		al->addr = al->map->map_ip(al->map, al->addr);
837
	}
838 839
}

840
void thread__find_addr_location(struct thread *thread,
841
				u8 cpumode, enum map_type type, u64 addr,
842
				struct addr_location *al)
843
{
844
	thread__find_addr_map(thread, cpumode, type, addr, al);
845
	if (al->map != NULL)
846
		al->sym = map__find_symbol(al->map, al->addr,
847
					   thread->mg->machine->symbol_filter);
848 849
	else
		al->sym = NULL;
850 851
}

852
int perf_event__preprocess_sample(const union perf_event *event,
853
				  struct machine *machine,
854
				  struct addr_location *al,
855
				  struct perf_sample *sample)
856
{
857
	u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
858
	struct thread *thread = machine__findnew_thread(machine, sample->pid,
859
							sample->tid);
860

861 862 863
	if (thread == NULL)
		return -1;

864
	dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid);
865
	/*
866
	 * Have we already created the kernel maps for this machine?
867 868 869 870 871 872
	 *
	 * This should have happened earlier, when we processed the kernel MMAP
	 * events, but for older perf.data files there was no such thing, so do
	 * it now.
	 */
	if (cpumode == PERF_RECORD_MISC_KERNEL &&
873 874
	    machine->vmlinux_maps[MAP__FUNCTION] == NULL)
		machine__create_kernel_maps(machine);
875

876
	thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->ip, al);
877 878 879
	dump_printf(" ...... dso: %s\n",
		    al->map ? al->map->dso->long_name :
			al->level == 'H' ? "[hypervisor]" : "<not found>");
880 881 882 883

	if (thread__is_filtered(thread))
		al->filtered |= (1 << HIST_FILTER__THREAD);

884
	al->sym = NULL;
885
	al->cpu = sample->cpu;
886 887

	if (al->map) {
888 889
		struct dso *dso = al->map->dso;

890
		if (symbol_conf.dso_list &&
891 892 893 894
		    (!dso || !(strlist__has_entry(symbol_conf.dso_list,
						  dso->short_name) ||
			       (dso->short_name != dso->long_name &&
				strlist__has_entry(symbol_conf.dso_list,
895 896 897
						   dso->long_name))))) {
			al->filtered |= (1 << HIST_FILTER__DSO);
		}
898

899 900
		al->sym = map__find_symbol(al->map, al->addr,
					   machine->symbol_filter);
901
	}
902

903 904
	if (symbol_conf.sym_list &&
		(!al->sym || !strlist__has_entry(symbol_conf.sym_list,
905 906 907
						al->sym->name))) {
		al->filtered |= (1 << HIST_FILTER__SYMBOL);
	}
908 909

	return 0;
910
}
911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939

bool is_bts_event(struct perf_event_attr *attr)
{
	return attr->type == PERF_TYPE_HARDWARE &&
	       (attr->config & PERF_COUNT_HW_BRANCH_INSTRUCTIONS) &&
	       attr->sample_period == 1;
}

bool sample_addr_correlates_sym(struct perf_event_attr *attr)
{
	if (attr->type == PERF_TYPE_SOFTWARE &&
	    (attr->config == PERF_COUNT_SW_PAGE_FAULTS ||
	     attr->config == PERF_COUNT_SW_PAGE_FAULTS_MIN ||
	     attr->config == PERF_COUNT_SW_PAGE_FAULTS_MAJ))
		return true;

	if (is_bts_event(attr))
		return true;

	return false;
}

void perf_event__preprocess_sample_addr(union perf_event *event,
					struct perf_sample *sample,
					struct thread *thread,
					struct addr_location *al)
{
	u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;

940
	thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->addr, al);
941
	if (!al->map)
942
		thread__find_addr_map(thread, cpumode, MAP__VARIABLE,
943 944 945 946 947 948 949 950
				      sample->addr, al);

	al->cpu = sample->cpu;
	al->sym = NULL;

	if (al->map)
		al->sym = map__find_symbol(al->map, al->addr, NULL);
}