Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Ian Rogers and committed by
Namhyung Kim
5c2938fe 3d94b844

+118 -161
+64 -42
tools/perf/builtin-trace.c
··· 149 149 150 150 struct trace { 151 151 struct perf_tool tool; 152 - struct syscalltbl *sctbl; 153 152 struct { 154 153 /** Sorted sycall numbers used by the trace. */ 155 154 struct syscall *table; ··· 187 188 pid_t *entries; 188 189 struct bpf_map *map; 189 190 } filter_pids; 191 + /* 192 + * TODO: The map is from an ID (aka system call number) to struct 193 + * syscall_stats. If there is >1 e_machine, such as i386 and x86-64 194 + * processes, then the stats here will gather wrong the statistics for 195 + * the non EM_HOST system calls. A fix would be to add the e_machine 196 + * into the key, but this would make the code inconsistent with the 197 + * per-thread version. 198 + */ 190 199 struct hashmap *syscall_stats; 191 200 double duration_filter; 192 201 double runtime_ms; ··· 2148 2141 return 0; 2149 2142 } 2150 2143 2151 - name = syscalltbl__name(trace->sctbl, sc->id); 2144 + name = syscalltbl__name(sc->e_machine, sc->id); 2152 2145 if (name == NULL) { 2153 2146 sc->nonexistent = true; 2154 2147 return -EEXIST; ··· 2248 2241 2249 2242 strlist__for_each_entry(pos, trace->ev_qualifier) { 2250 2243 const char *sc = pos->s; 2251 - int id = syscalltbl__id(trace->sctbl, sc), match_next = -1; 2244 + /* 2245 + * TODO: Assume more than the validation/warnings are all for 2246 + * the same binary type as perf. 2247 + */ 2248 + int id = syscalltbl__id(EM_HOST, sc), match_next = -1; 2252 2249 2253 2250 if (id < 0) { 2254 - id = syscalltbl__strglobmatch_first(trace->sctbl, sc, &match_next); 2251 + id = syscalltbl__strglobmatch_first(EM_HOST, sc, &match_next); 2255 2252 if (id >= 0) 2256 2253 goto matches; 2257 2254 ··· 2275 2264 continue; 2276 2265 2277 2266 while (1) { 2278 - id = syscalltbl__strglobmatch_next(trace->sctbl, sc, &match_next); 2267 + id = syscalltbl__strglobmatch_next(EM_HOST, sc, &match_next); 2279 2268 if (id < 0) 2280 2269 break; 2281 2270 if (nr_allocated == nr_used) { ··· 2733 2722 int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1; 2734 2723 int augmented_args_size = 0; 2735 2724 void *augmented_args = NULL; 2725 + /* TODO: get e_machine from thread. */ 2736 2726 struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id); 2737 2727 struct thread_trace *ttrace; 2738 2728 ··· 2808 2796 struct thread_trace *ttrace; 2809 2797 struct thread *thread; 2810 2798 int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1; 2799 + /* TODO: get e_machine from thread. */ 2811 2800 struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id); 2812 2801 char msg[1024]; 2813 2802 void *args, *augmented_args = NULL; ··· 2884 2871 struct thread *thread; 2885 2872 int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1, callchain_ret = 0, printed = 0; 2886 2873 int alignment = trace->args_alignment; 2874 + /* TODO: get e_machine from thread. */ 2887 2875 struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id); 2888 2876 struct thread_trace *ttrace; 2889 2877 ··· 3238 3224 3239 3225 if (evsel == trace->syscalls.events.bpf_output) { 3240 3226 int id = perf_evsel__sc_tp_uint(evsel, id, sample); 3227 + /* TODO: get e_machine from thread. */ 3241 3228 struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id); 3242 3229 3243 3230 if (sc) { ··· 3746 3731 return trace->skel->progs.syscall_unaugmented; 3747 3732 } 3748 3733 3749 - static void trace__init_syscall_bpf_progs(struct trace *trace, int id) 3734 + static void trace__init_syscall_bpf_progs(struct trace *trace, int e_machine, int id) 3750 3735 { 3751 - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id); 3736 + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, id); 3752 3737 3753 3738 if (sc == NULL) 3754 3739 return; ··· 3757 3742 sc->bpf_prog.sys_exit = trace__find_syscall_bpf_prog(trace, sc, sc->fmt ? sc->fmt->bpf_prog_name.sys_exit : NULL, "exit"); 3758 3743 } 3759 3744 3760 - static int trace__bpf_prog_sys_enter_fd(struct trace *trace, int id) 3745 + static int trace__bpf_prog_sys_enter_fd(struct trace *trace, int e_machine, int id) 3761 3746 { 3762 - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id); 3747 + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, id); 3763 3748 return sc ? bpf_program__fd(sc->bpf_prog.sys_enter) : bpf_program__fd(trace->skel->progs.syscall_unaugmented); 3764 3749 } 3765 3750 3766 - static int trace__bpf_prog_sys_exit_fd(struct trace *trace, int id) 3751 + static int trace__bpf_prog_sys_exit_fd(struct trace *trace, int e_machine, int id) 3767 3752 { 3768 - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id); 3753 + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, id); 3769 3754 return sc ? bpf_program__fd(sc->bpf_prog.sys_exit) : bpf_program__fd(trace->skel->progs.syscall_unaugmented); 3770 3755 } 3771 3756 3772 - static int trace__bpf_sys_enter_beauty_map(struct trace *trace, int key, unsigned int *beauty_array) 3757 + static int trace__bpf_sys_enter_beauty_map(struct trace *trace, int e_machine, int key, unsigned int *beauty_array) 3773 3758 { 3774 3759 struct tep_format_field *field; 3775 - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, key); 3760 + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, key); 3776 3761 const struct btf_type *bt; 3777 3762 char *struct_offset, *tmp, name[32]; 3778 3763 bool can_augment = false; ··· 3869 3854 return NULL; 3870 3855 3871 3856 try_to_find_pair: 3872 - for (int i = 0; i < trace->sctbl->syscalls.nr_entries; ++i) { 3873 - int id = syscalltbl__id_at_idx(trace->sctbl, i); 3857 + for (int i = 0, num_idx = syscalltbl__num_idx(sc.e_machine); i < num_idx; ++i) { 3858 + int id = syscalltbl__id_at_idx(sc.e_machine, i); 3874 3859 /* calling trace__syscall_info() may invalidate '_sc' */ 3875 3860 struct syscall *pair = trace__syscall_info(trace, NULL, sc.e_machine, id); 3876 3861 struct bpf_program *pair_prog; ··· 3956 3941 return NULL; 3957 3942 } 3958 3943 3959 - static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace) 3944 + static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace, int e_machine) 3960 3945 { 3961 3946 int map_enter_fd = bpf_map__fd(trace->skel->maps.syscalls_sys_enter); 3962 3947 int map_exit_fd = bpf_map__fd(trace->skel->maps.syscalls_sys_exit); ··· 3964 3949 int err = 0; 3965 3950 unsigned int beauty_array[6]; 3966 3951 3967 - for (int i = 0; i < trace->sctbl->syscalls.nr_entries; ++i) { 3968 - int prog_fd, key = syscalltbl__id_at_idx(trace->sctbl, i); 3952 + for (int i = 0, num_idx = syscalltbl__num_idx(e_machine); i < num_idx; ++i) { 3953 + int prog_fd, key = syscalltbl__id_at_idx(e_machine, i); 3969 3954 3970 3955 if (!trace__syscall_enabled(trace, key)) 3971 3956 continue; 3972 3957 3973 - trace__init_syscall_bpf_progs(trace, key); 3958 + trace__init_syscall_bpf_progs(trace, e_machine, key); 3974 3959 3975 3960 // It'll get at least the "!raw_syscalls:unaugmented" 3976 - prog_fd = trace__bpf_prog_sys_enter_fd(trace, key); 3961 + prog_fd = trace__bpf_prog_sys_enter_fd(trace, e_machine, key); 3977 3962 err = bpf_map_update_elem(map_enter_fd, &key, &prog_fd, BPF_ANY); 3978 3963 if (err) 3979 3964 break; 3980 - prog_fd = trace__bpf_prog_sys_exit_fd(trace, key); 3965 + prog_fd = trace__bpf_prog_sys_exit_fd(trace, e_machine, key); 3981 3966 err = bpf_map_update_elem(map_exit_fd, &key, &prog_fd, BPF_ANY); 3982 3967 if (err) 3983 3968 break; 3984 3969 3985 3970 /* use beauty_map to tell BPF how many bytes to collect, set beauty_map's value here */ 3986 3971 memset(beauty_array, 0, sizeof(beauty_array)); 3987 - err = trace__bpf_sys_enter_beauty_map(trace, key, (unsigned int *)beauty_array); 3972 + err = trace__bpf_sys_enter_beauty_map(trace, e_machine, key, (unsigned int *)beauty_array); 3988 3973 if (err) 3989 3974 continue; 3990 3975 err = bpf_map_update_elem(beauty_map_fd, &key, beauty_array, BPF_ANY); ··· 4020 4005 * first and second arg (this one on the raw_syscalls:sys_exit prog 4021 4006 * array tail call, then that one will be used. 4022 4007 */ 4023 - for (int i = 0; i < trace->sctbl->syscalls.nr_entries; ++i) { 4024 - int key = syscalltbl__id_at_idx(trace->sctbl, i); 4025 - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, key); 4008 + for (int i = 0, num_idx = syscalltbl__num_idx(e_machine); i < num_idx; ++i) { 4009 + int key = syscalltbl__id_at_idx(e_machine, i); 4010 + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, key); 4026 4011 struct bpf_program *pair_prog; 4027 4012 int prog_fd; 4028 4013 ··· 4047 4032 * Get syscall info again as find usable entry above might 4048 4033 * modify the syscall table and shuffle it. 4049 4034 */ 4050 - sc = trace__syscall_info(trace, NULL, EM_HOST, key); 4035 + sc = trace__syscall_info(trace, NULL, e_machine, key); 4051 4036 sc->bpf_prog.sys_enter = pair_prog; 4052 4037 4053 4038 /* ··· 4472 4457 goto out_error_mem; 4473 4458 4474 4459 #ifdef HAVE_BPF_SKEL 4475 - if (trace->skel && trace->skel->progs.sys_enter) 4476 - trace__init_syscalls_bpf_prog_array_maps(trace); 4460 + if (trace->skel && trace->skel->progs.sys_enter) { 4461 + /* 4462 + * TODO: Initialize for all host binary machine types, not just 4463 + * those matching the perf binary. 4464 + */ 4465 + trace__init_syscalls_bpf_prog_array_maps(trace, EM_HOST); 4466 + } 4477 4467 #endif 4478 4468 4479 4469 if (trace->ev_qualifier_ids.nr > 0) { ··· 4503 4483 * So just disable this beautifier (SCA_FD, SCA_FDAT) when 'close' is 4504 4484 * not in use. 4505 4485 */ 4506 - trace->fd_path_disabled = !trace__syscall_enabled(trace, syscalltbl__id(trace->sctbl, "close")); 4486 + /* TODO: support for more than just perf binary machine type close. */ 4487 + trace->fd_path_disabled = !trace__syscall_enabled(trace, syscalltbl__id(EM_HOST, "close")); 4507 4488 4508 4489 err = trace__expand_filters(trace, &evsel); 4509 4490 if (err) ··· 4817 4796 return entry; 4818 4797 } 4819 4798 4820 - static size_t syscall__dump_stats(struct trace *trace, FILE *fp, 4799 + static size_t syscall__dump_stats(struct trace *trace, int e_machine, FILE *fp, 4821 4800 struct hashmap *syscall_stats) 4822 4801 { 4823 4802 size_t printed = 0; ··· 4848 4827 pct = avg ? 100.0 * stddev_stats(&stats->stats) / avg : 0.0; 4849 4828 avg /= NSEC_PER_MSEC; 4850 4829 4851 - sc = trace__syscall_info(trace, /*evsel=*/NULL, EM_HOST, entry->syscall); 4830 + sc = trace__syscall_info(trace, /*evsel=*/NULL, e_machine, entry->syscall); 4852 4831 if (!sc) 4853 4832 continue; 4854 4833 ··· 4875 4854 } 4876 4855 4877 4856 static size_t thread__dump_stats(struct thread_trace *ttrace, 4878 - struct trace *trace, FILE *fp) 4857 + struct trace *trace, int e_machine, FILE *fp) 4879 4858 { 4880 - return syscall__dump_stats(trace, fp, ttrace->syscall_stats); 4859 + return syscall__dump_stats(trace, e_machine, fp, ttrace->syscall_stats); 4881 4860 } 4882 4861 4883 - static size_t system__dump_stats(struct trace *trace, FILE *fp) 4862 + static size_t system__dump_stats(struct trace *trace, int e_machine, FILE *fp) 4884 4863 { 4885 - return syscall__dump_stats(trace, fp, trace->syscall_stats); 4864 + return syscall__dump_stats(trace, e_machine, fp, trace->syscall_stats); 4886 4865 } 4887 4866 4888 4867 static size_t trace__fprintf_thread(FILE *fp, struct thread *thread, struct trace *trace) ··· 4908 4887 else if (fputc('\n', fp) != EOF) 4909 4888 ++printed; 4910 4889 4911 - printed += thread__dump_stats(ttrace, trace, fp); 4890 + /* TODO: get e_machine from thread. */ 4891 + printed += thread__dump_stats(ttrace, trace, EM_HOST, fp); 4912 4892 4913 4893 return printed; 4914 4894 } ··· 4970 4948 else if (fputc('\n', fp) != EOF) 4971 4949 ++printed; 4972 4950 4973 - printed += system__dump_stats(trace, fp); 4951 + /* TODO: get all system e_machines. */ 4952 + printed += system__dump_stats(trace, EM_HOST, fp); 4974 4953 4975 4954 return printed; 4976 4955 } ··· 5163 5140 *sep = '\0'; 5164 5141 5165 5142 list = 0; 5166 - if (syscalltbl__id(trace->sctbl, s) >= 0 || 5167 - syscalltbl__strglobmatch_first(trace->sctbl, s, &idx) >= 0) { 5143 + /* TODO: support for more than just perf binary machine type syscalls. */ 5144 + if (syscalltbl__id(EM_HOST, s) >= 0 || 5145 + syscalltbl__strglobmatch_first(EM_HOST, s, &idx) >= 0) { 5168 5146 list = 1; 5169 5147 goto do_concat; 5170 5148 } ··· 5318 5294 syscall__exit(&trace->syscalls.table[i]); 5319 5295 zfree(&trace->syscalls.table); 5320 5296 } 5321 - syscalltbl__delete(trace->sctbl); 5322 5297 zfree(&trace->perfconfig_events); 5323 5298 } 5324 5299 ··· 5466 5443 sigaction(SIGCHLD, &sigchld_act, NULL); 5467 5444 5468 5445 trace.evlist = evlist__new(); 5469 - trace.sctbl = syscalltbl__new(); 5470 5446 5471 - if (trace.evlist == NULL || trace.sctbl == NULL) { 5447 + if (trace.evlist == NULL) { 5472 5448 pr_err("Not enough memory to run!\n"); 5473 5449 err = -ENOMEM; 5474 5450 goto out;
+15 -25
tools/perf/scripts/syscalltbl.sh
··· 50 50 infile="$1" 51 51 outfile="$2" 52 52 53 - nxt=0 54 - 55 - syscall_macro() { 56 - nr="$1" 57 - name="$2" 58 - 59 - echo " [$nr] = \"$name\"," 60 - } 61 - 62 - emit() { 63 - nr="$1" 64 - entry="$2" 65 - 66 - syscall_macro "$nr" "$entry" 67 - } 68 - 69 - echo "static const char *const syscalltbl[] = {" > $outfile 70 - 71 53 sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX) 72 54 grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | sort -n > $sorted_table 73 55 74 - max_nr=0 56 + echo "static const char *const syscall_num_to_name[] = {" > $outfile 75 57 # the params are: nr abi name entry compat 76 58 # use _ for intentionally unused variables according to SC2034 77 59 while read nr _ name _ _; do 78 - emit "$nr" "$name" >> $outfile 79 - max_nr=$nr 60 + echo " [$nr] = \"$name\"," >> $outfile 80 61 done < $sorted_table 81 - 82 - rm -f $sorted_table 83 - 84 62 echo "};" >> $outfile 85 63 86 - echo "#define SYSCALLTBL_MAX_ID ${max_nr}" >> $outfile 64 + echo "static const uint16_t syscall_sorted_names[] = {" >> $outfile 65 + 66 + # When sorting by name, add a suffix of 0s upto 20 characters so that system 67 + # calls that differ with a numerical suffix don't sort before those 68 + # without. This default behavior of sort differs from that of strcmp used at 69 + # runtime. Use sed to strip the trailing 0s suffix afterwards. 70 + grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | awk '{printf $3; for (i = length($3); i < 20; i++) { printf "0"; }; print " " $1}'| sort | sed 's/\([a-zA-Z1-9]\+\)0\+ \([0-9]\+\)/\1 \2/' > $sorted_table 71 + while read name nr; do 72 + echo " $nr, /* $name */" >> $outfile 73 + done < $sorted_table 74 + echo "};" >> $outfile 75 + 76 + rm -f $sorted_table
+33 -78
tools/perf/util/syscalltbl.c
··· 9 9 #include <stdlib.h> 10 10 #include <asm/bitsperlong.h> 11 11 #include <linux/compiler.h> 12 + #include <linux/kernel.h> 12 13 #include <linux/zalloc.h> 13 14 14 15 #include <string.h> ··· 21 20 #include <asm/syscalls_32.h> 22 21 #endif 23 22 24 - const int syscalltbl_native_max_id = SYSCALLTBL_MAX_ID; 25 - static const char *const *syscalltbl_native = syscalltbl; 23 + const char *syscalltbl__name(int e_machine __maybe_unused, int id) 24 + { 25 + if (id >= 0 && id <= (int)ARRAY_SIZE(syscall_num_to_name)) 26 + return syscall_num_to_name[id]; 27 + return NULL; 28 + } 26 29 27 - struct syscall { 28 - int id; 30 + struct syscall_cmp_key { 29 31 const char *name; 32 + const char *const *tbl; 30 33 }; 31 34 32 35 static int syscallcmpname(const void *vkey, const void *ventry) 33 36 { 34 - const char *key = vkey; 35 - const struct syscall *entry = ventry; 37 + const struct syscall_cmp_key *key = vkey; 38 + const uint16_t *entry = ventry; 36 39 37 - return strcmp(key, entry->name); 40 + return strcmp(key->name, key->tbl[*entry]); 38 41 } 39 42 40 - static int syscallcmp(const void *va, const void *vb) 43 + int syscalltbl__id(int e_machine __maybe_unused, const char *name) 41 44 { 42 - const struct syscall *a = va, *b = vb; 45 + struct syscall_cmp_key key = { 46 + .name = name, 47 + .tbl = syscall_num_to_name, 48 + }; 49 + const int *id = bsearch(&key, syscall_sorted_names, 50 + ARRAY_SIZE(syscall_sorted_names), 51 + sizeof(syscall_sorted_names[0]), 52 + syscallcmpname); 43 53 44 - return strcmp(a->name, b->name); 54 + return id ? *id : -1; 45 55 } 46 56 47 - static int syscalltbl__init_native(struct syscalltbl *tbl) 57 + int syscalltbl__num_idx(int e_machine __maybe_unused) 48 58 { 49 - int nr_entries = 0, i, j; 50 - struct syscall *entries; 51 - 52 - for (i = 0; i <= syscalltbl_native_max_id; ++i) 53 - if (syscalltbl_native[i]) 54 - ++nr_entries; 55 - 56 - entries = tbl->syscalls.entries = malloc(sizeof(struct syscall) * nr_entries); 57 - if (tbl->syscalls.entries == NULL) 58 - return -1; 59 - 60 - for (i = 0, j = 0; i <= syscalltbl_native_max_id; ++i) { 61 - if (syscalltbl_native[i]) { 62 - entries[j].name = syscalltbl_native[i]; 63 - entries[j].id = i; 64 - ++j; 65 - } 66 - } 67 - 68 - qsort(tbl->syscalls.entries, nr_entries, sizeof(struct syscall), syscallcmp); 69 - tbl->syscalls.nr_entries = nr_entries; 70 - tbl->syscalls.max_id = syscalltbl_native_max_id; 71 - return 0; 59 + return ARRAY_SIZE(syscall_sorted_names); 72 60 } 73 61 74 - struct syscalltbl *syscalltbl__new(void) 62 + int syscalltbl__id_at_idx(int e_machine __maybe_unused, int idx) 75 63 { 76 - struct syscalltbl *tbl = malloc(sizeof(*tbl)); 77 - if (tbl) { 78 - if (syscalltbl__init_native(tbl)) { 79 - free(tbl); 80 - return NULL; 81 - } 82 - } 83 - return tbl; 64 + return syscall_sorted_names[idx]; 84 65 } 85 66 86 - void syscalltbl__delete(struct syscalltbl *tbl) 67 + int syscalltbl__strglobmatch_next(int e_machine __maybe_unused, const char *syscall_glob, int *idx) 87 68 { 88 - zfree(&tbl->syscalls.entries); 89 - free(tbl); 90 - } 69 + for (int i = *idx + 1; i < (int)ARRAY_SIZE(syscall_sorted_names); ++i) { 70 + const char *name = syscall_num_to_name[syscall_sorted_names[i]]; 91 71 92 - const char *syscalltbl__name(const struct syscalltbl *tbl __maybe_unused, int id) 93 - { 94 - return id <= syscalltbl_native_max_id ? syscalltbl_native[id]: NULL; 95 - } 96 - 97 - int syscalltbl__id(struct syscalltbl *tbl, const char *name) 98 - { 99 - struct syscall *sc = bsearch(name, tbl->syscalls.entries, 100 - tbl->syscalls.nr_entries, sizeof(*sc), 101 - syscallcmpname); 102 - 103 - return sc ? sc->id : -1; 104 - } 105 - 106 - int syscalltbl__id_at_idx(struct syscalltbl *tbl, int idx) 107 - { 108 - struct syscall *syscalls = tbl->syscalls.entries; 109 - 110 - return idx < tbl->syscalls.nr_entries ? syscalls[idx].id : -1; 111 - } 112 - 113 - int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx) 114 - { 115 - int i; 116 - struct syscall *syscalls = tbl->syscalls.entries; 117 - 118 - for (i = *idx + 1; i < tbl->syscalls.nr_entries; ++i) { 119 - if (strglobmatch(syscalls[i].name, syscall_glob)) { 72 + if (strglobmatch(name, syscall_glob)) { 120 73 *idx = i; 121 - return syscalls[i].id; 74 + return syscall_sorted_names[i]; 122 75 } 123 76 } 124 77 125 78 return -1; 126 79 } 127 80 128 - int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx) 81 + int syscalltbl__strglobmatch_first(int e_machine, const char *syscall_glob, int *idx) 129 82 { 130 83 *idx = -1; 131 - return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx); 84 + return syscalltbl__strglobmatch_next(e_machine, syscall_glob, idx); 132 85 }
+6 -16
tools/perf/util/syscalltbl.h
··· 2 2 #ifndef __PERF_SYSCALLTBL_H 3 3 #define __PERF_SYSCALLTBL_H 4 4 5 - struct syscalltbl { 6 - struct { 7 - int max_id; 8 - int nr_entries; 9 - void *entries; 10 - } syscalls; 11 - }; 5 + const char *syscalltbl__name(int e_machine, int id); 6 + int syscalltbl__id(int e_machine, const char *name); 7 + int syscalltbl__num_idx(int e_machine); 8 + int syscalltbl__id_at_idx(int e_machine, int idx); 12 9 13 - struct syscalltbl *syscalltbl__new(void); 14 - void syscalltbl__delete(struct syscalltbl *tbl); 15 - 16 - const char *syscalltbl__name(const struct syscalltbl *tbl, int id); 17 - int syscalltbl__id(struct syscalltbl *tbl, const char *name); 18 - int syscalltbl__id_at_idx(struct syscalltbl *tbl, int idx); 19 - 20 - int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx); 21 - int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx); 10 + int syscalltbl__strglobmatch_first(int e_machine, const char *syscall_glob, int *idx); 11 + int syscalltbl__strglobmatch_next(int e_machine, const char *syscall_glob, int *idx); 22 12 23 13 #endif /* __PERF_SYSCALLTBL_H */