xref: /openbmc/linux/tools/perf/util/util.c (revision 8fdff1dc)
1 #include "../perf.h"
2 #include "util.h"
3 #include <sys/mman.h>
4 #ifdef BACKTRACE_SUPPORT
5 #include <execinfo.h>
6 #endif
7 #include <stdio.h>
8 #include <stdlib.h>
9 
10 /*
11  * XXX We need to find a better place for these things...
12  */
13 unsigned int page_size;
14 
15 bool perf_host  = true;
16 bool perf_guest = false;
17 
18 void event_attr_init(struct perf_event_attr *attr)
19 {
20 	if (!perf_host)
21 		attr->exclude_host  = 1;
22 	if (!perf_guest)
23 		attr->exclude_guest = 1;
24 	/* to capture ABI version */
25 	attr->size = sizeof(*attr);
26 }
27 
28 int mkdir_p(char *path, mode_t mode)
29 {
30 	struct stat st;
31 	int err;
32 	char *d = path;
33 
34 	if (*d != '/')
35 		return -1;
36 
37 	if (stat(path, &st) == 0)
38 		return 0;
39 
40 	while (*++d == '/');
41 
42 	while ((d = strchr(d, '/'))) {
43 		*d = '\0';
44 		err = stat(path, &st) && mkdir(path, mode);
45 		*d++ = '/';
46 		if (err)
47 			return -1;
48 		while (*d == '/')
49 			++d;
50 	}
51 	return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0;
52 }
53 
54 static int slow_copyfile(const char *from, const char *to)
55 {
56 	int err = 0;
57 	char *line = NULL;
58 	size_t n;
59 	FILE *from_fp = fopen(from, "r"), *to_fp;
60 
61 	if (from_fp == NULL)
62 		goto out;
63 
64 	to_fp = fopen(to, "w");
65 	if (to_fp == NULL)
66 		goto out_fclose_from;
67 
68 	while (getline(&line, &n, from_fp) > 0)
69 		if (fputs(line, to_fp) == EOF)
70 			goto out_fclose_to;
71 	err = 0;
72 out_fclose_to:
73 	fclose(to_fp);
74 	free(line);
75 out_fclose_from:
76 	fclose(from_fp);
77 out:
78 	return err;
79 }
80 
81 int copyfile(const char *from, const char *to)
82 {
83 	int fromfd, tofd;
84 	struct stat st;
85 	void *addr;
86 	int err = -1;
87 
88 	if (stat(from, &st))
89 		goto out;
90 
91 	if (st.st_size == 0) /* /proc? do it slowly... */
92 		return slow_copyfile(from, to);
93 
94 	fromfd = open(from, O_RDONLY);
95 	if (fromfd < 0)
96 		goto out;
97 
98 	tofd = creat(to, 0755);
99 	if (tofd < 0)
100 		goto out_close_from;
101 
102 	addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fromfd, 0);
103 	if (addr == MAP_FAILED)
104 		goto out_close_to;
105 
106 	if (write(tofd, addr, st.st_size) == st.st_size)
107 		err = 0;
108 
109 	munmap(addr, st.st_size);
110 out_close_to:
111 	close(tofd);
112 	if (err)
113 		unlink(to);
114 out_close_from:
115 	close(fromfd);
116 out:
117 	return err;
118 }
119 
120 unsigned long convert_unit(unsigned long value, char *unit)
121 {
122 	*unit = ' ';
123 
124 	if (value > 1000) {
125 		value /= 1000;
126 		*unit = 'K';
127 	}
128 
129 	if (value > 1000) {
130 		value /= 1000;
131 		*unit = 'M';
132 	}
133 
134 	if (value > 1000) {
135 		value /= 1000;
136 		*unit = 'G';
137 	}
138 
139 	return value;
140 }
141 
142 int readn(int fd, void *buf, size_t n)
143 {
144 	void *buf_start = buf;
145 
146 	while (n) {
147 		int ret = read(fd, buf, n);
148 
149 		if (ret <= 0)
150 			return ret;
151 
152 		n -= ret;
153 		buf += ret;
154 	}
155 
156 	return buf - buf_start;
157 }
158 
159 size_t hex_width(u64 v)
160 {
161 	size_t n = 1;
162 
163 	while ((v >>= 4))
164 		++n;
165 
166 	return n;
167 }
168 
169 static int hex(char ch)
170 {
171 	if ((ch >= '0') && (ch <= '9'))
172 		return ch - '0';
173 	if ((ch >= 'a') && (ch <= 'f'))
174 		return ch - 'a' + 10;
175 	if ((ch >= 'A') && (ch <= 'F'))
176 		return ch - 'A' + 10;
177 	return -1;
178 }
179 
180 /*
181  * While we find nice hex chars, build a long_val.
182  * Return number of chars processed.
183  */
184 int hex2u64(const char *ptr, u64 *long_val)
185 {
186 	const char *p = ptr;
187 	*long_val = 0;
188 
189 	while (*p) {
190 		const int hex_val = hex(*p);
191 
192 		if (hex_val < 0)
193 			break;
194 
195 		*long_val = (*long_val << 4) | hex_val;
196 		p++;
197 	}
198 
199 	return p - ptr;
200 }
201 
202 /* Obtain a backtrace and print it to stdout. */
203 #ifdef BACKTRACE_SUPPORT
204 void dump_stack(void)
205 {
206 	void *array[16];
207 	size_t size = backtrace(array, ARRAY_SIZE(array));
208 	char **strings = backtrace_symbols(array, size);
209 	size_t i;
210 
211 	printf("Obtained %zd stack frames.\n", size);
212 
213 	for (i = 0; i < size; i++)
214 		printf("%s\n", strings[i]);
215 
216 	free(strings);
217 }
218 #else
219 void dump_stack(void) {}
220 #endif
221