event.c 29.2 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
	[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",
26
	[PERF_RECORD_AUX]			= "AUX",
27
	[PERF_RECORD_ITRACE_START]		= "ITRACE_START",
28
	[PERF_RECORD_LOST_SAMPLES]		= "LOST_SAMPLES",
29 30
	[PERF_RECORD_SWITCH]			= "SWITCH",
	[PERF_RECORD_SWITCH_CPU_WIDE]		= "SWITCH_CPU_WIDE",
31 32 33 34 35
	[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 已提交
36
	[PERF_RECORD_ID_INDEX]			= "ID_INDEX",
37 38
	[PERF_RECORD_AUXTRACE_INFO]		= "AUXTRACE_INFO",
	[PERF_RECORD_AUXTRACE]			= "AUXTRACE",
39
	[PERF_RECORD_AUXTRACE_ERROR]		= "AUXTRACE_ERROR",
40
	[PERF_RECORD_THREAD_MAP]		= "THREAD_MAP",
41 42
};

43
const char *perf_event__name(unsigned int id)
44
{
45
	if (id >= ARRAY_SIZE(perf_event__names))
46
		return "INVALID";
47
	if (!perf_event__names[id])
48
		return "UNKNOWN";
49
	return perf_event__names[id];
50 51
}

52
static struct perf_sample synth_sample = {
53 54 55 56 57 58 59 60
	.pid	   = -1,
	.tid	   = -1,
	.time	   = -1,
	.stream_id = -1,
	.cpu	   = -1,
	.period	   = 1,
};

61 62
/*
 * Assumes that the first 4095 bytes of /proc/pid/stat contains
63
 * the comm, tgid and ppid.
64
 */
65 66
static int perf_event__get_comm_ids(pid_t pid, char *comm, size_t len,
				    pid_t *tgid, pid_t *ppid)
67 68
{
	char filename[PATH_MAX];
69 70
	char bf[4096];
	int fd;
71 72
	size_t size = 0;
	ssize_t n;
73 74 75 76
	char *nl, *name, *tgids, *ppids;

	*tgid = -1;
	*ppid = -1;
77 78 79

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

80 81
	fd = open(filename, O_RDONLY);
	if (fd < 0) {
82
		pr_debug("couldn't open %s\n", filename);
83
		return -1;
84 85
	}

86 87 88
	n = read(fd, bf, sizeof(bf) - 1);
	close(fd);
	if (n <= 0) {
89
		pr_warning("Couldn't get COMM, tigd and ppid for pid %d\n",
90 91
			   pid);
		return -1;
92
	}
93
	bf[n] = '\0';
94

95 96
	name = strstr(bf, "Name:");
	tgids = strstr(bf, "Tgid:");
97
	ppids = strstr(bf, "PPid:");
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119

	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:") */
120
		*tgid = atoi(tgids);
121 122 123
	} else {
		pr_debug("Tgid: string not found for pid %d\n", pid);
	}
124

125 126 127 128 129 130 131 132
	if (ppids) {
		ppids += 5;  /* strlen("PPid:") */
		*ppid = atoi(ppids);
	} else {
		pr_debug("PPid: string not found for pid %d\n", pid);
	}

	return 0;
133 134
}

135 136 137
static int perf_event__prepare_comm(union perf_event *event, pid_t pid,
				    struct machine *machine,
				    pid_t *tgid, pid_t *ppid)
138 139
{
	size_t size;
140 141

	*ppid = -1;
142 143 144

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

145 146 147 148 149 150 151 152 153
	if (machine__is_host(machine)) {
		if (perf_event__get_comm_ids(pid, event->comm.comm,
					     sizeof(event->comm.comm),
					     tgid, ppid) != 0) {
			return -1;
		}
	} else {
		*tgid = machine->pid;
	}
154

155 156
	if (*tgid < 0)
		return -1;
157

158
	event->comm.pid = *tgid;
159
	event->comm.header.type = PERF_RECORD_COMM;
160 161

	size = strlen(event->comm.comm) + 1;
162
	size = PERF_ALIGN(size, sizeof(u64));
163
	memset(event->comm.comm + size, 0, machine->id_hdr_size);
164 165
	event->comm.header.size = (sizeof(event->comm) -
				(sizeof(event->comm.comm) - size) +
166
				machine->id_hdr_size);
167
	event->comm.tid = pid;
168 169

	return 0;
170 171
}

