Merge tag 'linux-kselftest-kunit-5.15-rc1' of git://git.kernel.org/pub/scm/linux...
[linux-2.6-microblaze.git] / tools / perf / util / config.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * config.c
4  *
5  * Helper functions for parsing config items.
6  * Originally copied from GIT source.
7  *
8  * Copyright (C) Linus Torvalds, 2005
9  * Copyright (C) Johannes Schindelin, 2005
10  *
11  */
12 #include <errno.h>
13 #include <sys/param.h>
14 #include "cache.h"
15 #include "callchain.h"
16 #include <subcmd/exec-cmd.h>
17 #include "util/event.h"  /* proc_map_timeout */
18 #include "util/hist.h"  /* perf_hist_config */
19 #include "util/llvm-utils.h"   /* perf_llvm_config */
20 #include "util/stat.h"  /* perf_stat__set_big_num */
21 #include "util/evsel.h"  /* evsel__hw_names, evsel__use_bpf_counters */
22 #include "build-id.h"
23 #include "debug.h"
24 #include "config.h"
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <linux/string.h>
30 #include <linux/zalloc.h>
31 #include <linux/ctype.h>
32
33 #define MAXNAME (256)
34
35 #define DEBUG_CACHE_DIR ".debug"
36
37
38 char buildid_dir[MAXPATHLEN]; /* root dir for buildid, binary cache */
39
40 static FILE *config_file;
41 static const char *config_file_name;
42 static int config_linenr;
43 static int config_file_eof;
44 static struct perf_config_set *config_set;
45
46 const char *config_exclusive_filename;
47
48 static int get_next_char(void)
49 {
50         int c;
51         FILE *f;
52
53         c = '\n';
54         if ((f = config_file) != NULL) {
55                 c = fgetc(f);
56                 if (c == '\r') {
57                         /* DOS like systems */
58                         c = fgetc(f);
59                         if (c != '\n') {
60                                 ungetc(c, f);
61                                 c = '\r';
62                         }
63                 }
64                 if (c == '\n')
65                         config_linenr++;
66                 if (c == EOF) {
67                         config_file_eof = 1;
68                         c = '\n';
69                 }
70         }
71         return c;
72 }
73
74 static char *parse_value(void)
75 {
76         static char value[1024];
77         int quote = 0, comment = 0, space = 0;
78         size_t len = 0;
79
80         for (;;) {
81                 int c = get_next_char();
82
83                 if (len >= sizeof(value) - 1)
84                         return NULL;
85                 if (c == '\n') {
86                         if (quote)
87                                 return NULL;
88                         value[len] = 0;
89                         return value;
90                 }
91                 if (comment)
92                         continue;
93                 if (isspace(c) && !quote) {
94                         space = 1;
95                         continue;
96                 }
97                 if (!quote) {
98                         if (c == ';' || c == '#') {
99                                 comment = 1;
100                                 continue;
101                         }
102                 }
103                 if (space) {
104                         if (len)
105                                 value[len++] = ' ';
106                         space = 0;
107                 }
108                 if (c == '\\') {
109                         c = get_next_char();
110                         switch (c) {
111                         case '\n':
112                                 continue;
113                         case 't':
114                                 c = '\t';
115                                 break;
116                         case 'b':
117                                 c = '\b';
118                                 break;
119                         case 'n':
120                                 c = '\n';
121                                 break;
122                         /* Some characters escape as themselves */
123                         case '\\': case '"':
124                                 break;
125                         /* Reject unknown escape sequences */
126                         default:
127                                 return NULL;
128                         }
129                         value[len++] = c;
130                         continue;
131                 }
132                 if (c == '"') {
133                         quote = 1-quote;
134                         continue;
135                 }
136                 value[len++] = c;
137         }
138 }
139
140 static inline int iskeychar(int c)
141 {
142         return isalnum(c) || c == '-' || c == '_';
143 }
144
145 static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
146 {
147         int c;
148         char *value;
149
150         /* Get the full name */
151         for (;;) {
152                 c = get_next_char();
153                 if (config_file_eof)
154                         break;
155                 if (!iskeychar(c))
156                         break;
157                 name[len++] = c;
158                 if (len >= MAXNAME)
159                         return -1;
160         }
161         name[len] = 0;
162         while (c == ' ' || c == '\t')
163                 c = get_next_char();
164
165         value = NULL;
166         if (c != '\n') {
167                 if (c != '=')
168                         return -1;
169                 value = parse_value();
170                 if (!value)
171                         return -1;
172         }
173         return fn(name, value, data);
174 }
175
176 static int get_extended_base_var(char *name, int baselen, int c)
177 {
178         do {
179                 if (c == '\n')
180                         return -1;
181                 c = get_next_char();
182         } while (isspace(c));
183
184         /* We require the format to be '[base "extension"]' */
185         if (c != '"')
186                 return -1;
187         name[baselen++] = '.';
188
189         for (;;) {
190                 int ch = get_next_char();
191
192                 if (ch == '\n')
193                         return -1;
194                 if (ch == '"')
195                         break;
196                 if (ch == '\\') {
197                         ch = get_next_char();
198                         if (ch == '\n')
199                                 return -1;
200                 }
201                 name[baselen++] = ch;
202                 if (baselen > MAXNAME / 2)
203                         return -1;
204         }
205
206         /* Final ']' */
207         if (get_next_char() != ']')
208                 return -1;
209         return baselen;
210 }
211
212 static int get_base_var(char *name)
213 {
214         int baselen = 0;
215
216         for (;;) {
217                 int c = get_next_char();
218                 if (config_file_eof)
219                         return -1;
220                 if (c == ']')
221                         return baselen;
222                 if (isspace(c))
223                         return get_extended_base_var(name, baselen, c);
224                 if (!iskeychar(c) && c != '.')
225                         return -1;
226                 if (baselen > MAXNAME / 2)
227                         return -1;
228                 name[baselen++] = tolower(c);
229         }
230 }
231
232 static int perf_parse_file(config_fn_t fn, void *data)
233 {
234         int comment = 0;
235         int baselen = 0;
236         static char var[MAXNAME];
237
238         /* U+FEFF Byte Order Mark in UTF8 */
239         static const unsigned char *utf8_bom = (unsigned char *) "\xef\xbb\xbf";
240         const unsigned char *bomptr = utf8_bom;
241
242         for (;;) {
243                 int line, c = get_next_char();
244
245                 if (bomptr && *bomptr) {
246                         /* We are at the file beginning; skip UTF8-encoded BOM
247                          * if present. Sane editors won't put this in on their
248                          * own, but e.g. Windows Notepad will do it happily. */
249                         if ((unsigned char) c == *bomptr) {
250                                 bomptr++;
251                                 continue;
252                         } else {
253                                 /* Do not tolerate partial BOM. */
254                                 if (bomptr != utf8_bom)
255                                         break;
256                                 /* No BOM at file beginning. Cool. */
257                                 bomptr = NULL;
258                         }
259                 }
260                 if (c == '\n') {
261                         if (config_file_eof)
262                                 return 0;
263                         comment = 0;
264                         continue;
265                 }
266                 if (comment || isspace(c))
267                         continue;
268                 if (c == '#' || c == ';') {
269                         comment = 1;
270                         continue;
271                 }
272                 if (c == '[') {
273                         baselen = get_base_var(var);
274                         if (baselen <= 0)
275                                 break;
276                         var[baselen++] = '.';
277                         var[baselen] = 0;
278                         continue;
279                 }
280                 if (!isalpha(c))
281                         break;
282                 var[baselen] = tolower(c);
283
284                 /*
285                  * The get_value function might or might not reach the '\n',
286                  * so saving the current line number for error reporting.
287                  */
288                 line = config_linenr;
289                 if (get_value(fn, data, var, baselen+1) < 0) {
290                         config_linenr = line;
291                         break;
292                 }
293         }
294         pr_err("bad config file line %d in %s\n", config_linenr, config_file_name);
295         return -1;
296 }
297
298 static int parse_unit_factor(const char *end, unsigned long *val)
299 {
300         if (!*end)
301                 return 1;
302         else if (!strcasecmp(end, "k")) {
303                 *val *= 1024;
304                 return 1;
305         }
306         else if (!strcasecmp(end, "m")) {
307                 *val *= 1024 * 1024;
308                 return 1;
309         }
310         else if (!strcasecmp(end, "g")) {
311                 *val *= 1024 * 1024 * 1024;
312                 return 1;
313         }
314         return 0;
315 }
316
317 static int perf_parse_llong(const char *value, long long *ret)
318 {
319         if (value && *value) {
320                 char *end;
321                 long long val = strtoll(value, &end, 0);
322                 unsigned long factor = 1;
323
324                 if (!parse_unit_factor(end, &factor))
325                         return 0;
326                 *ret = val * factor;
327                 return 1;
328         }
329         return 0;
330 }
331
332 static int perf_parse_long(const char *value, long *ret)
333 {
334         if (value && *value) {
335                 char *end;
336                 long val = strtol(value, &end, 0);
337                 unsigned long factor = 1;
338                 if (!parse_unit_factor(end, &factor))
339                         return 0;
340                 *ret = val * factor;
341                 return 1;
342         }
343         return 0;
344 }
345
346 static void bad_config(const char *name)
347 {
348         if (config_file_name)
349                 pr_warning("bad config value for '%s' in %s, ignoring...\n", name, config_file_name);
350         else
351                 pr_warning("bad config value for '%s', ignoring...\n", name);
352 }
353
354 int perf_config_u64(u64 *dest, const char *name, const char *value)
355 {
356         long long ret = 0;
357
358         if (!perf_parse_llong(value, &ret)) {
359                 bad_config(name);
360                 return -1;
361         }
362
363         *dest = ret;
364         return 0;
365 }
366
367 int perf_config_int(int *dest, const char *name, const char *value)
368 {
369         long ret = 0;
370         if (!perf_parse_long(value, &ret)) {
371                 bad_config(name);
372                 return -1;
373         }
374         *dest = ret;
375         return 0;
376 }
377
378 int perf_config_u8(u8 *dest, const char *name, const char *value)
379 {
380         long ret = 0;
381
382         if (!perf_parse_long(value, &ret)) {
383                 bad_config(name);
384                 return -1;
385         }
386         *dest = ret;
387         return 0;
388 }
389
390 static int perf_config_bool_or_int(const char *name, const char *value, int *is_bool)
391 {
392         int ret;
393
394         *is_bool = 1;
395         if (!value)
396                 return 1;
397         if (!*value)
398                 return 0;
399         if (!strcasecmp(value, "true") || !strcasecmp(value, "yes") || !strcasecmp(value, "on"))
400                 return 1;
401         if (!strcasecmp(value, "false") || !strcasecmp(value, "no") || !strcasecmp(value, "off"))
402                 return 0;
403         *is_bool = 0;
404         return perf_config_int(&ret, name, value) < 0 ? -1 : ret;
405 }
406
407 int perf_config_bool(const char *name, const char *value)
408 {
409         int discard;
410         return !!perf_config_bool_or_int(name, value, &discard);
411 }
412
413 static const char *perf_config_dirname(const char *name, const char *value)
414 {
415         if (!name)
416                 return NULL;
417         return value;
418 }
419
420 static int perf_buildid_config(const char *var, const char *value)
421 {
422         /* same dir for all commands */
423         if (!strcmp(var, "buildid.dir")) {
424                 const char *dir = perf_config_dirname(var, value);
425
426                 if (!dir) {
427                         pr_err("Invalid buildid directory!\n");
428                         return -1;
429                 }
430                 strncpy(buildid_dir, dir, MAXPATHLEN-1);
431                 buildid_dir[MAXPATHLEN-1] = '\0';
432         }
433
434         return 0;
435 }
436
437 static int perf_default_core_config(const char *var __maybe_unused,
438                                     const char *value __maybe_unused)
439 {
440         if (!strcmp(var, "core.proc-map-timeout"))
441                 proc_map_timeout = strtoul(value, NULL, 10);
442
443         /* Add other config variables here. */
444         return 0;
445 }
446
447 static int perf_ui_config(const char *var, const char *value)
448 {
449         /* Add other config variables here. */
450         if (!strcmp(var, "ui.show-headers"))
451                 symbol_conf.show_hist_headers = perf_config_bool(var, value);
452
453         return 0;
454 }
455
456 static int perf_stat_config(const char *var, const char *value)
457 {
458         if (!strcmp(var, "stat.big-num"))
459                 perf_stat__set_big_num(perf_config_bool(var, value));
460
461         if (!strcmp(var, "stat.no-csv-summary"))
462                 perf_stat__set_no_csv_summary(perf_config_bool(var, value));
463
464         if (!strcmp(var, "stat.bpf-counter-events"))
465                 evsel__bpf_counter_events = strdup(value);
466
467         /* Add other config variables here. */
468         return 0;
469 }
470
471 int perf_default_config(const char *var, const char *value,
472                         void *dummy __maybe_unused)
473 {
474         if (strstarts(var, "core."))
475                 return perf_default_core_config(var, value);
476
477         if (strstarts(var, "hist."))
478                 return perf_hist_config(var, value);
479
480         if (strstarts(var, "ui."))
481                 return perf_ui_config(var, value);
482
483         if (strstarts(var, "call-graph."))
484                 return perf_callchain_config(var, value);
485
486         if (strstarts(var, "llvm."))
487                 return perf_llvm_config(var, value);
488
489         if (strstarts(var, "buildid."))
490                 return perf_buildid_config(var, value);
491
492         if (strstarts(var, "stat."))
493                 return perf_stat_config(var, value);
494
495         /* Add other config variables here. */
496         return 0;
497 }
498
499 static int perf_config_from_file(config_fn_t fn, const char *filename, void *data)
500 {
501         int ret;
502         FILE *f = fopen(filename, "r");
503
504         ret = -1;
505         if (f) {
506                 config_file = f;
507                 config_file_name = filename;
508                 config_linenr = 1;
509                 config_file_eof = 0;
510                 ret = perf_parse_file(fn, data);
511                 fclose(f);
512                 config_file_name = NULL;
513         }
514         return ret;
515 }
516
517 const char *perf_etc_perfconfig(void)
518 {
519         static const char *system_wide;
520         if (!system_wide)
521                 system_wide = system_path(ETC_PERFCONFIG);
522         return system_wide;
523 }
524
525 static int perf_env_bool(const char *k, int def)
526 {
527         const char *v = getenv(k);
528         return v ? perf_config_bool(k, v) : def;
529 }
530
531 int perf_config_system(void)
532 {
533         return !perf_env_bool("PERF_CONFIG_NOSYSTEM", 0);
534 }
535
536 int perf_config_global(void)
537 {
538         return !perf_env_bool("PERF_CONFIG_NOGLOBAL", 0);
539 }
540
541 static char *home_perfconfig(void)
542 {
543         const char *home = NULL;
544         char *config;
545         struct stat st;
546
547         home = getenv("HOME");
548
549         /*
550          * Skip reading user config if:
551          *   - there is no place to read it from (HOME)
552          *   - we are asked not to (PERF_CONFIG_NOGLOBAL=1)
553          */
554         if (!home || !*home || !perf_config_global())
555                 return NULL;
556
557         config = strdup(mkpath("%s/.perfconfig", home));
558         if (config == NULL) {
559                 pr_warning("Not enough memory to process %s/.perfconfig, ignoring it.", home);
560                 return NULL;
561         }
562
563         if (stat(config, &st) < 0)
564                 goto out_free;
565
566         if (st.st_uid && (st.st_uid != geteuid())) {
567                 pr_warning("File %s not owned by current user or root, ignoring it.", config);
568                 goto out_free;
569         }
570
571         if (st.st_size)
572                 return config;
573
574 out_free:
575         free(config);
576         return NULL;
577 }
578
579 const char *perf_home_perfconfig(void)
580 {
581         static const char *config;
582         static bool failed;
583
584         config = failed ? NULL : home_perfconfig();
585         if (!config)
586                 failed = true;
587
588         return config;
589 }
590
591 static struct perf_config_section *find_section(struct list_head *sections,
592                                                 const char *section_name)
593 {
594         struct perf_config_section *section;
595
596         list_for_each_entry(section, sections, node)
597                 if (!strcmp(section->name, section_name))
598                         return section;
599
600         return NULL;
601 }
602
603 static struct perf_config_item *find_config_item(const char *name,
604                                                  struct perf_config_section *section)
605 {
606         struct perf_config_item *item;
607
608         list_for_each_entry(item, &section->items, node)
609                 if (!strcmp(item->name, name))
610                         return item;
611
612         return NULL;
613 }
614
615 static struct perf_config_section *add_section(struct list_head *sections,
616                                                const char *section_name)
617 {
618         struct perf_config_section *section = zalloc(sizeof(*section));
619
620         if (!section)
621                 return NULL;
622
623         INIT_LIST_HEAD(&section->items);
624         section->name = strdup(section_name);
625         if (!section->name) {
626                 pr_debug("%s: strdup failed\n", __func__);
627                 free(section);
628                 return NULL;
629         }
630
631         list_add_tail(&section->node, sections);
632         return section;
633 }
634
635 static struct perf_config_item *add_config_item(struct perf_config_section *section,
636                                                 const char *name)
637 {
638         struct perf_config_item *item = zalloc(sizeof(*item));
639
640         if (!item)
641                 return NULL;
642
643         item->name = strdup(name);
644         if (!item->name) {
645                 pr_debug("%s: strdup failed\n", __func__);
646                 free(item);
647                 return NULL;
648         }
649
650         list_add_tail(&item->node, &section->items);
651         return item;
652 }
653
654 static int set_value(struct perf_config_item *item, const char *value)
655 {
656         char *val = strdup(value);
657
658         if (!val)
659                 return -1;
660
661         zfree(&item->value);
662         item->value = val;
663         return 0;
664 }
665
666 static int collect_config(const char *var, const char *value,
667                           void *perf_config_set)
668 {
669         int ret = -1;
670         char *ptr, *key;
671         char *section_name, *name;
672         struct perf_config_section *section = NULL;
673         struct perf_config_item *item = NULL;
674         struct perf_config_set *set = perf_config_set;
675         struct list_head *sections;
676
677         if (set == NULL)
678                 return -1;
679
680         sections = &set->sections;
681         key = ptr = strdup(var);
682         if (!key) {
683                 pr_debug("%s: strdup failed\n", __func__);
684                 return -1;
685         }
686
687         section_name = strsep(&ptr, ".");
688         name = ptr;
689         if (name == NULL || value == NULL)
690                 goto out_free;
691
692         section = find_section(sections, section_name);
693         if (!section) {
694                 section = add_section(sections, section_name);
695                 if (!section)
696                         goto out_free;
697         }
698
699         item = find_config_item(name, section);
700         if (!item) {
701                 item = add_config_item(section, name);
702                 if (!item)
703                         goto out_free;
704         }
705
706         /* perf_config_set can contain both user and system config items.
707          * So we should know where each value is from.
708          * The classification would be needed when a particular config file
709          * is overwritten by setting feature i.e. set_config().
710          */
711         if (strcmp(config_file_name, perf_etc_perfconfig()) == 0) {
712                 section->from_system_config = true;
713                 item->from_system_config = true;
714         } else {
715                 section->from_system_config = false;
716                 item->from_system_config = false;
717         }
718
719         ret = set_value(item, value);
720
721 out_free:
722         free(key);
723         return ret;
724 }
725
726 int perf_config_set__collect(struct perf_config_set *set, const char *file_name,
727                              const char *var, const char *value)
728 {
729         config_file_name = file_name;
730         return collect_config(var, value, set);
731 }
732
733 static int perf_config_set__init(struct perf_config_set *set)
734 {
735         int ret = -1;
736
737         /* Setting $PERF_CONFIG makes perf read _only_ the given config file. */
738         if (config_exclusive_filename)
739                 return perf_config_from_file(collect_config, config_exclusive_filename, set);
740         if (perf_config_system() && !access(perf_etc_perfconfig(), R_OK)) {
741                 if (perf_config_from_file(collect_config, perf_etc_perfconfig(), set) < 0)
742                         goto out;
743         }
744         if (perf_config_global() && perf_home_perfconfig()) {
745                 if (perf_config_from_file(collect_config, perf_home_perfconfig(), set) < 0)
746                         goto out;
747         }
748
749 out:
750         return ret;
751 }
752
753 struct perf_config_set *perf_config_set__new(void)
754 {
755         struct perf_config_set *set = zalloc(sizeof(*set));
756
757         if (set) {
758                 INIT_LIST_HEAD(&set->sections);
759                 perf_config_set__init(set);
760         }
761
762         return set;
763 }
764
765 struct perf_config_set *perf_config_set__load_file(const char *file)
766 {
767         struct perf_config_set *set = zalloc(sizeof(*set));
768
769         if (set) {
770                 INIT_LIST_HEAD(&set->sections);
771                 perf_config_from_file(collect_config, file, set);
772         }
773
774         return set;
775 }
776
777 static int perf_config__init(void)
778 {
779         if (config_set == NULL)
780                 config_set = perf_config_set__new();
781
782         return config_set == NULL;
783 }
784
785 int perf_config_set(struct perf_config_set *set,
786                     config_fn_t fn, void *data)
787 {
788         int ret = 0;
789         char key[BUFSIZ];
790         struct perf_config_section *section;
791         struct perf_config_item *item;
792
793         perf_config_set__for_each_entry(set, section, item) {
794                 char *value = item->value;
795
796                 if (value) {
797                         scnprintf(key, sizeof(key), "%s.%s",
798                                   section->name, item->name);
799                         ret = fn(key, value, data);
800                         if (ret < 0) {
801                                 pr_err("Error: wrong config key-value pair %s=%s\n",
802                                        key, value);
803                                 /*
804                                  * Can't be just a 'break', as perf_config_set__for_each_entry()
805                                  * expands to two nested for() loops.
806                                  */
807                                 goto out;
808                         }
809                 }
810         }
811 out:
812         return ret;
813 }
814
815 int perf_config(config_fn_t fn, void *data)
816 {
817         if (config_set == NULL && perf_config__init())
818                 return -1;
819
820         return perf_config_set(config_set, fn, data);
821 }
822
823 void perf_config__exit(void)
824 {
825         perf_config_set__delete(config_set);
826         config_set = NULL;
827 }
828
829 void perf_config__refresh(void)
830 {
831         perf_config__exit();
832         perf_config__init();
833 }
834
835 static void perf_config_item__delete(struct perf_config_item *item)
836 {
837         zfree(&item->name);
838         zfree(&item->value);
839         free(item);
840 }
841
842 static void perf_config_section__purge(struct perf_config_section *section)
843 {
844         struct perf_config_item *item, *tmp;
845
846         list_for_each_entry_safe(item, tmp, &section->items, node) {
847                 list_del_init(&item->node);
848                 perf_config_item__delete(item);
849         }
850 }
851
852 static void perf_config_section__delete(struct perf_config_section *section)
853 {
854         perf_config_section__purge(section);
855         zfree(&section->name);
856         free(section);
857 }
858
859 static void perf_config_set__purge(struct perf_config_set *set)
860 {
861         struct perf_config_section *section, *tmp;
862
863         list_for_each_entry_safe(section, tmp, &set->sections, node) {
864                 list_del_init(&section->node);
865                 perf_config_section__delete(section);
866         }
867 }
868
869 void perf_config_set__delete(struct perf_config_set *set)
870 {
871         if (set == NULL)
872                 return;
873
874         perf_config_set__purge(set);
875         free(set);
876 }
877
878 /*
879  * Call this to report error for your variable that should not
880  * get a boolean value (i.e. "[my] var" means "true").
881  */
882 int config_error_nonbool(const char *var)
883 {
884         pr_err("Missing value for '%s'", var);
885         return -1;
886 }
887
888 void set_buildid_dir(const char *dir)
889 {
890         if (dir)
891                 scnprintf(buildid_dir, MAXPATHLEN, "%s", dir);
892
893         /* default to $HOME/.debug */
894         if (buildid_dir[0] == '\0') {
895                 char *home = getenv("HOME");
896
897                 if (home) {
898                         snprintf(buildid_dir, MAXPATHLEN, "%s/%s",
899                                  home, DEBUG_CACHE_DIR);
900                 } else {
901                         strncpy(buildid_dir, DEBUG_CACHE_DIR, MAXPATHLEN-1);
902                 }
903                 buildid_dir[MAXPATHLEN-1] = '\0';
904         }
905         /* for communicating with external commands */
906         setenv("PERF_BUILDID_DIR", buildid_dir, 1);
907 }