1e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "../perf.h"
2e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "util.h"
3e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <sys/mman.h>
4e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#ifdef BACKTRACE_SUPPORT
5e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <execinfo.h>
6e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#endif
7e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdio.h>
8e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdlib.h>
9e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
10e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/*
11e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * XXX We need to find a better place for these things...
12e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
13e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengunsigned int page_size;
14e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
15e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengbool test_attr__enabled;
16e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
17e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengbool perf_host  = true;
18e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengbool perf_guest = false;
19e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
20e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengchar tracing_events_path[PATH_MAX + 1] = "/sys/kernel/debug/tracing/events";
21e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
22e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid event_attr_init(struct perf_event_attr *attr)
23e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
24e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!perf_host)
25e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		attr->exclude_host  = 1;
26e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!perf_guest)
27e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		attr->exclude_guest = 1;
28e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* to capture ABI version */
29e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	attr->size = sizeof(*attr);
30e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
31e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
32e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint mkdir_p(char *path, mode_t mode)
33e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
34e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct stat st;
35e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int err;
36e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *d = path;
37e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
38e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (*d != '/')
39e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
40e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
41e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (stat(path, &st) == 0)
42e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
43e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
44e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (*++d == '/');
45e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
46e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while ((d = strchr(d, '/'))) {
47e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*d = '\0';
48e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		err = stat(path, &st) && mkdir(path, mode);
49e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*d++ = '/';
50e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (err)
51e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return -1;
52e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		while (*d == '/')
53e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			++d;
54e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
55e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0;
56e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
57e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
58e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int slow_copyfile(const char *from, const char *to)
59e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
60e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int err = 0;
61e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *line = NULL;
62e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	size_t n;
63e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	FILE *from_fp = fopen(from, "r"), *to_fp;
64e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
65e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (from_fp == NULL)
66e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out;
67e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
68e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	to_fp = fopen(to, "w");
69e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (to_fp == NULL)
70e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_fclose_from;
71e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
72e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (getline(&line, &n, from_fp) > 0)
73e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (fputs(line, to_fp) == EOF)
74e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_fclose_to;
75e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	err = 0;
76e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_fclose_to:
77e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fclose(to_fp);
78e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(line);
79e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_fclose_from:
80e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fclose(from_fp);
81e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout:
82e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return err;
83e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
84e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
85e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint copyfile(const char *from, const char *to)
86e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
87e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int fromfd, tofd;
88e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct stat st;
89e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	void *addr;
90e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int err = -1;
91e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
92e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (stat(from, &st))
93e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out;
94e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
95e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (st.st_size == 0) /* /proc? do it slowly... */
96e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return slow_copyfile(from, to);
97e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
98e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fromfd = open(from, O_RDONLY);
99e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (fromfd < 0)
100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out;
101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	tofd = creat(to, 0755);
103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (tofd < 0)
104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_close_from;
105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fromfd, 0);
107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (addr == MAP_FAILED)
108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_close_to;
109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
110e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (write(tofd, addr, st.st_size) == st.st_size)
111e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		err = 0;
112e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
113e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	munmap(addr, st.st_size);
114e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_close_to:
115e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	close(tofd);
116e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (err)
117e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		unlink(to);
118e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_close_from:
119e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	close(fromfd);
120e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout:
121e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return err;
122e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
123e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
124e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengunsigned long convert_unit(unsigned long value, char *unit)
125e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
126e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*unit = ' ';
127e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
128e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (value > 1000) {
129e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		value /= 1000;
130e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*unit = 'K';
131e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
132e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
133e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (value > 1000) {
134e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		value /= 1000;
135e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*unit = 'M';
136e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
137e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
138e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (value > 1000) {
139e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		value /= 1000;
140e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*unit = 'G';
141e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
142e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
143e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return value;
144e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
145e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
146e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint readn(int fd, void *buf, size_t n)
147e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
148e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	void *buf_start = buf;
149e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
150e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (n) {
151e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		int ret = read(fd, buf, n);
152e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
153e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (ret <= 0)
154e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return ret;
155e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
156e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		n -= ret;
157e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		buf += ret;
158e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
159e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
160e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return buf - buf_start;
161e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
162e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
163e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengsize_t hex_width(u64 v)
164e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
165e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	size_t n = 1;
166e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
167e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while ((v >>= 4))
168e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		++n;
169e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
170e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return n;
171e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
172e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
173e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int hex(char ch)
174e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
175e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if ((ch >= '0') && (ch <= '9'))
176e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return ch - '0';
177e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if ((ch >= 'a') && (ch <= 'f'))
178e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return ch - 'a' + 10;
179e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if ((ch >= 'A') && (ch <= 'F'))
180e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return ch - 'A' + 10;
181e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return -1;
182e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
183e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
184e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/*
185e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * While we find nice hex chars, build a long_val.
186e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Return number of chars processed.
187e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
188e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint hex2u64(const char *ptr, u64 *long_val)
189e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
190e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *p = ptr;
191e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*long_val = 0;
192e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
193e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (*p) {
194e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		const int hex_val = hex(*p);
195e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
196e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (hex_val < 0)
197e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
198e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
199e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*long_val = (*long_val << 4) | hex_val;
200e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		p++;
201e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
202e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
203e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return p - ptr;
204e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
205e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
206e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* Obtain a backtrace and print it to stdout. */
207e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#ifdef BACKTRACE_SUPPORT
208e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid dump_stack(void)
209e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
210e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	void *array[16];
211e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	size_t size = backtrace(array, ARRAY_SIZE(array));
212e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char **strings = backtrace_symbols(array, size);
213e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	size_t i;
214e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
215e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	printf("Obtained %zd stack frames.\n", size);
216e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
217e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (i = 0; i < size; i++)
218e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printf("%s\n", strings[i]);
219e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
220e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(strings);
221e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
222e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#else
223e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid dump_stack(void) {}
224e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#endif
225e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
226e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid get_term_dimensions(struct winsize *ws)
227e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
228e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *s = getenv("LINES");
229e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
230e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (s != NULL) {
231e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ws->ws_row = atoi(s);
232e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		s = getenv("COLUMNS");
233e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (s != NULL) {
234e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ws->ws_col = atoi(s);
235e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (ws->ws_row && ws->ws_col)
236e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				return;
237e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
238e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
239e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#ifdef TIOCGWINSZ
240e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (ioctl(1, TIOCGWINSZ, ws) == 0 &&
241e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    ws->ws_row && ws->ws_col)
242e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
243e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#endif
244e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ws->ws_row = 25;
245e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ws->ws_col = 80;
246e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
247e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
248e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void set_tracing_events_path(const char *mountpoint)
249e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
250e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s",
251e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 mountpoint, "tracing/events");
252e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
253e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
254e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengconst char *perf_debugfs_mount(const char *mountpoint)
255e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
256e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *mnt;
257e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
258e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	mnt = debugfs_mount(mountpoint);
259e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!mnt)
260e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
261e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
262e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	set_tracing_events_path(mnt);
263e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
264e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return mnt;
265e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
266e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
267e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid perf_debugfs_set_path(const char *mntpt)
268e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
269e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	snprintf(debugfs_mountpoint, strlen(debugfs_mountpoint), "%s", mntpt);
270e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	set_tracing_events_path(mntpt);
271e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
272e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
273e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic const char *find_debugfs(void)
274e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
275e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *path = perf_debugfs_mount(NULL);
276e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
277e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!path)
278e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fprintf(stderr, "Your kernel does not support the debugfs filesystem");
279e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
280e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return path;
281e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
282e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
283e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/*
284e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Finds the path to the debugfs/tracing
285e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Allocates the string and stores it.
286e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
287e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengconst char *find_tracing_dir(void)
288e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
289e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static char *tracing;
290e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static int tracing_found;
291e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *debugfs;
292e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
293e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (tracing_found)
294e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return tracing;
295e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
296e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	debugfs = find_debugfs();
297e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!debugfs)
298e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
299e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
300e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	tracing = malloc(strlen(debugfs) + 9);
301e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!tracing)
302e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
303e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
304e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sprintf(tracing, "%s/tracing", debugfs);
305e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
306e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	tracing_found = 1;
307e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return tracing;
308e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
309e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
310e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengchar *get_tracing_file(const char *name)
311e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
312e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *tracing;
313e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *file;
314e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
315e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	tracing = find_tracing_dir();
316e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!tracing)
317e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
318e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
319e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	file = malloc(strlen(tracing) + strlen(name) + 2);
320e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!file)
321e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
322e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
323e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sprintf(file, "%s/%s", tracing, name);
324e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return file;
325e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
326e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
327e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid put_tracing_file(char *file)
328e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
329e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(file);
330e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
331e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
332e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint parse_nsec_time(const char *str, u64 *ptime)
333e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
334e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	u64 time_sec, time_nsec;
335e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *end;
336e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
337e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	time_sec = strtoul(str, &end, 10);
338e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (*end != '.' && *end != '\0')
339e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
340e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
341e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (*end == '.') {
342e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		int i;
343e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		char nsec_buf[10];
344e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
345e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strlen(++end) > 9)
346e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return -1;
347e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
348e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		strncpy(nsec_buf, end, 9);
349e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		nsec_buf[9] = '\0';
350e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
351e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* make it nsec precision */
352e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		for (i = strlen(nsec_buf); i < 9; i++)
353e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			nsec_buf[i] = '0';
354e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
355e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		time_nsec = strtoul(nsec_buf, &end, 10);
356e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (*end != '\0')
357e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return -1;
358e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} else
359e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		time_nsec = 0;
360e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
361e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*ptime = time_sec * NSEC_PER_SEC + time_nsec;
362e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
363e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
364