172
pid_t perf_event__synthesize_comm(struct perf_tool *tool,
173 174 175 176
					 union perf_event *event, pid_t pid,
					 perf_event__handler_t process,
					 struct machine *machine)
{
177
	pid_t tgid, ppid;
178

179 180
	if (perf_event__prepare_comm(event, pid, machine, &tgid, &ppid) != 0)
		return -1;
181

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

185
	return tgid;
186 187
}

188
static int perf_event__synthesize_fork(struct perf_tool *tool,
189 190 191
				       union perf_event *event,
				       pid_t pid, pid_t tgid, pid_t ppid,
				       perf_event__handler_t process,
192 193 194 195
				       struct machine *machine)
{
	memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size);

196 197 198 199 200 201 202 203 204 205 206 207
	/*
	 * for main thread set parent to ppid from status file. For other
	 * threads set parent pid to main thread. ie., assume main thread
	 * spawns all threads in a process
	*/
	if (tgid == pid) {
		event->fork.ppid = ppid;
		event->fork.ptid = ppid;
	} else {
		event->fork.ppid = tgid;
		event->fork.ptid = tgid;
	}
208 209 210 211 212 213 214 215 216 217 218 219
	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;
}

220 221 222 223 224
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,
225 226
				       bool mmap_data,
				       unsigned int proc_map_timeout)
227 228 229
{
	char filename[PATH_MAX];
	FILE *fp;
230 231
	unsigned long long t;
	bool truncation = false;
232
	unsigned long long timeout = proc_map_timeout * 1000000ULL;
233
	int rc = 0;
234

235 236 237
	if (machine__is_default_guest(machine))
		return 0;

238 239
	snprintf(filename, sizeof(filename), "%s/proc/%d/maps",
		 machine->root_dir, pid);
240 241 242 243 244 245 246 247 248 249

	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;
	}

250
	event->header.type = PERF_RECORD_MMAP2;
251
	t = rdclock();
252

253
	while (1) {
254 255 256 257
		char bf[BUFSIZ];
		char prot[5];
		char execname[PATH_MAX];
		char anonstr[] = "//anon";
258
		unsigned int ino;
259
		size_t size;
260
		ssize_t n;
261

262 263 264
		if (fgets(bf, sizeof(bf), fp) == NULL)
			break;

265 266 267 268 269
		if ((rdclock() - t) > timeout) {
			pr_warning("Reading %s time out. "
				   "You may want to increase "
				   "the time limit by --proc-map-timeout\n",
				   filename);
270 271 272 273
			truncation = true;
			goto out;
		}

274 275 276
		/* ensure null termination since stack will be reused. */
		strcpy(execname, "");

277
		/* 00400000-0040c000 r-xp 00000000 fd:01 41038  /bin/cat */
278 279 280 281 282 283
		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);

284 285 286
		/*
 		 * Anon maps don't have the execname.
 		 */
287
		if (n < 7)
288
			continue;
289 290 291

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

292 293 294
		/*
		 * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c
		 */
295 296 297 298
		if (machine__is_host(machine))
			event->header.misc = PERF_RECORD_MISC_USER;
		else
			event->header.misc = PERF_RECORD_MISC_GUEST_USER;
299

300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
		/* 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;

315 316 317 318 319 320
		if (prot[2] != 'x') {
			if (!mmap_data || prot[0] != 'r')
				continue;

			event->header.misc |= PERF_RECORD_MISC_MMAP_DATA;
		}
321

322 323 324 325
out:
		if (truncation)
			event->header.misc |= PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT;

326 327 328 329
		if (!strcmp(execname, ""))
			strcpy(execname, anonstr);

		size = strlen(execname) + 1;
330
		memcpy(event->mmap2.filename, execname, size);
331
		size = PERF_ALIGN(size, sizeof(u64));
332 333 334 335 336 337 338
		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;
339 340 341 342

		if (process(tool, event, &synth_sample, machine) != 0) {
			rc = -1;
			break;
343
		}
344 345 346

		if (truncation)
			break;
347 348 349
	}

	fclose(fp);
350
	return rc;
351 352
}

353
int perf_event__synthesize_modules(struct perf_tool *tool,
354
				   perf_event__handler_t process,
355
				   struct machine *machine)
356
{
357
	int rc = 0;
358
	struct map *pos;
359
	struct map_groups *kmaps = &machine->kmaps;
360
	struct maps *maps = &kmaps->maps[MAP__FUNCTION];
361
	union perf_event *event = zalloc((sizeof(event->mmap) +
362
					  machine->id_hdr_size));
363 364 365 366 367 368 369
	if (event == NULL) {
		pr_debug("Not enough memory synthesizing mmap event "
			 "for kernel modules\n");
		return -1;
	}

	event->header.type = PERF_RECORD_MMAP;
370

371 372 373 374
	/*
	 * kernel uses 0 for user space maps, see kernel/perf_event.c
	 * __perf_event_mmap
	 */
