xref: /linux/tools/perf/util/syscalltbl.c (revision 5c2938fe789c1876a35a1fbc24da3800b33adf26)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * System call table mapper
4  *
5  * (C) 2016 Arnaldo Carvalho de Melo <acme@redhat.com>
6  */
7 
8 #include "syscalltbl.h"
9 #include <stdlib.h>
10 #include <asm/bitsperlong.h>
11 #include <linux/compiler.h>
12 #include <linux/kernel.h>
13 #include <linux/zalloc.h>
14 
15 #include <string.h>
16 #include "string2.h"
17 
18 #if __BITS_PER_LONG == 64
19   #include <asm/syscalls_64.h>
20 #else
21   #include <asm/syscalls_32.h>
22 #endif
23 
24 const char *syscalltbl__name(int e_machine __maybe_unused, int id)
25 {
26 	if (id >= 0 && id <= (int)ARRAY_SIZE(syscall_num_to_name))
27 		return syscall_num_to_name[id];
28 	return NULL;
29 }
30 
31 struct syscall_cmp_key {
32 	const char *name;
33 	const char *const *tbl;
34 };
35 
36 static int syscallcmpname(const void *vkey, const void *ventry)
37 {
38 	const struct syscall_cmp_key *key = vkey;
39 	const uint16_t *entry = ventry;
40 
41 	return strcmp(key->name, key->tbl[*entry]);
42 }
43 
44 int syscalltbl__id(int e_machine __maybe_unused, const char *name)
45 {
46 	struct syscall_cmp_key key = {
47 		.name = name,
48 		.tbl = syscall_num_to_name,
49 	};
50 	const int *id = bsearch(&key, syscall_sorted_names,
51 				ARRAY_SIZE(syscall_sorted_names),
52 				sizeof(syscall_sorted_names[0]),
53 				syscallcmpname);
54 
55 	return id ? *id : -1;
56 }
57 
58 int syscalltbl__num_idx(int e_machine __maybe_unused)
59 {
60 	return ARRAY_SIZE(syscall_sorted_names);
61 }
62 
63 int syscalltbl__id_at_idx(int e_machine __maybe_unused, int idx)
64 {
65 	return syscall_sorted_names[idx];
66 }
67 
68 int syscalltbl__strglobmatch_next(int e_machine __maybe_unused, const char *syscall_glob, int *idx)
69 {
70 	for (int i = *idx + 1; i < (int)ARRAY_SIZE(syscall_sorted_names); ++i) {
71 		const char *name = syscall_num_to_name[syscall_sorted_names[i]];
72 
73 		if (strglobmatch(name, syscall_glob)) {
74 			*idx = i;
75 			return syscall_sorted_names[i];
76 		}
77 	}
78 
79 	return -1;
80 }
81 
82 int syscalltbl__strglobmatch_first(int e_machine, const char *syscall_glob, int *idx)
83 {
84 	*idx = -1;
85 	return syscalltbl__strglobmatch_next(e_machine, syscall_glob, idx);
86 }
87