diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-04-04 17:52:18 -0300 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-04-08 09:58:14 -0300 |
commit | 5af56fab2b11769e35ce96613d321bcc0f7b84c1 (patch) | |
tree | f49152e486b9fad3bf5f6165df0f6e4ad38b4341 /tools/perf/util/syscalltbl.c | |
parent | fd0db10268b3729eb466fd726a39ce7d800bb150 (diff) | |
download | blackbird-obmc-linux-5af56fab2b11769e35ce96613d321bcc0f7b84c1.tar.gz blackbird-obmc-linux-5af56fab2b11769e35ce96613d321bcc0f7b84c1.zip |
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",
<SNIP>
[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 <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-02uuamkxgccczdth8komspgp@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/syscalltbl.c')
-rw-r--r-- | tools/perf/util/syscalltbl.c | 89 |
1 files changed, 87 insertions, 2 deletions
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,21 +14,105 @@ */ #include "syscalltbl.h" +#include <stdlib.h> + +#ifdef HAVE_SYSCALL_TABLE +#include <linux/compiler.h> #include <string.h> -#include <libaudit.h> +#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 <libaudit.h> + +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 */ |