375
	if (machine__is_host(machine))
376
		event->header.misc = PERF_RECORD_MISC_KERNEL;
377
	else
378
		event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL;
379

380
	for (pos = maps__first(maps); pos; pos = map__next(pos)) {
381 382
		size_t size;

383
		if (__map__is_kernel(pos))
384 385
			continue;

386
		size = PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64));
387 388 389
		event->mmap.header.type = PERF_RECORD_MMAP;
		event->mmap.header.size = (sizeof(event->mmap) -
				        (sizeof(event->mmap.filename) - size));
390 391
		memset(event->mmap.filename + size, 0, machine->id_hdr_size);
		event->mmap.header.size += machine->id_hdr_size;
392 393 394 395 396
		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,
397
		       pos->dso->long_name_len + 1);
398 399 400 401
		if (process(tool, event, &synth_sample, machine) != 0) {
			rc = -1;
			break;
		}
402 403
	}

404
	free(event);
405
	return rc;
406 407
}

408 409
static int __event__synthesize_thread(union perf_event *comm_event,
				      union perf_event *mmap_event,
410
				      union perf_event *fork_event,
411 412
				      pid_t pid, int full,
					  perf_event__handler_t process,
413
				      struct perf_tool *tool,
414 415 416
				      struct machine *machine,
				      bool mmap_data,
				      unsigned int proc_map_timeout)
417
{
418 419 420
	char filename[PATH_MAX];
	DIR *tasks;
	struct dirent dirent, *next;
421
	pid_t tgid, ppid;
422
	int rc = 0;
423 424 425 426 427 428 429 430 431 432

	/* 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,
433 434
							  process, machine, mmap_data,
							  proc_map_timeout);
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
	}

	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;
		pid_t _pid;

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

457
		rc = -1;
458 459
		if (perf_event__prepare_comm(comm_event, _pid, machine,
					     &tgid, &ppid) != 0)
460
			break;
461

462
		if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid,
463
						ppid, process, machine) < 0)
464
			break;
465 466 467 468
		/*
		 * Send the prepared comm event
		 */
		if (process(tool, comm_event, &synth_sample, machine) != 0)
469
			break;
470

471
		rc = 0;
472 473 474
		if (_pid == pid) {
			/* process the parent's maps too */
			rc = perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
475
						process, machine, mmap_data, proc_map_timeout);
476 477
			if (rc)
				break;
478
		}
479 480 481
	}

	closedir(tasks);
482
	return rc;
483 484
}

485
int perf_event__synthesize_thread_map(struct perf_tool *tool,
486
				      struct thread_map *threads,
487
				      perf_event__handler_t process,
488
				      struct machine *machine,
489 490
				      bool mmap_data,
				      unsigned int proc_map_timeout)
491
{
492
	union perf_event *comm_event, *mmap_event, *fork_event;
493
	int err = -1, thread, j;
494

495
	comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size);
496 497 498
	if (comm_event == NULL)
		goto out;

499
	mmap_event = malloc(sizeof(mmap_event->mmap) + machine->id_hdr_size);
500 501 502
	if (mmap_event == NULL)
		goto out_free_comm;

503 504 505 506
	fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size);
	if (fork_event == NULL)
		goto out_free_mmap;

507 508 509
	err = 0;
	for (thread = 0; thread < threads->nr; ++thread) {
		if (__event__synthesize_thread(comm_event, mmap_event,
510
					       fork_event,
511
					       thread_map__pid(threads, thread), 0,
512
					       process, tool, machine,
513
					       mmap_data, proc_map_timeout)) {
514 515 516
			err = -1;
			break;
		}
517 518 519 520 521

		/*
		 * comm.pid is set to thread group id by
		 * perf_event__synthesize_comm
		 */
522
		if ((int) comm_event->comm.pid != thread_map__pid(threads, thread)) {
523 524 525 526
			bool need_leader = true;

			/* is thread group leader in thread_map? */
			for (j = 0; j < threads->nr; ++j) {
527
				if ((int) comm_event->comm.pid == thread_map__pid(threads, j)) {
528 529 530 531 532 533 534
					need_leader = false;
					break;
				}
			}

			/* if not, generate events for it */
			if (need_leader &&
535
			    __event__synthesize_thread(comm_event, mmap_event,
536
						       fork_event,
537 538
						       comm_event->comm.pid, 0,
						       process, tool, machine,
539
						       mmap_data, proc_map_timeout)) {
540 541 542 543
				err = -1;
				break;
			}
		}
544
	}
