Re: [PATCH v1 3/7] perf syscalltbl: Remove struct syscalltbl

Howard Chu
2025-02-05T00:18:26Z

Hello Ian,

On Fri, Jan 31, 2025 at 11:15 PM Ian Rogers <irogers@google.com> wrote:
>
> 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>
> ---
> tools/perf/builtin-trace.c | 88 +++++++++++++-----------
> tools/perf/scripts/syscalltbl.sh | 36 ++++------
> tools/perf/util/syscalltbl.c | 113 ++++++++++---------------------
> tools/perf/util/syscalltbl.h | 22 ++----
> 4 files changed, 103 insertions(+), 156 deletions(-)
>
> diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
> index 10d3ad0d21f7..7e3aa2f6c5e2 100644
> --- a/tools/perf/builtin-trace.c
> +++ b/tools/perf/builtin-trace.c
> @@ -143,7 +143,6 @@ struct syscall_fmt {
>
> struct trace {
> struct perf_tool tool;
> - struct syscalltbl *sctbl;
> struct {
> /** Sorted sycall numbers used by the trace. */
> struct syscall *table;
> @@ -2100,7 +2099,7 @@ static int syscall__read_info(struct syscall *sc, struct trace *trace)
> return 0;
> }
>
> - name = syscalltbl__name(trace->sctbl, sc->id);
> + name = syscalltbl__name(sc->e_machine, sc->id);
> if (name == NULL) {
> sc->nonexistent = true;
> return -EEXIST;
> @@ -2196,10 +2195,14 @@ static int trace__validate_ev_qualifier(struct trace *trace)
>
> strlist__for_each_entry(pos, trace->ev_qualifier) {
> const char *sc = pos->s;
> - int id = syscalltbl__id(trace->sctbl, sc), match_next = -1;
> + /*
> + * TODO: Assume more than the validation/warnings are all for
> + * the same binary type as perf.
> + */
> + int id = syscalltbl__id(EM_HOST, sc), match_next = -1;
>
> if (id < 0) {
> - id = syscalltbl__strglobmatch_first(trace->sctbl, sc, &match_next);
> + id = syscalltbl__strglobmatch_first(EM_HOST, sc, &match_next);
> if (id >= 0)
> goto matches;
>
> @@ -2219,7 +2222,7 @@ static int trace__validate_ev_qualifier(struct trace *trace)
> continue;
>
> while (1) {
> - id = syscalltbl__strglobmatch_next(trace->sctbl, sc, &match_next);
> + id = syscalltbl__strglobmatch_next(EM_HOST, sc, &match_next);
> if (id < 0)
> break;
> if (nr_allocated == nr_used) {
> @@ -2673,6 +2676,7 @@ static int trace__sys_enter(struct trace *trace, struct evsel *evsel,
> int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
> int augmented_args_size = 0;
> void *augmented_args = NULL;
> + /* TODO: get e_machine from thread. */
> struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
> struct thread_trace *ttrace;
>
> @@ -2747,6 +2751,7 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct evsel *evsel,
> struct thread_trace *ttrace;
> struct thread *thread;
> int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
> + /* TODO: get e_machine from thread. */
> struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
> char msg[1024];
> void *args, *augmented_args = NULL;
> @@ -2822,6 +2827,7 @@ static int trace__sys_exit(struct trace *trace, struct evsel *evsel,
> struct thread *thread;
> int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1, callchain_ret = 0, printed = 0;
> int alignment = trace->args_alignment;
> + /* TODO: get e_machine from thread. */
> struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
> struct thread_trace *ttrace;
>
> @@ -3175,6 +3181,7 @@ static int trace__event_handler(struct trace *trace, struct evsel *evsel,
>
> if (evsel == trace->syscalls.events.bpf_output) {
> int id = perf_evsel__sc_tp_uint(evsel, id, sample);
> + /* TODO: get e_machine from thread. */
> struct syscall *sc = trace__syscall_info(trace, evsel, EM_HOST, id);
>
> if (sc) {
> @@ -3678,9 +3685,9 @@ static struct bpf_program *trace__find_syscall_bpf_prog(struct trace *trace, str
> return trace->skel->progs.syscall_unaugmented;
> }
>
> -static void trace__init_syscall_bpf_progs(struct trace *trace, int id)
> +static void trace__init_syscall_bpf_progs(struct trace *trace, int e_machine, int id)
> {
> - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id);
> + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, id);
>
> if (sc == NULL)
> return;
> @@ -3689,22 +3696,22 @@ static void trace__init_syscall_bpf_progs(struct trace *trace, int id)
> sc->bpf_prog.sys_exit = trace__find_syscall_bpf_prog(trace, sc, sc->fmt ? sc->fmt->bpf_prog_name.sys_exit : NULL, "exit");
> }
>
> -static int trace__bpf_prog_sys_enter_fd(struct trace *trace, int id)
> +static int trace__bpf_prog_sys_enter_fd(struct trace *trace, int e_machine, int id)
> {
> - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id);
> + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, id);
> return sc ? bpf_program__fd(sc->bpf_prog.sys_enter) : bpf_program__fd(trace->skel->progs.syscall_unaugmented);
> }
>
> -static int trace__bpf_prog_sys_exit_fd(struct trace *trace, int id)
> +static int trace__bpf_prog_sys_exit_fd(struct trace *trace, int e_machine, int id)
> {
> - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, id);
> + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, id);
> return sc ? bpf_program__fd(sc->bpf_prog.sys_exit) : bpf_program__fd(trace->skel->progs.syscall_unaugmented);
> }
>
> -static int trace__bpf_sys_enter_beauty_map(struct trace *trace, int key, unsigned int *beauty_array)
> +static int trace__bpf_sys_enter_beauty_map(struct trace *trace, int e_machine, int key, unsigned int *beauty_array)
> {
> struct tep_format_field *field;
> - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, key);
> + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, key);
> const struct btf_type *bt;
> char *struct_offset, *tmp, name[32];
> bool can_augment = false;
> @@ -3800,9 +3807,9 @@ static struct bpf_program *trace__find_usable_bpf_prog_entry(struct trace *trace
> return NULL;
>
> try_to_find_pair:
> - for (int i = 0; i < trace->sctbl->syscalls.nr_entries; ++i) {
> - int id = syscalltbl__id_at_idx(trace->sctbl, i);
> - struct syscall *pair = trace__syscall_info(trace, NULL, EM_HOST, id);
> + for (int i = 0, num_idx = syscalltbl__num_idx(sc->e_machine); i < num_idx; ++i) {
> + int id = syscalltbl__id_at_idx(sc->e_machine, i);
> + struct syscall *pair = trace__syscall_info(trace, NULL, sc->e_machine, id);
> struct bpf_program *pair_prog;
> bool is_candidate = false;
>
> @@ -3886,7 +3893,7 @@ static struct bpf_program *trace__find_usable_bpf_prog_entry(struct trace *trace
> return NULL;
> }
>
> -static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace)
> +static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace, int e_machine)
> {
> int map_enter_fd = bpf_map__fd(trace->skel->maps.syscalls_sys_enter);
> int map_exit_fd = bpf_map__fd(trace->skel->maps.syscalls_sys_exit);
> @@ -3894,27 +3901,27 @@ static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace)
> int err = 0;
> unsigned int beauty_array[6];
>
> - for (int i = 0; i < trace->sctbl->syscalls.nr_entries; ++i) {
> - int prog_fd, key = syscalltbl__id_at_idx(trace->sctbl, i);
> + for (int i = 0, num_idx = syscalltbl__num_idx(e_machine); i < num_idx; ++i) {
> + int prog_fd, key = syscalltbl__id_at_idx(e_machine, i);
>
> if (!trace__syscall_enabled(trace, key))
> continue;
>
> - trace__init_syscall_bpf_progs(trace, key);
> + trace__init_syscall_bpf_progs(trace, e_machine, key);
>
> // It'll get at least the "!raw_syscalls:unaugmented"
> - prog_fd = trace__bpf_prog_sys_enter_fd(trace, key);
> + prog_fd = trace__bpf_prog_sys_enter_fd(trace, e_machine, key);
> err = bpf_map_update_elem(map_enter_fd, &key, &prog_fd, BPF_ANY);
> if (err)
> break;
> - prog_fd = trace__bpf_prog_sys_exit_fd(trace, key);
> + prog_fd = trace__bpf_prog_sys_exit_fd(trace, e_machine, key);
> err = bpf_map_update_elem(map_exit_fd, &key, &prog_fd, BPF_ANY);
> if (err)
> break;
>
> /* use beauty_map to tell BPF how many bytes to collect, set beauty_map's value here */
> memset(beauty_array, 0, sizeof(beauty_array));
> - err = trace__bpf_sys_enter_beauty_map(trace, key, (unsigned int *)beauty_array);
> + err = trace__bpf_sys_enter_beauty_map(trace, e_machine, key, (unsigned int *)beauty_array);
> if (err)
> continue;
> err = bpf_map_update_elem(beauty_map_fd, &key, beauty_array, BPF_ANY);
> @@ -3950,9 +3957,9 @@ static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace)
> * first and second arg (this one on the raw_syscalls:sys_exit prog
> * array tail call, then that one will be used.
> */
> - for (int i = 0; i < trace->sctbl->syscalls.nr_entries; ++i) {
> - int key = syscalltbl__id_at_idx(trace->sctbl, i);
> - struct syscall *sc = trace__syscall_info(trace, NULL, EM_HOST, key);
> + for (int i = 0, num_idx = syscalltbl__num_idx(e_machine); i < num_idx; ++i) {
> + int key = syscalltbl__id_at_idx(e_machine, i);
> + struct syscall *sc = trace__syscall_info(trace, NULL, e_machine, key);
> struct bpf_program *pair_prog;
> int prog_fd;
>
> @@ -4389,8 +4396,13 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
> goto out_error_mem;
>
> #ifdef HAVE_BPF_SKEL
> - if (trace->skel && trace->skel->progs.sys_enter)
> - trace__init_syscalls_bpf_prog_array_maps(trace);
> + if (trace->skel && trace->skel->progs.sys_enter) {
> + /*
> + * TODO: Initialize for all host binary machine types, not just
> + * those matching the perf binary.
> + */
> + trace__init_syscalls_bpf_prog_array_maps(trace, EM_HOST);
> + }
> #endif
>
> if (trace->ev_qualifier_ids.nr > 0) {
> @@ -4415,7 +4427,8 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
> * So just disable this beautifier (SCA_FD, SCA_FDAT) when 'close' is
> * not in use.
> */
> - trace->fd_path_disabled = !trace__syscall_enabled(trace, syscalltbl__id(trace->sctbl, "close"));
> + /* TODO: support for more than just perf binary machine type close. */
> + trace->fd_path_disabled = !trace__syscall_enabled(trace, syscalltbl__id(EM_HOST, "close"));
>
> err = trace__expand_filters(trace, &evsel);
> if (err)
> @@ -4688,8 +4701,7 @@ DEFINE_RESORT_RB(syscall_stats, a->msecs > b->msecs,
> entry->msecs = stats ? (u64)stats->stats.n * (avg_stats(&stats->stats) / NSEC_PER_MSEC) : 0;
> }
>
> -static size_t thread__dump_stats(struct thread_trace *ttrace,
> - struct trace *trace, FILE *fp)
> +static size_t thread__dump_stats(struct thread_trace *ttrace, struct trace *trace, int e_machine, FILE *fp)
> {
> size_t printed = 0;
> struct syscall *sc;
> @@ -4717,7 +4729,7 @@ static size_t thread__dump_stats(struct thread_trace *ttrace,
> pct = avg ? 100.0 * stddev_stats(&stats->stats) / avg : 0.0;
> avg /= NSEC_PER_MSEC;
>
> - sc = trace__syscall_info(trace, /*evsel=*/NULL, EM_HOST,
> + sc = trace__syscall_info(trace, /*evsel=*/NULL, e_machine,
> syscall_stats_entry->syscall);
> if (!sc)
> continue;
> @@ -4767,7 +4779,8 @@ static size_t trace__fprintf_thread(FILE *fp, struct thread *thread, struct trac
> else if (fputc('\n', fp) != EOF)
> ++printed;
>
> - printed += thread__dump_stats(ttrace, trace, fp);
> + /* TODO: get e_machine from thread. */
> + printed += thread__dump_stats(ttrace, trace, EM_HOST, fp);
>
> return printed;
> }
> @@ -4999,8 +5012,9 @@ static int trace__parse_events_option(const struct option *opt, const char *str,
> *sep = '\0';
>
> list = 0;
> - if (syscalltbl__id(trace->sctbl, s) >= 0 ||
> - syscalltbl__strglobmatch_first(trace->sctbl, s, &idx) >= 0) {
> + /* TODO: support for more than just perf binary machine type syscalls. */
> + if (syscalltbl__id(EM_HOST, s) >= 0 ||
> + syscalltbl__strglobmatch_first(EM_HOST, s, &idx) >= 0) {
> list = 1;
> goto do_concat;
> }
> @@ -5136,7 +5150,6 @@ static void trace__exit(struct trace *trace)
> syscall__exit(&trace->syscalls.table[i]);
> zfree(&trace->syscalls.table);
> }
> - syscalltbl__delete(trace->sctbl);
> zfree(&trace->perfconfig_events);
> }
>
> @@ -5282,9 +5295,8 @@ int cmd_trace(int argc, const char **argv)
> sigaction(SIGCHLD, &sigchld_act, NULL);
>
> trace.evlist = evlist__new();
> - trace.sctbl = syscalltbl__new();
>
> - if (trace.evlist == NULL || trace.sctbl == NULL) {
> + if (trace.evlist == NULL) {
> pr_err("Not enough memory to run!\n");
> err = -ENOMEM;
> goto out;
> diff --git a/tools/perf/scripts/syscalltbl.sh b/tools/perf/scripts/syscalltbl.sh
> index 1ce0d5aa8b50..a39b3013b103 100755
> --- a/tools/perf/scripts/syscalltbl.sh
> +++ b/tools/perf/scripts/syscalltbl.sh
> @@ -50,37 +50,27 @@ fi
> infile="$1"
> outfile="$2"
>
> -nxt=0
> -
> -syscall_macro() {
> - nr="$1"
> - name="$2"
> -
> - echo " [$nr] = \"$name\","
> -}
> -
> -emit() {
> - nr="$1"
> - entry="$2"
> -
> - syscall_macro "$nr" "$entry"
> -}
> -
> -echo "static const char *const syscalltbl[] = {" > $outfile
> -
> sorted_table=$(mktemp /tmp/syscalltbl.XXXXXX)
> grep -E "^[0-9]+[[:space:]]+$abis" "$infile" | sort -n > $sorted_table
>
> -max_nr=0
> +echo "static const char *const syscall_num_to_name[] = {" > $outfile
> # the params are: nr abi name entry compat
> # use _ for intentionally unused variables according to SC2034
> while read nr _ name _ _; do
> - emit "$nr" "$name" >> $outfile
> - max_nr=$nr
> + echo " [$nr] = \"$name\"," >> $outfile
> done < $sorted_table
> +echo "};" >> $outfile
>
> -rm -f $sorted_table
> +echo "static const uint16_t syscall_sorted_names[] = {" >> $outfile
>
> +# When sorting by name, add a suffix of 0s upto 20 characters so that system
> +# calls that differ with a numerical suffix don't sort before those
> +# without. This default behavior of sort differs from that of strcmp used at
> +# runtime. Use sed to strip the trailing 0s suffix afterwards.
> +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
> +while read name nr; do
> + echo " $nr, /* $name */" >> $outfile
> +done < $sorted_table
> echo "};" >> $outfile
>
> -echo "#define SYSCALLTBL_MAX_ID ${max_nr}" >> $outfile
> +rm -f $sorted_table
> 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);

This has puzzled me several times lol. Searching in
syscall_sorted_names returns an int id... I get that it's sorted by
name, but maybe call it syscall_ids_sorted_by_name, syscall_ids, or
syscall_ids_sorted instead?

> +
> + return id ? *id : -1;
> }
>
> -static int syscalltbl__init_native(struct syscalltbl *tbl)
> +int syscalltbl__num_idx(int e_machine __maybe_unused)

I haven't found many instances of *num_idx in the source tree
indicating the length of an array. Are you okay with
syscalltbl__nr_idx()?

Otherwise LGTM.

Thanks,
Howard
> {
> - 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);
> }
> diff --git a/tools/perf/util/syscalltbl.h b/tools/perf/util/syscalltbl.h
> index 362411a6d849..2bb628eff367 100644
> --- a/tools/perf/util/syscalltbl.h
> +++ b/tools/perf/util/syscalltbl.h
> @@ -2,22 +2,12 @@
> #ifndef __PERF_SYSCALLTBL_H
> #define __PERF_SYSCALLTBL_H
>
> -struct syscalltbl {
> - struct {
> - int max_id;
> - int nr_entries;
> - void *entries;
> - } syscalls;
> -};
> +const char *syscalltbl__name(int e_machine, int id);
> +int syscalltbl__id(int e_machine, const char *name);
> +int syscalltbl__num_idx(int e_machine);
> +int syscalltbl__id_at_idx(int e_machine, int idx);
>
> -struct syscalltbl *syscalltbl__new(void);
> -void syscalltbl__delete(struct syscalltbl *tbl);
> -
> -const char *syscalltbl__name(const struct syscalltbl *tbl, int id);
> -int syscalltbl__id(struct syscalltbl *tbl, const char *name);
> -int syscalltbl__id_at_idx(struct syscalltbl *tbl, int idx);
> -
> -int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx);
> -int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx);
> +int syscalltbl__strglobmatch_first(int e_machine, const char *syscall_glob, int *idx);
> +int syscalltbl__strglobmatch_next(int e_machine, const char *syscall_glob, int *idx);
>
> #endif /* __PERF_SYSCALLTBL_H */
> --
> 2.48.1.362.g079036d154-goog
>