diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-04-04 16:52:18 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-04-08 08:58:14 -0400 |
commit | 5af56fab2b11769e35ce96613d321bcc0f7b84c1 (patch) | |
tree | f49152e486b9fad3bf5f6165df0f6e4ad38b4341 /tools/perf/util/syscalltbl.c | |
parent | fd0db10268b3729eb466fd726a39ce7d800bb150 (diff) |
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 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include "syscalltbl.h" | 16 | #include "syscalltbl.h" |
17 | #include <stdlib.h> | ||
18 | |||
19 | #ifdef HAVE_SYSCALL_TABLE | ||
20 | #include <linux/compiler.h> | ||
17 | #include <string.h> | 21 | #include <string.h> |
18 | #include <libaudit.h> | 22 | #include "util.h" |
23 | |||
24 | struct syscall { | ||
25 | int id; | ||
26 | const char *name; | ||
27 | }; | ||
19 | 28 | ||
29 | static int syscallcmpname(const void *vkey, const void *ventry) | ||
30 | { | ||
31 | const char *key = vkey; | ||
32 | const struct syscall *entry = ventry; | ||
33 | |||
34 | return strcmp(key, entry->name); | ||
35 | } | ||
36 | |||
37 | static int syscallcmp(const void *va, const void *vb) | ||
38 | { | ||
39 | const struct syscall *a = va, *b = vb; | ||
40 | |||
41 | return strcmp(a->name, b->name); | ||
42 | } | ||
43 | |||
44 | static int syscalltbl__init_native(struct syscalltbl *tbl) | ||
45 | { | ||
46 | int nr_entries = 0, i, j; | ||
47 | struct syscall *entries; | ||
48 | |||
49 | for (i = 0; i <= syscalltbl_native_max_id; ++i) | ||
50 | if (syscalltbl_native[i]) | ||
51 | ++nr_entries; | ||
52 | |||
53 | entries = tbl->syscalls.entries = malloc(sizeof(struct syscall) * nr_entries); | ||
54 | if (tbl->syscalls.entries == NULL) | ||
55 | return -1; | ||
56 | |||
57 | for (i = 0, j = 0; i <= syscalltbl_native_max_id; ++i) { | ||
58 | if (syscalltbl_native[i]) { | ||
59 | entries[j].name = syscalltbl_native[i]; | ||
60 | entries[j].id = i; | ||
61 | ++j; | ||
62 | } | ||
63 | } | ||
64 | |||
65 | qsort(tbl->syscalls.entries, nr_entries, sizeof(struct syscall), syscallcmp); | ||
66 | tbl->syscalls.nr_entries = nr_entries; | ||
67 | return 0; | ||
68 | } | ||
20 | 69 | ||
21 | struct syscalltbl *syscalltbl__new(void) | 70 | struct syscalltbl *syscalltbl__new(void) |
22 | { | 71 | { |
23 | struct syscalltbl *tbl = malloc(sizeof(*tbl)); | 72 | struct syscalltbl *tbl = malloc(sizeof(*tbl)); |
24 | if (tbl) { | 73 | if (tbl) { |
25 | tbl->audit_machine = audit_detect_machine(); | 74 | if (syscalltbl__init_native(tbl)) { |
75 | free(tbl); | ||
76 | return NULL; | ||
77 | } | ||
26 | } | 78 | } |
27 | return tbl; | 79 | return tbl; |
28 | } | 80 | } |
29 | 81 | ||
30 | void syscalltbl__delete(struct syscalltbl *tbl) | 82 | void syscalltbl__delete(struct syscalltbl *tbl) |
31 | { | 83 | { |
84 | zfree(&tbl->syscalls.entries); | ||
85 | free(tbl); | ||
86 | } | ||
87 | |||
88 | const char *syscalltbl__name(const struct syscalltbl *tbl __maybe_unused, int id) | ||
89 | { | ||
90 | return id <= syscalltbl_native_max_id ? syscalltbl_native[id]: NULL; | ||
91 | } | ||
92 | |||
93 | int syscalltbl__id(struct syscalltbl *tbl, const char *name) | ||
94 | { | ||
95 | struct syscall *sc = bsearch(name, tbl->syscalls.entries, | ||
96 | tbl->syscalls.nr_entries, sizeof(*sc), | ||
97 | syscallcmpname); | ||
98 | |||
99 | return sc ? sc->id : -1; | ||
100 | } | ||
101 | |||
102 | #else /* HAVE_SYSCALL_TABLE */ | ||
103 | |||
104 | #include <libaudit.h> | ||
105 | |||
106 | struct syscalltbl *syscalltbl__new(void) | ||
107 | { | ||
108 | struct syscalltbl *tbl = malloc(sizeof(*tbl)); | ||
109 | if (tbl) | ||
110 | tbl->audit_machine = audit_detect_machine(); | ||
111 | return tbl; | ||
112 | } | ||
113 | |||
114 | void syscalltbl__delete(struct syscalltbl *tbl) | ||
115 | { | ||
32 | free(tbl); | 116 | free(tbl); |
33 | } | 117 | } |
34 | 118 | ||
@@ -41,3 +125,4 @@ int syscalltbl__id(struct syscalltbl *tbl, const char *name) | |||
41 | { | 125 | { |
42 | return audit_name_to_syscall(name, tbl->audit_machine); | 126 | return audit_name_to_syscall(name, tbl->audit_machine); |
43 | } | 127 | } |
128 | #endif /* HAVE_SYSCALL_TABLE */ | ||