545 546
	free(fork_event);
out_free_mmap:
547 548 549 550 551 552 553
	free(mmap_event);
out_free_comm:
	free(comm_event);
out:
	return err;
}

554
int perf_event__synthesize_threads(struct perf_tool *tool,
555
				   perf_event__handler_t process,
556 557 558
				   struct machine *machine,
				   bool mmap_data,
				   unsigned int proc_map_timeout)
559 560
{
	DIR *proc;
561
	char proc_path[PATH_MAX];
562
	struct dirent dirent, *next;
563
	union perf_event *comm_event, *mmap_event, *fork_event;
564 565
	int err = -1;

566 567 568
	if (machine__is_default_guest(machine))
		return 0;

569
	comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size);
570 571 572
	if (comm_event == NULL)
		goto out;

573
	mmap_event = malloc(sizeof(mmap_event->mmap) + machine->id_hdr_size);
574 575
	if (mmap_event == NULL)
		goto out_free_comm;
576

577 578 579 580
	fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size);
	if (fork_event == NULL)
		goto out_free_mmap;

581 582 583
	snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir);
	proc = opendir(proc_path);

584
	if (proc == NULL)
585
		goto out_free_fork;
586 587 588 589 590 591 592

	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;
593 594 595 596
		/*
 		 * We may race with exiting thread, so don't stop just because
 		 * one thread couldn't be synthesized.
 		 */
597
		__event__synthesize_thread(comm_event, mmap_event, fork_event, pid,
598 599
					   1, process, tool, machine, mmap_data,
					   proc_map_timeout);
600 601
	}

602
	err = 0;
603
	closedir(proc);
604 605
out_free_fork:
	free(fork_event);
606 607 608 609 610 611
out_free_mmap:
	free(mmap_event);
out_free_comm:
	free(comm_event);
out:
	return err;
612
}
613

614 615 616 617 618
struct process_symbol_args {
	const char *name;
	u64	   start;
};

619
static int find_symbol_cb(void *arg, const char *name, char type,
620
			  u64 start)
621 622 623
{
	struct process_symbol_args *args = arg;

624 625 626 627 628 629
	/*
	 * 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))
630 631 632 633 634 635
		return 0;

	args->start = start;
	return 1;
}

636 637 638 639 640 641 642 643 644 645 646
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;
}

647
int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
648
				       perf_event__handler_t process,
649
				       struct machine *machine)
650 651
{
	size_t size;
652
	const char *mmap_name;
653
	char name_buff[PATH_MAX];
654
	struct map *map = machine__kernel_map(machine);
655
	struct kmap *kmap;
656
	int err;
657 658
	union perf_event *event;

659
	if (map == NULL)
660 661
		return -1;

662 663 664 665 666
	/*
	 * 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.
	 */
667
	event = zalloc((sizeof(event->mmap) + machine->id_hdr_size));
668 669 670 671 672
	if (event == NULL) {
		pr_debug("Not enough memory synthesizing mmap event "
			 "for kernel modules\n");
		return -1;
	}
673

674
	mmap_name = machine__mmap_name(machine, name_buff, sizeof(name_buff));
675
	if (machine__is_host(machine)) {
676 677 678 679
		/*
		 * kernel uses PERF_RECORD_MISC_USER for user space maps,
		 * see kernel/perf_event.c __perf_event_mmap
		 */
680
		event->header.misc = PERF_RECORD_MISC_KERNEL;
681
	} else {
682
		event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL;
683
	}
684

685
	kmap = map__kmap(map);
686
	size = snprintf(event->mmap.filename, sizeof(event->mmap.filename),
687
			"%s%s", mmap_name, kmap->ref_reloc_sym->name) + 1;
688
	size = PERF_ALIGN(size, sizeof(u64));
689 690
	event->mmap.header.type = PERF_RECORD_MMAP;
	event->mmap.header.size = (sizeof(event->mmap) -
691
			(sizeof(event->mmap.filename) - size) + machine->id_hdr_size);
692
	event->mmap.pgoff = kmap->ref_reloc_sym->addr;
693 694 695 696
	event->mmap.start = map->start;
	event->mmap.len   = map->end - event->mmap.start;
	event->mmap.pid   = machine->pid;

697
	err = process(tool, event, &synth_sample, machine);
698 699 700
	free(event);

	return err;
701 702
}

