aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tools/perf/util/syscalltbl.c
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2025-03-18 22:07:32 -0700
committerNamhyung Kim <namhyung@kernel.org>2025-03-20 22:57:57 -0700
commit5c2938fe789c1876a35a1fbc24da3800b33adf26 (patch)
tree5785226022d3013e7aca6d4be1f0f95af1bcd4ff /tools/perf/util/syscalltbl.c
parentperf trace: Reorganize syscalls (diff)
downloadwireguard-linux-5c2938fe789c1876a35a1fbc24da3800b33adf26.tar.xz
wireguard-linux-5c2938fe789c1876a35a1fbc24da3800b33adf26.zip
perf syscalltbl: Remove struct syscalltbl
The syscalltbl held entries of system call name and number pairs, generated from a native syscalltbl at start up. As there are gaps in the system call number there is a notion of index into the table. Going forward we want the system call table to be identifiable by a machine type, for example, i386 vs x86-64. Change the interface to the syscalltbl so (1) a (currently unused machine type of EM_HOST) is passed (2) the index to syscall number and system call name mapping is computed at build time. Two tables are used for this, an array of system call number to name, an array of system call numbers sorted by the system call name. The sorted array doesn't store strings in part to save memory and relocations. The index notion is carried forward and is an index into the sorted array of system call numbers, the data structures are opaque (held only in syscalltbl.c), and so the number of indices for a machine type is exposed as a new API. The arrays are computed in the syscalltbl.sh script and so no start-up time computation and storage is necessary. Signed-off-by: Ian Rogers <irogers@google.com> Reviewed-by: Howard Chu <howardchu95@gmail.com> Reviewed-by: Charlie Jenkins <charlie@rivosinc.com> Reviewed-by: Namhyung Kim <namhyung@kernel.org> Acked-by: Arnaldo Carvalho de Melo <acme@kernel.org> Link: https://lore.kernel.org/r/20250319050741.269828-6-irogers@google.com Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Diffstat (limited to '')
-rw-r--r--tools/perf/util/syscalltbl.c113
1 files changed, 34 insertions, 79 deletions
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 2f76241494c8..760ac4d0869f 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -9,6 +9,7 @@
#include <stdlib.h>
#include <asm/bitsperlong.h>
#include <linux/compiler.h>
+#include <linux/kernel.h>
#include <linux/zalloc.h>
#include <string.h>
@@ -20,112 +21,66 @@
#include <asm/syscalls_32.h>
#endif
-const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID;
-static const char *const *syscalltbl_native = syscalltbl;
+const char *syscalltbl__name(int e_machine __maybe_unused, int id)
+{
+ if (id >= 0 && id <= (int)ARRAY_SIZE(syscall_num_to_name))
+ return syscall_num_to_name[id];
+ return NULL;
+}
-struct syscall {
- int id;
+struct syscall_cmp_key {
const char *name;
+ const char *const *tbl;
};
static int syscallcmpname(const void *vkey, const void *ventry)
{
- const char *key = vkey;
- const struct syscall *entry = ventry;
+ const struct syscall_cmp_key *key = vkey;
+ const uint16_t *entry = ventry;
- return strcmp(key, entry->name);
+ return strcmp(key->name, key->tbl[*entry]);
}
-static int syscallcmp(const void *va, const void *vb)
+int syscalltbl__id(int e_machine __maybe_unused, const char *name)
{
- const struct syscall *a = va, *b = vb;
-
- return strcmp(a->name, b->name);
+ struct syscall_cmp_key key = {
+ .name = name,
+ .tbl = syscall_num_to_name,
+ };
+ const int *id = bsearch(&key, syscall_sorted_names,
+ ARRAY_SIZE(syscall_sorted_names),
+ sizeof(syscall_sorted_names[0]),
+ syscallcmpname);
+
+ return id ? *id : -1;
}
-static int syscalltbl__init_native(struct syscalltbl *tbl)
+int syscalltbl__num_idx(int e_machine __maybe_unused)
{
- 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;
- tbl->syscalls.max_id = syscalltbl_native_max_id;
- return 0;
+ return ARRAY_SIZE(syscall_sorted_names);
}
-struct syscalltbl *syscalltbl__new(void)
+int syscalltbl__id_at_idx(int e_machine __maybe_unused, int idx)
{
- struct syscalltbl *tbl = malloc(sizeof(*tbl));
- if (tbl) {
- 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;
-}
-
-int syscalltbl__id_at_idx(struct syscalltbl *tbl, int idx)
-{
- struct syscall *syscalls = tbl->syscalls.entries;
-
- return idx < tbl->syscalls.nr_entries ? syscalls[idx].id : -1;
+ return syscall_sorted_names[idx];
}
-int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
+int syscalltbl__strglobmatch_next(int e_machine __maybe_unused, const char *syscall_glob, int *idx)
{
- int i;
- struct syscall *syscalls = tbl->syscalls.entries;
+ for (int i = *idx + 1; i < (int)ARRAY_SIZE(syscall_sorted_names); ++i) {
+ const char *name = syscall_num_to_name[syscall_sorted_names[i]];
- for (i = *idx + 1; i < tbl->syscalls.nr_entries; ++i) {
- if (strglobmatch(syscalls[i].name, syscall_glob)) {
+ if (strglobmatch(name, syscall_glob)) {
*idx = i;
- return syscalls[i].id;
+ return syscall_sorted_names[i];
}
}
return -1;
}
-int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
+int syscalltbl__strglobmatch_first(int e_machine, const char *syscall_glob, int *idx)
{
*idx = -1;
- return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
+ return syscalltbl__strglobmatch_next(e_machine, syscall_glob, idx);
}