]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - tools/perf/util/util.c
Merge branch 'x86-nuke386-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[mirror_ubuntu-jammy-kernel.git] / tools / perf / util / util.c
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