703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738
int perf_event__synthesize_thread_map2(struct perf_tool *tool,
				      struct thread_map *threads,
				      perf_event__handler_t process,
				      struct machine *machine)
{
	union perf_event *event;
	int i, err, size;

	size  = sizeof(event->thread_map);
	size +=	threads->nr * sizeof(event->thread_map.entries[0]);

	event = zalloc(size);
	if (!event)
		return -ENOMEM;

	event->header.type = PERF_RECORD_THREAD_MAP;
	event->header.size = size;
	event->thread_map.nr = threads->nr;

	for (i = 0; i < threads->nr; i++) {
		struct thread_map_event_entry *entry = &event->thread_map.entries[i];
		char *comm = thread_map__comm(threads, i);

		if (!comm)
			comm = (char *) "";

		entry->pid = thread_map__pid(threads, i);
		strncpy((char *) &entry->comm, comm, sizeof(entry->comm));
	}

	err = process(tool, event, NULL, machine);

	free(event);
	return err;
}

739 740
size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp)
{
741 742 743 744 745 746 747
	const char *s;

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

748
	return fprintf(fp, "%s: %s:%d/%d\n", s, event->comm.comm, event->comm.pid, event->comm.tid);
749 750
}

751
int perf_event__process_comm(struct perf_tool *tool __maybe_unused,
752
			     union perf_event *event,
753
			     struct perf_sample *sample,
754
			     struct machine *machine)
755
{
756
	return machine__process_comm_event(machine, event, sample);
757 758
}

759
int perf_event__process_lost(struct perf_tool *tool __maybe_unused,
760
			     union perf_event *event,
761
			     struct perf_sample *sample,
762
			     struct machine *machine)
763
{
764
	return machine__process_lost_event(machine, event, sample);
765
}
766

767 768 769 770 771 772 773 774
int perf_event__process_aux(struct perf_tool *tool __maybe_unused,
			    union perf_event *event,
			    struct perf_sample *sample __maybe_unused,
			    struct machine *machine)
{
	return machine__process_aux_event(machine, event);
}

775 776 777 778 779 780 781 782
int perf_event__process_itrace_start(struct perf_tool *tool __maybe_unused,
				     union perf_event *event,
				     struct perf_sample *sample __maybe_unused,
				     struct machine *machine)
{
	return machine__process_itrace_start_event(machine, event);
}

783 784 785 786 787 788 789 790
int perf_event__process_lost_samples(struct perf_tool *tool __maybe_unused,
				     union perf_event *event,
				     struct perf_sample *sample,
				     struct machine *machine)
{
	return machine__process_lost_samples_event(machine, event, sample);
}

791 792 793 794 795 796 797 798
int perf_event__process_switch(struct perf_tool *tool __maybe_unused,
			       union perf_event *event,
			       struct perf_sample *sample __maybe_unused,
			       struct machine *machine)
{
	return machine__process_switch_event(machine, event);
}

799 800
size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp)
{
801
	return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %c %s\n",
802
		       event->mmap.pid, event->mmap.tid, event->mmap.start,
803 804 805
		       event->mmap.len, event->mmap.pgoff,
		       (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x',
		       event->mmap.filename);
806 807
}

808 809 810
size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp)
{
	return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64
811
			   " %02x:%02x %"PRIu64" %"PRIu64"]: %c%c%c%c %s\n",
812 813 814 815
		       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,
816 817 818 819
		       (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',
820 821 822
		       event->mmap2.filename);
}

823
int perf_event__process_mmap(struct perf_tool *tool __maybe_unused,
824
			     union perf_event *event,
825
			     struct perf_sample *sample,
826
			     struct machine *machine)
827
{
828
	return machine__process_mmap_event(machine, event, sample);
829 830
}

831 832
int perf_event__process_mmap2(struct perf_tool *tool __maybe_unused,
			     union perf_event *event,
833
			     struct perf_sample *sample,
834 835
			     struct machine *machine)
{
836
	return machine__process_mmap2_event(machine, event, sample);
837 838
}

