Commit ac931f87a647ca156f65a4c00e7297165e4fa2d8
Committed by
Ingo Molnar
1 parent
6aaba7c901
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
perf: Fix building warning on ARM 32
Commit 85c116a6cb91 ("perf callchain: Make get_srcline fall back to sym+offset") introduces asprintf() call and matches '%ld' to a u64 argument, which is incorrect on ARM: CC /home/wn/util/srcline.o util/srcline.c: In function 'get_srcline': util/srcline.c:297:6: error: format '%ld' expects argument of type 'long int', but argument 4 has type 'u64' [-Werror=format] cc1: all warnings being treated as errors make[1]: *** [/home/wn/util/srcline.o] Error 1 In addition, all users of get_srcline() use u64 addr, and libbfd also use 64 bit bfd_vma as address. This patch also fix prototype of get_srcline() and addr2line() to use u64 addr instead of unsigned long. Signed-off-by: Wang Nan <wangnan0@huawei.com> Acked-by: Namhyung Kim <namhyung@kernel.org> Cc: <lizefan@huawei.com> Cc: <a.p.zijlstra@chello.nl> Cc: <paulus@samba.org> Cc: <acme@kernel.org> Cc: <ak@linux.intel.com> Link: http://lkml.kernel.org/r/1418710746-35943-1-git-send-email-wangnan0@huawei.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Showing 2 changed files with 7 additions and 7 deletions Inline Diff
tools/perf/util/srcline.c
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | #include <stdlib.h> | 2 | #include <stdlib.h> |
3 | #include <string.h> | 3 | #include <string.h> |
4 | 4 | ||
5 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
6 | 6 | ||
7 | #include "util/dso.h" | 7 | #include "util/dso.h" |
8 | #include "util/util.h" | 8 | #include "util/util.h" |
9 | #include "util/debug.h" | 9 | #include "util/debug.h" |
10 | 10 | ||
11 | #include "symbol.h" | 11 | #include "symbol.h" |
12 | 12 | ||
13 | #ifdef HAVE_LIBBFD_SUPPORT | 13 | #ifdef HAVE_LIBBFD_SUPPORT |
14 | 14 | ||
15 | /* | 15 | /* |
16 | * Implement addr2line using libbfd. | 16 | * Implement addr2line using libbfd. |
17 | */ | 17 | */ |
18 | #define PACKAGE "perf" | 18 | #define PACKAGE "perf" |
19 | #include <bfd.h> | 19 | #include <bfd.h> |
20 | 20 | ||
21 | struct a2l_data { | 21 | struct a2l_data { |
22 | const char *input; | 22 | const char *input; |
23 | unsigned long addr; | 23 | u64 addr; |
24 | 24 | ||
25 | bool found; | 25 | bool found; |
26 | const char *filename; | 26 | const char *filename; |
27 | const char *funcname; | 27 | const char *funcname; |
28 | unsigned line; | 28 | unsigned line; |
29 | 29 | ||
30 | bfd *abfd; | 30 | bfd *abfd; |
31 | asymbol **syms; | 31 | asymbol **syms; |
32 | }; | 32 | }; |
33 | 33 | ||
34 | static int bfd_error(const char *string) | 34 | static int bfd_error(const char *string) |
35 | { | 35 | { |
36 | const char *errmsg; | 36 | const char *errmsg; |
37 | 37 | ||
38 | errmsg = bfd_errmsg(bfd_get_error()); | 38 | errmsg = bfd_errmsg(bfd_get_error()); |
39 | fflush(stdout); | 39 | fflush(stdout); |
40 | 40 | ||
41 | if (string) | 41 | if (string) |
42 | pr_debug("%s: %s\n", string, errmsg); | 42 | pr_debug("%s: %s\n", string, errmsg); |
43 | else | 43 | else |
44 | pr_debug("%s\n", errmsg); | 44 | pr_debug("%s\n", errmsg); |
45 | 45 | ||
46 | return -1; | 46 | return -1; |
47 | } | 47 | } |
48 | 48 | ||
49 | static int slurp_symtab(bfd *abfd, struct a2l_data *a2l) | 49 | static int slurp_symtab(bfd *abfd, struct a2l_data *a2l) |
50 | { | 50 | { |
51 | long storage; | 51 | long storage; |
52 | long symcount; | 52 | long symcount; |
53 | asymbol **syms; | 53 | asymbol **syms; |
54 | bfd_boolean dynamic = FALSE; | 54 | bfd_boolean dynamic = FALSE; |
55 | 55 | ||
56 | if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0) | 56 | if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0) |
57 | return bfd_error(bfd_get_filename(abfd)); | 57 | return bfd_error(bfd_get_filename(abfd)); |
58 | 58 | ||
59 | storage = bfd_get_symtab_upper_bound(abfd); | 59 | storage = bfd_get_symtab_upper_bound(abfd); |
60 | if (storage == 0L) { | 60 | if (storage == 0L) { |
61 | storage = bfd_get_dynamic_symtab_upper_bound(abfd); | 61 | storage = bfd_get_dynamic_symtab_upper_bound(abfd); |
62 | dynamic = TRUE; | 62 | dynamic = TRUE; |
63 | } | 63 | } |
64 | if (storage < 0L) | 64 | if (storage < 0L) |
65 | return bfd_error(bfd_get_filename(abfd)); | 65 | return bfd_error(bfd_get_filename(abfd)); |
66 | 66 | ||
67 | syms = malloc(storage); | 67 | syms = malloc(storage); |
68 | if (dynamic) | 68 | if (dynamic) |
69 | symcount = bfd_canonicalize_dynamic_symtab(abfd, syms); | 69 | symcount = bfd_canonicalize_dynamic_symtab(abfd, syms); |
70 | else | 70 | else |
71 | symcount = bfd_canonicalize_symtab(abfd, syms); | 71 | symcount = bfd_canonicalize_symtab(abfd, syms); |
72 | 72 | ||
73 | if (symcount < 0) { | 73 | if (symcount < 0) { |
74 | free(syms); | 74 | free(syms); |
75 | return bfd_error(bfd_get_filename(abfd)); | 75 | return bfd_error(bfd_get_filename(abfd)); |
76 | } | 76 | } |
77 | 77 | ||
78 | a2l->syms = syms; | 78 | a2l->syms = syms; |
79 | return 0; | 79 | return 0; |
80 | } | 80 | } |
81 | 81 | ||
82 | static void find_address_in_section(bfd *abfd, asection *section, void *data) | 82 | static void find_address_in_section(bfd *abfd, asection *section, void *data) |
83 | { | 83 | { |
84 | bfd_vma pc, vma; | 84 | bfd_vma pc, vma; |
85 | bfd_size_type size; | 85 | bfd_size_type size; |
86 | struct a2l_data *a2l = data; | 86 | struct a2l_data *a2l = data; |
87 | 87 | ||
88 | if (a2l->found) | 88 | if (a2l->found) |
89 | return; | 89 | return; |
90 | 90 | ||
91 | if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0) | 91 | if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0) |
92 | return; | 92 | return; |
93 | 93 | ||
94 | pc = a2l->addr; | 94 | pc = a2l->addr; |
95 | vma = bfd_get_section_vma(abfd, section); | 95 | vma = bfd_get_section_vma(abfd, section); |
96 | size = bfd_get_section_size(section); | 96 | size = bfd_get_section_size(section); |
97 | 97 | ||
98 | if (pc < vma || pc >= vma + size) | 98 | if (pc < vma || pc >= vma + size) |
99 | return; | 99 | return; |
100 | 100 | ||
101 | a2l->found = bfd_find_nearest_line(abfd, section, a2l->syms, pc - vma, | 101 | a2l->found = bfd_find_nearest_line(abfd, section, a2l->syms, pc - vma, |
102 | &a2l->filename, &a2l->funcname, | 102 | &a2l->filename, &a2l->funcname, |
103 | &a2l->line); | 103 | &a2l->line); |
104 | } | 104 | } |
105 | 105 | ||
106 | static struct a2l_data *addr2line_init(const char *path) | 106 | static struct a2l_data *addr2line_init(const char *path) |
107 | { | 107 | { |
108 | bfd *abfd; | 108 | bfd *abfd; |
109 | struct a2l_data *a2l = NULL; | 109 | struct a2l_data *a2l = NULL; |
110 | 110 | ||
111 | abfd = bfd_openr(path, NULL); | 111 | abfd = bfd_openr(path, NULL); |
112 | if (abfd == NULL) | 112 | if (abfd == NULL) |
113 | return NULL; | 113 | return NULL; |
114 | 114 | ||
115 | if (!bfd_check_format(abfd, bfd_object)) | 115 | if (!bfd_check_format(abfd, bfd_object)) |
116 | goto out; | 116 | goto out; |
117 | 117 | ||
118 | a2l = zalloc(sizeof(*a2l)); | 118 | a2l = zalloc(sizeof(*a2l)); |
119 | if (a2l == NULL) | 119 | if (a2l == NULL) |
120 | goto out; | 120 | goto out; |
121 | 121 | ||
122 | a2l->abfd = abfd; | 122 | a2l->abfd = abfd; |
123 | a2l->input = strdup(path); | 123 | a2l->input = strdup(path); |
124 | if (a2l->input == NULL) | 124 | if (a2l->input == NULL) |
125 | goto out; | 125 | goto out; |
126 | 126 | ||
127 | if (slurp_symtab(abfd, a2l)) | 127 | if (slurp_symtab(abfd, a2l)) |
128 | goto out; | 128 | goto out; |
129 | 129 | ||
130 | return a2l; | 130 | return a2l; |
131 | 131 | ||
132 | out: | 132 | out: |
133 | if (a2l) { | 133 | if (a2l) { |
134 | zfree((char **)&a2l->input); | 134 | zfree((char **)&a2l->input); |
135 | free(a2l); | 135 | free(a2l); |
136 | } | 136 | } |
137 | bfd_close(abfd); | 137 | bfd_close(abfd); |
138 | return NULL; | 138 | return NULL; |
139 | } | 139 | } |
140 | 140 | ||
141 | static void addr2line_cleanup(struct a2l_data *a2l) | 141 | static void addr2line_cleanup(struct a2l_data *a2l) |
142 | { | 142 | { |
143 | if (a2l->abfd) | 143 | if (a2l->abfd) |
144 | bfd_close(a2l->abfd); | 144 | bfd_close(a2l->abfd); |
145 | zfree((char **)&a2l->input); | 145 | zfree((char **)&a2l->input); |
146 | zfree(&a2l->syms); | 146 | zfree(&a2l->syms); |
147 | free(a2l); | 147 | free(a2l); |
148 | } | 148 | } |
149 | 149 | ||
150 | static int addr2line(const char *dso_name, unsigned long addr, | 150 | static int addr2line(const char *dso_name, u64 addr, |
151 | char **file, unsigned int *line, struct dso *dso) | 151 | char **file, unsigned int *line, struct dso *dso) |
152 | { | 152 | { |
153 | int ret = 0; | 153 | int ret = 0; |
154 | struct a2l_data *a2l = dso->a2l; | 154 | struct a2l_data *a2l = dso->a2l; |
155 | 155 | ||
156 | if (!a2l) { | 156 | if (!a2l) { |
157 | dso->a2l = addr2line_init(dso_name); | 157 | dso->a2l = addr2line_init(dso_name); |
158 | a2l = dso->a2l; | 158 | a2l = dso->a2l; |
159 | } | 159 | } |
160 | 160 | ||
161 | if (a2l == NULL) { | 161 | if (a2l == NULL) { |
162 | pr_warning("addr2line_init failed for %s\n", dso_name); | 162 | pr_warning("addr2line_init failed for %s\n", dso_name); |
163 | return 0; | 163 | return 0; |
164 | } | 164 | } |
165 | 165 | ||
166 | a2l->addr = addr; | 166 | a2l->addr = addr; |
167 | a2l->found = false; | 167 | a2l->found = false; |
168 | 168 | ||
169 | bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l); | 169 | bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l); |
170 | 170 | ||
171 | if (a2l->found && a2l->filename) { | 171 | if (a2l->found && a2l->filename) { |
172 | *file = strdup(a2l->filename); | 172 | *file = strdup(a2l->filename); |
173 | *line = a2l->line; | 173 | *line = a2l->line; |
174 | 174 | ||
175 | if (*file) | 175 | if (*file) |
176 | ret = 1; | 176 | ret = 1; |
177 | } | 177 | } |
178 | 178 | ||
179 | return ret; | 179 | return ret; |
180 | } | 180 | } |
181 | 181 | ||
182 | void dso__free_a2l(struct dso *dso) | 182 | void dso__free_a2l(struct dso *dso) |
183 | { | 183 | { |
184 | struct a2l_data *a2l = dso->a2l; | 184 | struct a2l_data *a2l = dso->a2l; |
185 | 185 | ||
186 | if (!a2l) | 186 | if (!a2l) |
187 | return; | 187 | return; |
188 | 188 | ||
189 | addr2line_cleanup(a2l); | 189 | addr2line_cleanup(a2l); |
190 | 190 | ||
191 | dso->a2l = NULL; | 191 | dso->a2l = NULL; |
192 | } | 192 | } |
193 | 193 | ||
194 | #else /* HAVE_LIBBFD_SUPPORT */ | 194 | #else /* HAVE_LIBBFD_SUPPORT */ |
195 | 195 | ||
196 | static int addr2line(const char *dso_name, unsigned long addr, | 196 | static int addr2line(const char *dso_name, u64 addr, |
197 | char **file, unsigned int *line_nr, | 197 | char **file, unsigned int *line_nr, |
198 | struct dso *dso __maybe_unused) | 198 | struct dso *dso __maybe_unused) |
199 | { | 199 | { |
200 | FILE *fp; | 200 | FILE *fp; |
201 | char cmd[PATH_MAX]; | 201 | char cmd[PATH_MAX]; |
202 | char *filename = NULL; | 202 | char *filename = NULL; |
203 | size_t len; | 203 | size_t len; |
204 | char *sep; | 204 | char *sep; |
205 | int ret = 0; | 205 | int ret = 0; |
206 | 206 | ||
207 | scnprintf(cmd, sizeof(cmd), "addr2line -e %s %016"PRIx64, | 207 | scnprintf(cmd, sizeof(cmd), "addr2line -e %s %016"PRIx64, |
208 | dso_name, addr); | 208 | dso_name, addr); |
209 | 209 | ||
210 | fp = popen(cmd, "r"); | 210 | fp = popen(cmd, "r"); |
211 | if (fp == NULL) { | 211 | if (fp == NULL) { |
212 | pr_warning("popen failed for %s\n", dso_name); | 212 | pr_warning("popen failed for %s\n", dso_name); |
213 | return 0; | 213 | return 0; |
214 | } | 214 | } |
215 | 215 | ||
216 | if (getline(&filename, &len, fp) < 0 || !len) { | 216 | if (getline(&filename, &len, fp) < 0 || !len) { |
217 | pr_warning("addr2line has no output for %s\n", dso_name); | 217 | pr_warning("addr2line has no output for %s\n", dso_name); |
218 | goto out; | 218 | goto out; |
219 | } | 219 | } |
220 | 220 | ||
221 | sep = strchr(filename, '\n'); | 221 | sep = strchr(filename, '\n'); |
222 | if (sep) | 222 | if (sep) |
223 | *sep = '\0'; | 223 | *sep = '\0'; |
224 | 224 | ||
225 | if (!strcmp(filename, "??:0")) { | 225 | if (!strcmp(filename, "??:0")) { |
226 | pr_debug("no debugging info in %s\n", dso_name); | 226 | pr_debug("no debugging info in %s\n", dso_name); |
227 | free(filename); | 227 | free(filename); |
228 | goto out; | 228 | goto out; |
229 | } | 229 | } |
230 | 230 | ||
231 | sep = strchr(filename, ':'); | 231 | sep = strchr(filename, ':'); |
232 | if (sep) { | 232 | if (sep) { |
233 | *sep++ = '\0'; | 233 | *sep++ = '\0'; |
234 | *file = filename; | 234 | *file = filename; |
235 | *line_nr = strtoul(sep, NULL, 0); | 235 | *line_nr = strtoul(sep, NULL, 0); |
236 | ret = 1; | 236 | ret = 1; |
237 | } | 237 | } |
238 | out: | 238 | out: |
239 | pclose(fp); | 239 | pclose(fp); |
240 | return ret; | 240 | return ret; |
241 | } | 241 | } |
242 | 242 | ||
243 | void dso__free_a2l(struct dso *dso __maybe_unused) | 243 | void dso__free_a2l(struct dso *dso __maybe_unused) |
244 | { | 244 | { |
245 | } | 245 | } |
246 | 246 | ||
247 | #endif /* HAVE_LIBBFD_SUPPORT */ | 247 | #endif /* HAVE_LIBBFD_SUPPORT */ |
248 | 248 | ||
249 | /* | 249 | /* |
250 | * Number of addr2line failures (without success) before disabling it for that | 250 | * Number of addr2line failures (without success) before disabling it for that |
251 | * dso. | 251 | * dso. |
252 | */ | 252 | */ |
253 | #define A2L_FAIL_LIMIT 123 | 253 | #define A2L_FAIL_LIMIT 123 |
254 | 254 | ||
255 | char *get_srcline(struct dso *dso, unsigned long addr, struct symbol *sym, | 255 | char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym, |
256 | bool show_sym) | 256 | bool show_sym) |
257 | { | 257 | { |
258 | char *file = NULL; | 258 | char *file = NULL; |
259 | unsigned line = 0; | 259 | unsigned line = 0; |
260 | char *srcline; | 260 | char *srcline; |
261 | const char *dso_name; | 261 | const char *dso_name; |
262 | 262 | ||
263 | if (!dso->has_srcline) | 263 | if (!dso->has_srcline) |
264 | goto out; | 264 | goto out; |
265 | 265 | ||
266 | if (dso->symsrc_filename) | 266 | if (dso->symsrc_filename) |
267 | dso_name = dso->symsrc_filename; | 267 | dso_name = dso->symsrc_filename; |
268 | else | 268 | else |
269 | dso_name = dso->long_name; | 269 | dso_name = dso->long_name; |
270 | 270 | ||
271 | if (dso_name[0] == '[') | 271 | if (dso_name[0] == '[') |
272 | goto out; | 272 | goto out; |
273 | 273 | ||
274 | if (!strncmp(dso_name, "/tmp/perf-", 10)) | 274 | if (!strncmp(dso_name, "/tmp/perf-", 10)) |
275 | goto out; | 275 | goto out; |
276 | 276 | ||
277 | if (!addr2line(dso_name, addr, &file, &line, dso)) | 277 | if (!addr2line(dso_name, addr, &file, &line, dso)) |
278 | goto out; | 278 | goto out; |
279 | 279 | ||
280 | if (asprintf(&srcline, "%s:%u", basename(file), line) < 0) { | 280 | if (asprintf(&srcline, "%s:%u", basename(file), line) < 0) { |
281 | free(file); | 281 | free(file); |
282 | goto out; | 282 | goto out; |
283 | } | 283 | } |
284 | 284 | ||
285 | dso->a2l_fails = 0; | 285 | dso->a2l_fails = 0; |
286 | 286 | ||
287 | free(file); | 287 | free(file); |
288 | return srcline; | 288 | return srcline; |
289 | 289 | ||
290 | out: | 290 | out: |
291 | if (dso->a2l_fails && ++dso->a2l_fails > A2L_FAIL_LIMIT) { | 291 | if (dso->a2l_fails && ++dso->a2l_fails > A2L_FAIL_LIMIT) { |
292 | dso->has_srcline = 0; | 292 | dso->has_srcline = 0; |
293 | dso__free_a2l(dso); | 293 | dso__free_a2l(dso); |
294 | } | 294 | } |
295 | if (sym) { | 295 | if (sym) { |
296 | if (asprintf(&srcline, "%s+%ld", show_sym ? sym->name : "", | 296 | if (asprintf(&srcline, "%s+%" PRIu64, show_sym ? sym->name : "", |
297 | addr - sym->start) < 0) | 297 | addr - sym->start) < 0) |
298 | return SRCLINE_UNKNOWN; | 298 | return SRCLINE_UNKNOWN; |
299 | } else if (asprintf(&srcline, "%s[%lx]", dso->short_name, addr) < 0) | 299 | } else if (asprintf(&srcline, "%s[%" PRIx64 "]", dso->short_name, addr) < 0) |
300 | return SRCLINE_UNKNOWN; | 300 | return SRCLINE_UNKNOWN; |
301 | return srcline; | 301 | return srcline; |
302 | } | 302 | } |
303 | 303 | ||
304 | void free_srcline(char *srcline) | 304 | void free_srcline(char *srcline) |
305 | { | 305 | { |
306 | if (srcline && strcmp(srcline, SRCLINE_UNKNOWN) != 0) | 306 | if (srcline && strcmp(srcline, SRCLINE_UNKNOWN) != 0) |
307 | free(srcline); | 307 | free(srcline); |
308 | } | 308 | } |
309 | 309 |
tools/perf/util/util.h
1 | #ifndef GIT_COMPAT_UTIL_H | 1 | #ifndef GIT_COMPAT_UTIL_H |
2 | #define GIT_COMPAT_UTIL_H | 2 | #define GIT_COMPAT_UTIL_H |
3 | 3 | ||
4 | #ifndef FLEX_ARRAY | 4 | #ifndef FLEX_ARRAY |
5 | /* | 5 | /* |
6 | * See if our compiler is known to support flexible array members. | 6 | * See if our compiler is known to support flexible array members. |
7 | */ | 7 | */ |
8 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) | 8 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) |
9 | # define FLEX_ARRAY /* empty */ | 9 | # define FLEX_ARRAY /* empty */ |
10 | #elif defined(__GNUC__) | 10 | #elif defined(__GNUC__) |
11 | # if (__GNUC__ >= 3) | 11 | # if (__GNUC__ >= 3) |
12 | # define FLEX_ARRAY /* empty */ | 12 | # define FLEX_ARRAY /* empty */ |
13 | # else | 13 | # else |
14 | # define FLEX_ARRAY 0 /* older GNU extension */ | 14 | # define FLEX_ARRAY 0 /* older GNU extension */ |
15 | # endif | 15 | # endif |
16 | #endif | 16 | #endif |
17 | 17 | ||
18 | /* | 18 | /* |
19 | * Otherwise, default to safer but a bit wasteful traditional style | 19 | * Otherwise, default to safer but a bit wasteful traditional style |
20 | */ | 20 | */ |
21 | #ifndef FLEX_ARRAY | 21 | #ifndef FLEX_ARRAY |
22 | # define FLEX_ARRAY 1 | 22 | # define FLEX_ARRAY 1 |
23 | #endif | 23 | #endif |
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) | 26 | #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) |
27 | 27 | ||
28 | #ifdef __GNUC__ | 28 | #ifdef __GNUC__ |
29 | #define TYPEOF(x) (__typeof__(x)) | 29 | #define TYPEOF(x) (__typeof__(x)) |
30 | #else | 30 | #else |
31 | #define TYPEOF(x) | 31 | #define TYPEOF(x) |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | #define MSB(x, bits) ((x) & TYPEOF(x)(~0ULL << (sizeof(x) * 8 - (bits)))) | 34 | #define MSB(x, bits) ((x) & TYPEOF(x)(~0ULL << (sizeof(x) * 8 - (bits)))) |
35 | #define HAS_MULTI_BITS(i) ((i) & ((i) - 1)) /* checks if an integer has more than 1 bit set */ | 35 | #define HAS_MULTI_BITS(i) ((i) & ((i) - 1)) /* checks if an integer has more than 1 bit set */ |
36 | 36 | ||
37 | /* Approximation of the length of the decimal representation of this type. */ | 37 | /* Approximation of the length of the decimal representation of this type. */ |
38 | #define decimal_length(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1) | 38 | #define decimal_length(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1) |
39 | 39 | ||
40 | #define _ALL_SOURCE 1 | 40 | #define _ALL_SOURCE 1 |
41 | #define _BSD_SOURCE 1 | 41 | #define _BSD_SOURCE 1 |
42 | /* glibc 2.20 deprecates _BSD_SOURCE in favour of _DEFAULT_SOURCE */ | 42 | /* glibc 2.20 deprecates _BSD_SOURCE in favour of _DEFAULT_SOURCE */ |
43 | #define _DEFAULT_SOURCE 1 | 43 | #define _DEFAULT_SOURCE 1 |
44 | #define HAS_BOOL | 44 | #define HAS_BOOL |
45 | 45 | ||
46 | #include <unistd.h> | 46 | #include <unistd.h> |
47 | #include <stdio.h> | 47 | #include <stdio.h> |
48 | #include <sys/stat.h> | 48 | #include <sys/stat.h> |
49 | #include <sys/statfs.h> | 49 | #include <sys/statfs.h> |
50 | #include <fcntl.h> | 50 | #include <fcntl.h> |
51 | #include <stdbool.h> | 51 | #include <stdbool.h> |
52 | #include <stddef.h> | 52 | #include <stddef.h> |
53 | #include <stdlib.h> | 53 | #include <stdlib.h> |
54 | #include <stdarg.h> | 54 | #include <stdarg.h> |
55 | #include <string.h> | 55 | #include <string.h> |
56 | #include <errno.h> | 56 | #include <errno.h> |
57 | #include <limits.h> | 57 | #include <limits.h> |
58 | #include <sys/param.h> | 58 | #include <sys/param.h> |
59 | #include <sys/types.h> | 59 | #include <sys/types.h> |
60 | #include <dirent.h> | 60 | #include <dirent.h> |
61 | #include <sys/time.h> | 61 | #include <sys/time.h> |
62 | #include <time.h> | 62 | #include <time.h> |
63 | #include <signal.h> | 63 | #include <signal.h> |
64 | #include <fnmatch.h> | 64 | #include <fnmatch.h> |
65 | #include <assert.h> | 65 | #include <assert.h> |
66 | #include <regex.h> | 66 | #include <regex.h> |
67 | #include <utime.h> | 67 | #include <utime.h> |
68 | #include <sys/wait.h> | 68 | #include <sys/wait.h> |
69 | #include <poll.h> | 69 | #include <poll.h> |
70 | #include <sys/socket.h> | 70 | #include <sys/socket.h> |
71 | #include <sys/ioctl.h> | 71 | #include <sys/ioctl.h> |
72 | #include <inttypes.h> | 72 | #include <inttypes.h> |
73 | #include <linux/kernel.h> | 73 | #include <linux/kernel.h> |
74 | #include <linux/magic.h> | 74 | #include <linux/magic.h> |
75 | #include <linux/types.h> | 75 | #include <linux/types.h> |
76 | #include <sys/ttydefaults.h> | 76 | #include <sys/ttydefaults.h> |
77 | #include <api/fs/debugfs.h> | 77 | #include <api/fs/debugfs.h> |
78 | #include <termios.h> | 78 | #include <termios.h> |
79 | #include <linux/bitops.h> | 79 | #include <linux/bitops.h> |
80 | #include <termios.h> | 80 | #include <termios.h> |
81 | 81 | ||
82 | extern const char *graph_line; | 82 | extern const char *graph_line; |
83 | extern const char *graph_dotted_line; | 83 | extern const char *graph_dotted_line; |
84 | extern char buildid_dir[]; | 84 | extern char buildid_dir[]; |
85 | extern char tracing_events_path[]; | 85 | extern char tracing_events_path[]; |
86 | extern void perf_debugfs_set_path(const char *mountpoint); | 86 | extern void perf_debugfs_set_path(const char *mountpoint); |
87 | const char *perf_debugfs_mount(const char *mountpoint); | 87 | const char *perf_debugfs_mount(const char *mountpoint); |
88 | const char *find_tracing_dir(void); | 88 | const char *find_tracing_dir(void); |
89 | char *get_tracing_file(const char *name); | 89 | char *get_tracing_file(const char *name); |
90 | void put_tracing_file(char *file); | 90 | void put_tracing_file(char *file); |
91 | 91 | ||
92 | /* On most systems <limits.h> would have given us this, but | 92 | /* On most systems <limits.h> would have given us this, but |
93 | * not on some systems (e.g. GNU/Hurd). | 93 | * not on some systems (e.g. GNU/Hurd). |
94 | */ | 94 | */ |
95 | #ifndef PATH_MAX | 95 | #ifndef PATH_MAX |
96 | #define PATH_MAX 4096 | 96 | #define PATH_MAX 4096 |
97 | #endif | 97 | #endif |
98 | 98 | ||
99 | #ifndef PRIuMAX | 99 | #ifndef PRIuMAX |
100 | #define PRIuMAX "llu" | 100 | #define PRIuMAX "llu" |
101 | #endif | 101 | #endif |
102 | 102 | ||
103 | #ifndef PRIu32 | 103 | #ifndef PRIu32 |
104 | #define PRIu32 "u" | 104 | #define PRIu32 "u" |
105 | #endif | 105 | #endif |
106 | 106 | ||
107 | #ifndef PRIx32 | 107 | #ifndef PRIx32 |
108 | #define PRIx32 "x" | 108 | #define PRIx32 "x" |
109 | #endif | 109 | #endif |
110 | 110 | ||
111 | #ifndef PATH_SEP | 111 | #ifndef PATH_SEP |
112 | #define PATH_SEP ':' | 112 | #define PATH_SEP ':' |
113 | #endif | 113 | #endif |
114 | 114 | ||
115 | #ifndef STRIP_EXTENSION | 115 | #ifndef STRIP_EXTENSION |
116 | #define STRIP_EXTENSION "" | 116 | #define STRIP_EXTENSION "" |
117 | #endif | 117 | #endif |
118 | 118 | ||
119 | #ifndef has_dos_drive_prefix | 119 | #ifndef has_dos_drive_prefix |
120 | #define has_dos_drive_prefix(path) 0 | 120 | #define has_dos_drive_prefix(path) 0 |
121 | #endif | 121 | #endif |
122 | 122 | ||
123 | #ifndef is_dir_sep | 123 | #ifndef is_dir_sep |
124 | #define is_dir_sep(c) ((c) == '/') | 124 | #define is_dir_sep(c) ((c) == '/') |
125 | #endif | 125 | #endif |
126 | 126 | ||
127 | #ifdef __GNUC__ | 127 | #ifdef __GNUC__ |
128 | #define NORETURN __attribute__((__noreturn__)) | 128 | #define NORETURN __attribute__((__noreturn__)) |
129 | #else | 129 | #else |
130 | #define NORETURN | 130 | #define NORETURN |
131 | #ifndef __attribute__ | 131 | #ifndef __attribute__ |
132 | #define __attribute__(x) | 132 | #define __attribute__(x) |
133 | #endif | 133 | #endif |
134 | #endif | 134 | #endif |
135 | 135 | ||
136 | #define PERF_GTK_DSO "libperf-gtk.so" | 136 | #define PERF_GTK_DSO "libperf-gtk.so" |
137 | 137 | ||
138 | /* General helper functions */ | 138 | /* General helper functions */ |
139 | extern void usage(const char *err) NORETURN; | 139 | extern void usage(const char *err) NORETURN; |
140 | extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); | 140 | extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); |
141 | extern int error(const char *err, ...) __attribute__((format (printf, 1, 2))); | 141 | extern int error(const char *err, ...) __attribute__((format (printf, 1, 2))); |
142 | extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2))); | 142 | extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2))); |
143 | 143 | ||
144 | #include "../../../include/linux/stringify.h" | 144 | #include "../../../include/linux/stringify.h" |
145 | 145 | ||
146 | #define DIE_IF(cnd) \ | 146 | #define DIE_IF(cnd) \ |
147 | do { if (cnd) \ | 147 | do { if (cnd) \ |
148 | die(" at (" __FILE__ ":" __stringify(__LINE__) "): " \ | 148 | die(" at (" __FILE__ ":" __stringify(__LINE__) "): " \ |
149 | __stringify(cnd) "\n"); \ | 149 | __stringify(cnd) "\n"); \ |
150 | } while (0) | 150 | } while (0) |
151 | 151 | ||
152 | 152 | ||
153 | extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN); | 153 | extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN); |
154 | 154 | ||
155 | extern int prefixcmp(const char *str, const char *prefix); | 155 | extern int prefixcmp(const char *str, const char *prefix); |
156 | extern void set_buildid_dir(const char *dir); | 156 | extern void set_buildid_dir(const char *dir); |
157 | 157 | ||
158 | static inline const char *skip_prefix(const char *str, const char *prefix) | 158 | static inline const char *skip_prefix(const char *str, const char *prefix) |
159 | { | 159 | { |
160 | size_t len = strlen(prefix); | 160 | size_t len = strlen(prefix); |
161 | return strncmp(str, prefix, len) ? NULL : str + len; | 161 | return strncmp(str, prefix, len) ? NULL : str + len; |
162 | } | 162 | } |
163 | 163 | ||
164 | #ifdef __GLIBC_PREREQ | 164 | #ifdef __GLIBC_PREREQ |
165 | #if __GLIBC_PREREQ(2, 1) | 165 | #if __GLIBC_PREREQ(2, 1) |
166 | #define HAVE_STRCHRNUL | 166 | #define HAVE_STRCHRNUL |
167 | #endif | 167 | #endif |
168 | #endif | 168 | #endif |
169 | 169 | ||
170 | #ifndef HAVE_STRCHRNUL | 170 | #ifndef HAVE_STRCHRNUL |
171 | #define strchrnul gitstrchrnul | 171 | #define strchrnul gitstrchrnul |
172 | static inline char *gitstrchrnul(const char *s, int c) | 172 | static inline char *gitstrchrnul(const char *s, int c) |
173 | { | 173 | { |
174 | while (*s && *s != c) | 174 | while (*s && *s != c) |
175 | s++; | 175 | s++; |
176 | return (char *)s; | 176 | return (char *)s; |
177 | } | 177 | } |
178 | #endif | 178 | #endif |
179 | 179 | ||
180 | /* | 180 | /* |
181 | * Wrappers: | 181 | * Wrappers: |
182 | */ | 182 | */ |
183 | extern char *xstrdup(const char *str); | 183 | extern char *xstrdup(const char *str); |
184 | extern void *xrealloc(void *ptr, size_t size) __attribute__((weak)); | 184 | extern void *xrealloc(void *ptr, size_t size) __attribute__((weak)); |
185 | 185 | ||
186 | 186 | ||
187 | static inline void *zalloc(size_t size) | 187 | static inline void *zalloc(size_t size) |
188 | { | 188 | { |
189 | return calloc(1, size); | 189 | return calloc(1, size); |
190 | } | 190 | } |
191 | 191 | ||
192 | #define zfree(ptr) ({ free(*ptr); *ptr = NULL; }) | 192 | #define zfree(ptr) ({ free(*ptr); *ptr = NULL; }) |
193 | 193 | ||
194 | static inline int has_extension(const char *filename, const char *ext) | 194 | static inline int has_extension(const char *filename, const char *ext) |
195 | { | 195 | { |
196 | size_t len = strlen(filename); | 196 | size_t len = strlen(filename); |
197 | size_t extlen = strlen(ext); | 197 | size_t extlen = strlen(ext); |
198 | 198 | ||
199 | return len > extlen && !memcmp(filename + len - extlen, ext, extlen); | 199 | return len > extlen && !memcmp(filename + len - extlen, ext, extlen); |
200 | } | 200 | } |
201 | 201 | ||
202 | /* Sane ctype - no locale, and works with signed chars */ | 202 | /* Sane ctype - no locale, and works with signed chars */ |
203 | #undef isascii | 203 | #undef isascii |
204 | #undef isspace | 204 | #undef isspace |
205 | #undef isdigit | 205 | #undef isdigit |
206 | #undef isxdigit | 206 | #undef isxdigit |
207 | #undef isalpha | 207 | #undef isalpha |
208 | #undef isprint | 208 | #undef isprint |
209 | #undef isalnum | 209 | #undef isalnum |
210 | #undef islower | 210 | #undef islower |
211 | #undef isupper | 211 | #undef isupper |
212 | #undef tolower | 212 | #undef tolower |
213 | #undef toupper | 213 | #undef toupper |
214 | 214 | ||
215 | #ifndef NSEC_PER_MSEC | 215 | #ifndef NSEC_PER_MSEC |
216 | #define NSEC_PER_MSEC 1000000L | 216 | #define NSEC_PER_MSEC 1000000L |
217 | #endif | 217 | #endif |
218 | 218 | ||
219 | int parse_nsec_time(const char *str, u64 *ptime); | 219 | int parse_nsec_time(const char *str, u64 *ptime); |
220 | 220 | ||
221 | extern unsigned char sane_ctype[256]; | 221 | extern unsigned char sane_ctype[256]; |
222 | #define GIT_SPACE 0x01 | 222 | #define GIT_SPACE 0x01 |
223 | #define GIT_DIGIT 0x02 | 223 | #define GIT_DIGIT 0x02 |
224 | #define GIT_ALPHA 0x04 | 224 | #define GIT_ALPHA 0x04 |
225 | #define GIT_GLOB_SPECIAL 0x08 | 225 | #define GIT_GLOB_SPECIAL 0x08 |
226 | #define GIT_REGEX_SPECIAL 0x10 | 226 | #define GIT_REGEX_SPECIAL 0x10 |
227 | #define GIT_PRINT_EXTRA 0x20 | 227 | #define GIT_PRINT_EXTRA 0x20 |
228 | #define GIT_PRINT 0x3E | 228 | #define GIT_PRINT 0x3E |
229 | #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0) | 229 | #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0) |
230 | #define isascii(x) (((x) & ~0x7f) == 0) | 230 | #define isascii(x) (((x) & ~0x7f) == 0) |
231 | #define isspace(x) sane_istest(x,GIT_SPACE) | 231 | #define isspace(x) sane_istest(x,GIT_SPACE) |
232 | #define isdigit(x) sane_istest(x,GIT_DIGIT) | 232 | #define isdigit(x) sane_istest(x,GIT_DIGIT) |
233 | #define isxdigit(x) \ | 233 | #define isxdigit(x) \ |
234 | (sane_istest(toupper(x), GIT_ALPHA | GIT_DIGIT) && toupper(x) < 'G') | 234 | (sane_istest(toupper(x), GIT_ALPHA | GIT_DIGIT) && toupper(x) < 'G') |
235 | #define isalpha(x) sane_istest(x,GIT_ALPHA) | 235 | #define isalpha(x) sane_istest(x,GIT_ALPHA) |
236 | #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT) | 236 | #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT) |
237 | #define isprint(x) sane_istest(x,GIT_PRINT) | 237 | #define isprint(x) sane_istest(x,GIT_PRINT) |
238 | #define islower(x) (sane_istest(x,GIT_ALPHA) && (x & 0x20)) | 238 | #define islower(x) (sane_istest(x,GIT_ALPHA) && (x & 0x20)) |
239 | #define isupper(x) (sane_istest(x,GIT_ALPHA) && !(x & 0x20)) | 239 | #define isupper(x) (sane_istest(x,GIT_ALPHA) && !(x & 0x20)) |
240 | #define tolower(x) sane_case((unsigned char)(x), 0x20) | 240 | #define tolower(x) sane_case((unsigned char)(x), 0x20) |
241 | #define toupper(x) sane_case((unsigned char)(x), 0) | 241 | #define toupper(x) sane_case((unsigned char)(x), 0) |
242 | 242 | ||
243 | static inline int sane_case(int x, int high) | 243 | static inline int sane_case(int x, int high) |
244 | { | 244 | { |
245 | if (sane_istest(x, GIT_ALPHA)) | 245 | if (sane_istest(x, GIT_ALPHA)) |
246 | x = (x & ~0x20) | high; | 246 | x = (x & ~0x20) | high; |
247 | return x; | 247 | return x; |
248 | } | 248 | } |
249 | 249 | ||
250 | int mkdir_p(char *path, mode_t mode); | 250 | int mkdir_p(char *path, mode_t mode); |
251 | int copyfile(const char *from, const char *to); | 251 | int copyfile(const char *from, const char *to); |
252 | int copyfile_mode(const char *from, const char *to, mode_t mode); | 252 | int copyfile_mode(const char *from, const char *to, mode_t mode); |
253 | 253 | ||
254 | s64 perf_atoll(const char *str); | 254 | s64 perf_atoll(const char *str); |
255 | char **argv_split(const char *str, int *argcp); | 255 | char **argv_split(const char *str, int *argcp); |
256 | void argv_free(char **argv); | 256 | void argv_free(char **argv); |
257 | bool strglobmatch(const char *str, const char *pat); | 257 | bool strglobmatch(const char *str, const char *pat); |
258 | bool strlazymatch(const char *str, const char *pat); | 258 | bool strlazymatch(const char *str, const char *pat); |
259 | int strtailcmp(const char *s1, const char *s2); | 259 | int strtailcmp(const char *s1, const char *s2); |
260 | char *strxfrchar(char *s, char from, char to); | 260 | char *strxfrchar(char *s, char from, char to); |
261 | unsigned long convert_unit(unsigned long value, char *unit); | 261 | unsigned long convert_unit(unsigned long value, char *unit); |
262 | ssize_t readn(int fd, void *buf, size_t n); | 262 | ssize_t readn(int fd, void *buf, size_t n); |
263 | ssize_t writen(int fd, void *buf, size_t n); | 263 | ssize_t writen(int fd, void *buf, size_t n); |
264 | 264 | ||
265 | struct perf_event_attr; | 265 | struct perf_event_attr; |
266 | 266 | ||
267 | void event_attr_init(struct perf_event_attr *attr); | 267 | void event_attr_init(struct perf_event_attr *attr); |
268 | 268 | ||
269 | #define _STR(x) #x | 269 | #define _STR(x) #x |
270 | #define STR(x) _STR(x) | 270 | #define STR(x) _STR(x) |
271 | 271 | ||
272 | size_t hex_width(u64 v); | 272 | size_t hex_width(u64 v); |
273 | int hex2u64(const char *ptr, u64 *val); | 273 | int hex2u64(const char *ptr, u64 *val); |
274 | 274 | ||
275 | char *ltrim(char *s); | 275 | char *ltrim(char *s); |
276 | char *rtrim(char *s); | 276 | char *rtrim(char *s); |
277 | 277 | ||
278 | void dump_stack(void); | 278 | void dump_stack(void); |
279 | 279 | ||
280 | extern unsigned int page_size; | 280 | extern unsigned int page_size; |
281 | extern int cacheline_size; | 281 | extern int cacheline_size; |
282 | 282 | ||
283 | void get_term_dimensions(struct winsize *ws); | 283 | void get_term_dimensions(struct winsize *ws); |
284 | void set_term_quiet_input(struct termios *old); | 284 | void set_term_quiet_input(struct termios *old); |
285 | 285 | ||
286 | struct parse_tag { | 286 | struct parse_tag { |
287 | char tag; | 287 | char tag; |
288 | int mult; | 288 | int mult; |
289 | }; | 289 | }; |
290 | 290 | ||
291 | unsigned long parse_tag_value(const char *str, struct parse_tag *tags); | 291 | unsigned long parse_tag_value(const char *str, struct parse_tag *tags); |
292 | 292 | ||
293 | #define SRCLINE_UNKNOWN ((char *) "??:0") | 293 | #define SRCLINE_UNKNOWN ((char *) "??:0") |
294 | 294 | ||
295 | static inline int path__join(char *bf, size_t size, | 295 | static inline int path__join(char *bf, size_t size, |
296 | const char *path1, const char *path2) | 296 | const char *path1, const char *path2) |
297 | { | 297 | { |
298 | return scnprintf(bf, size, "%s%s%s", path1, path1[0] ? "/" : "", path2); | 298 | return scnprintf(bf, size, "%s%s%s", path1, path1[0] ? "/" : "", path2); |
299 | } | 299 | } |
300 | 300 | ||
301 | static inline int path__join3(char *bf, size_t size, | 301 | static inline int path__join3(char *bf, size_t size, |
302 | const char *path1, const char *path2, | 302 | const char *path1, const char *path2, |
303 | const char *path3) | 303 | const char *path3) |
304 | { | 304 | { |
305 | return scnprintf(bf, size, "%s%s%s%s%s", | 305 | return scnprintf(bf, size, "%s%s%s%s%s", |
306 | path1, path1[0] ? "/" : "", | 306 | path1, path1[0] ? "/" : "", |
307 | path2, path2[0] ? "/" : "", path3); | 307 | path2, path2[0] ? "/" : "", path3); |
308 | } | 308 | } |
309 | 309 | ||
310 | struct dso; | 310 | struct dso; |
311 | struct symbol; | 311 | struct symbol; |
312 | 312 | ||
313 | char *get_srcline(struct dso *dso, unsigned long addr, struct symbol *sym, | 313 | char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym, |
314 | bool show_sym); | 314 | bool show_sym); |
315 | void free_srcline(char *srcline); | 315 | void free_srcline(char *srcline); |
316 | 316 | ||
317 | int filename__read_str(const char *filename, char **buf, size_t *sizep); | 317 | int filename__read_str(const char *filename, char **buf, size_t *sizep); |
318 | int perf_event_paranoid(void); | 318 | int perf_event_paranoid(void); |
319 | 319 | ||
320 | void mem_bswap_64(void *src, int byte_size); | 320 | void mem_bswap_64(void *src, int byte_size); |
321 | void mem_bswap_32(void *src, int byte_size); | 321 | void mem_bswap_32(void *src, int byte_size); |
322 | 322 | ||
323 | const char *get_filename_for_perf_kvm(void); | 323 | const char *get_filename_for_perf_kvm(void); |
324 | bool find_process(const char *name); | 324 | bool find_process(const char *name); |
325 | 325 | ||
326 | #ifdef HAVE_ZLIB_SUPPORT | 326 | #ifdef HAVE_ZLIB_SUPPORT |
327 | int gzip_decompress_to_file(const char *input, int output_fd); | 327 | int gzip_decompress_to_file(const char *input, int output_fd); |
328 | #endif | 328 | #endif |
329 | 329 | ||
330 | #endif /* GIT_COMPAT_UTIL_H */ | 330 | #endif /* GIT_COMPAT_UTIL_H */ |
331 | 331 |