From: Arnaldo Carvalho de Melo Date: Mon, 4 Apr 2016 20:52:18 +0000 (-0300) Subject: perf tools: Allow generating per-arch syscall table arrays X-Git-Tag: v4.7-rc1~191^2~39^2~3 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=5af56fab2b11769e35ce96613d321bcc0f7b84c1;p=karo-tx-linux.git perf tools: Allow generating per-arch syscall table arrays Tools should use a mechanism similar to arch/x86/entry/syscalls/ to generate a header file with the definitions for two variables: static const char *syscalltbl_x86_64[] = { [0] = "read", [1] = "write", [324] = "membarrier", [325] = "mlock2", [326] = "copy_file_range", }; static const int syscalltbl_x86_64_max_id = 326; In a per arch file that should then be included in tools/perf/util/syscalltbl.c. First one will be for x86_64. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-02uuamkxgccczdth8komspgp@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c index 1f13e57412eb..eb74a97b1f11 100644 --- a/tools/perf/util/syscalltbl.c +++ b/tools/perf/util/syscalltbl.c @@ -14,19 +14,103 @@ */ #include "syscalltbl.h" +#include + +#ifdef HAVE_SYSCALL_TABLE +#include #include -#include +#include "util.h" + +struct syscall { + int id; + const char *name; +}; +static int syscallcmpname(const void *vkey, const void *ventry) +{ + const char *key = vkey; + const struct syscall *entry = ventry; + + return strcmp(key, entry->name); +} + +static int syscallcmp(const void *va, const void *vb) +{ + const struct syscall *a = va, *b = vb; + + return strcmp(a->name, b->name); +} + +static int syscalltbl__init_native(struct syscalltbl *tbl) +{ + int nr_entries = 0, i, j; + struct syscall *entries; + + for (i = 0; i <= syscalltbl_native_max_id; ++i) + if (syscalltbl_native[i]) + ++nr_entries; + + entries = tbl->syscalls.entries = malloc(sizeof(struct syscall) * nr_entries); + if (tbl->syscalls.entries == NULL) + return -1; + + for (i = 0, j = 0; i <= syscalltbl_native_max_id; ++i) { + if (syscalltbl_native[i]) { + entries[j].name = syscalltbl_native[i]; + entries[j].id = i; + ++j; + } + } + + qsort(tbl->syscalls.entries, nr_entries, sizeof(struct syscall), syscallcmp); + tbl->syscalls.nr_entries = nr_entries; + return 0; +} struct syscalltbl *syscalltbl__new(void) { struct syscalltbl *tbl = malloc(sizeof(*tbl)); if (tbl) { - tbl->audit_machine = audit_detect_machine(); + if (syscalltbl__init_native(tbl)) { + free(tbl); + return NULL; + } } return tbl; } +void syscalltbl__delete(struct syscalltbl *tbl) +{ + zfree(&tbl->syscalls.entries); + free(tbl); +} + +const char *syscalltbl__name(const struct syscalltbl *tbl __maybe_unused, int id) +{ + return id <= syscalltbl_native_max_id ? syscalltbl_native[id]: NULL; +} + +int syscalltbl__id(struct syscalltbl *tbl, const char *name) +{ + struct syscall *sc = bsearch(name, tbl->syscalls.entries, + tbl->syscalls.nr_entries, sizeof(*sc), + syscallcmpname); + + return sc ? sc->id : -1; +} + +#else /* HAVE_SYSCALL_TABLE */ + +#include + +struct syscalltbl *syscalltbl__new(void) +{ + struct syscalltbl *tbl = malloc(sizeof(*tbl)); + if (tbl) + tbl->audit_machine = audit_detect_machine(); + return tbl; +} + void syscalltbl__delete(struct syscalltbl *tbl) { free(tbl); @@ -41,3 +125,4 @@ int syscalltbl__id(struct syscalltbl *tbl, const char *name) { return audit_name_to_syscall(name, tbl->audit_machine); } +#endif /* HAVE_SYSCALL_TABLE */ diff --git a/tools/perf/util/syscalltbl.h b/tools/perf/util/syscalltbl.h index 9dee73c2e082..e2951510484f 100644 --- a/tools/perf/util/syscalltbl.h +++ b/tools/perf/util/syscalltbl.h @@ -4,6 +4,10 @@ struct syscalltbl { union { int audit_machine; + struct { + int nr_entries; + void *entries; + } syscalls; }; };