839 840 841 842 843 844 845
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);
}

846
int perf_event__process_fork(struct perf_tool *tool __maybe_unused,
847
			     union perf_event *event,
848
			     struct perf_sample *sample,
849
			     struct machine *machine)
850
{
851
	return machine__process_fork_event(machine, event, sample);
852
}
853

854 855
int perf_event__process_exit(struct perf_tool *tool __maybe_unused,
			     union perf_event *event,
856
			     struct perf_sample *sample,
857 858
			     struct machine *machine)
{
859
	return machine__process_exit_event(machine, event, sample);
860 861
}

862 863 864 865 866 867 868 869 870
size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp)
{
	return fprintf(fp, " offset: %#"PRIx64" size: %#"PRIx64" flags: %#"PRIx64" [%s%s]\n",
		       event->aux.aux_offset, event->aux.aux_size,
		       event->aux.flags,
		       event->aux.flags & PERF_AUX_FLAG_TRUNCATED ? "T" : "",
		       event->aux.flags & PERF_AUX_FLAG_OVERWRITE ? "O" : "");
}

871 872 873 874 875 876
size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp)
{
	return fprintf(fp, " pid: %u tid: %u\n",
		       event->itrace_start.pid, event->itrace_start.tid);
}

877 878 879 880 881 882 883 884 885 886 887 888 889 890
size_t perf_event__fprintf_switch(union perf_event *event, FILE *fp)
{
	bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT;
	const char *in_out = out ? "OUT" : "IN ";

	if (event->header.type == PERF_RECORD_SWITCH)
		return fprintf(fp, " %s\n", in_out);

	return fprintf(fp, " %s  %s pid/tid: %5u/%-5u\n",
		       in_out, out ? "next" : "prev",
		       event->context_switch.next_prev_pid,
		       event->context_switch.next_prev_tid);
}

891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906
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;
907 908 909
	case PERF_RECORD_MMAP2:
		ret += perf_event__fprintf_mmap2(event, fp);
		break;
910 911 912
	case PERF_RECORD_AUX:
		ret += perf_event__fprintf_aux(event, fp);
		break;
913 914 915
	case PERF_RECORD_ITRACE_START:
		ret += perf_event__fprintf_itrace_start(event, fp);
		break;
916 917 918 919
	case PERF_RECORD_SWITCH:
	case PERF_RECORD_SWITCH_CPU_WIDE:
		ret += perf_event__fprintf_switch(event, fp);
		break;
920 921 922 923 924 925 926
	default:
		ret += fprintf(fp, "\n");
	}

	return ret;
}

927 928
int perf_event__process(struct perf_tool *tool __maybe_unused,
			union perf_event *event,
929
			struct perf_sample *sample,
930
			struct machine *machine)
931
{
932
	return machine__process_event(machine, event, sample);
933 934
}

935
void thread__find_addr_map(struct thread *thread, u8 cpumode,
936
			   enum map_type type, u64 addr,
937
			   struct addr_location *al)
938
{
939
	struct map_groups *mg = thread->mg;
940
	struct machine *machine = mg->machine;
941
	bool load_map = false;
942

943
	al->machine = machine;
944
	al->thread = thread;
945
	al->addr = addr;
946
	al->cpumode = cpumode;
947
	al->filtered = 0;
948

949 950 951 952 953
	if (machine == NULL) {
		al->map = NULL;
		return;
	}

954
	if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) {
955
		al->level = 'k';
956
		mg = &machine->kmaps;
957
		load_map = true;
958
	} else if (cpumode == PERF_RECORD_MISC_USER && perf_host) {
959
		al->level = '.';
960 961
	} else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) {
		al->level = 'g';
962
		mg = &machine->kmaps;
963
		load_map = true;
964 965
	} else if (cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest) {
		al->level = 'u';
966
	} else {
967
		al->level = 'H';
968
		al->map = NULL;
969 970 971 972

		if ((cpumode == PERF_RECORD_MISC_GUEST_USER ||
			cpumode == PERF_RECORD_MISC_GUEST_KERNEL) &&
			!perf_guest)
973
			al->filtered |= (1 << HIST_FILTER__GUEST);
974 975 976
		if ((cpumode == PERF_RECORD_MISC_USER ||
			cpumode == PERF_RECORD_MISC_KERNEL) &&
			!perf_host)
977
			al->filtered |= (1 << HIST_FILTER__HOST);
978

979 980 981
		return;
	}
try_again:
982
	al->map = map_groups__find(mg, type, al->addr);
983 984 985 986 987 988 989 990 991 992
	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.
		 */
993 994 995
		if (cpumode == PERF_RECORD_MISC_USER && machine &&
		    mg != &machine->kmaps &&
		    machine__kernel_ip(machine, al->addr)) {
996
			mg = &machine->kmaps;
997
			load_map = true;
998 999
			goto try_again;
		}
1000 1001 1002 1003 1004 1005
	} else {
		/*
		 * Kernel maps might be changed when loading symbols so loading
		 * must be done prior to using kernel maps.
		 */
		if (load_map)
1006
			map__load(al->map, machine->symbol_filter);
1007
		al->addr = al->map->map_ip(al->map, al->addr);
1008
	}
1009 1010
}

1011
void thread__find_addr_location(struct thread *thread,
1012
				u8 cpumode, enum map_type type, u64 addr,
1013
				struct addr_location *al)
1014
{
1015
	thread__find_addr_map(thread, cpumode, type, addr, al);
1016
	if (al->map != NULL)
1017
		al->sym = map__find_symbol(al->map, al->addr,
1018
					   thread->mg->machine->symbol_filter);
1019 1020
	else
		al->sym = NULL;
1021 1022
}

1023 1024 1025 1026
/*
 * Callers need to drop the reference to al->thread, obtained in
 * machine__findnew_thread()
 */
1027
int perf_event__preprocess_sample(const union perf_event *event,
1028
				  struct machine *machine,
1029
				  struct addr_location *al,
1030
				  struct perf_sample *sample)
1031
{
1032
	u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
1033
	struct thread *thread = machine__findnew_thread(machine, sample->pid,
1034
							sample->tid);
1035

1036 1037 1038
	if (thread == NULL)
		return -1;

1039
	dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid);
1040
	/*
1041
	 * Have we already created the kernel maps for this machine?
1042 1043 1044 1045 1046 1047
	 *
	 * 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 &&
1048
	    machine__kernel_map(machine) == NULL)
1049
		machine__create_kernel_maps(machine);
1050

1051
	thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->ip, al);
1052 1053 1054
	dump_printf(" ...... dso: %s\n",
		    al->map ? al->map->dso->long_name :
			al->level == 'H' ? "[hypervisor]" : "<not found>");
1055 1056 1057 1058

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

1059
	al->sym = NULL;
1060
	al->cpu = sample->cpu;
1061 1062 1063 1064 1065 1066 1067 1068
	al->socket = -1;

	if (al->cpu >= 0) {
		struct perf_env *env = machine->env;

		if (env && env->cpu)
			al->socket = env->cpu[al->cpu].socket_id;
	}
1069 1070

	if (al->map) {
1071 1072
		struct dso *dso = al->map->dso;

1073
		if (symbol_conf.dso_list &&
1074 1075 1076 1077
		    (!dso || !(strlist__has_entry(symbol_conf.dso_list,
						  dso->short_name) ||
			       (dso->short_name != dso->long_name &&
				strlist__has_entry(symbol_conf.dso_list,
1078 1079 1080
						   dso->long_name))))) {
			al->filtered |= (1 << HIST_FILTER__DSO);
		}
1081

1082 1083
		al->sym = map__find_symbol(al->map, al->addr,
					   machine->symbol_filter);
1084
	}
1085

1086 1087
	if (symbol_conf.sym_list &&
		(!al->sym || !strlist__has_entry(symbol_conf.sym_list,
1088 1089 1090
						al->sym->name))) {
		al->filtered |= (1 << HIST_FILTER__SYMBOL);
	}
1091 1092

	return 0;
1093
}
1094

1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105
/*
 * The preprocess_sample method will return with reference counts for the
 * in it, when done using (and perhaps getting ref counts if needing to
 * keep a pointer to one of those entries) it must be paired with
 * addr_location__put(), so that the refcounts can be decremented.
 */
void addr_location__put(struct addr_location *al)
{
	thread__zput(al->thread);
}

1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133
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;

1134
	thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->addr, al);
1135
	if (!al->map)
1136
		thread__find_addr_map(thread, cpumode, MAP__VARIABLE,
1137 1138 1139 1140 1141 1142 1143 1144
				      sample->addr, al);

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

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