linux/tools/perf/util/syscalltbl.c
<<
>>
Prefs
   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 <linux/compiler.h>
  11
  12#ifdef HAVE_SYSCALL_TABLE_SUPPORT
  13#include <linux/zalloc.h>
  14#include <string.h>
  15#include "string2.h"
  16
  17#if defined(__x86_64__)
  18#include <asm/syscalls_64.c>
  19const int syscalltbl_native_max_id = SYSCALLTBL_x86_64_MAX_ID;
  20static const char **syscalltbl_native = syscalltbl_x86_64;
  21#elif defined(__s390x__)
  22#include <asm/syscalls_64.c>
  23const int syscalltbl_native_max_id = SYSCALLTBL_S390_64_MAX_ID;
  24static const char **syscalltbl_native = syscalltbl_s390_64;
  25#elif defined(__powerpc64__)
  26#include <asm/syscalls_64.c>
  27const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_64_MAX_ID;
  28static const char **syscalltbl_native = syscalltbl_powerpc_64;
  29#elif defined(__powerpc__)
  30#include <asm/syscalls_32.c>
  31const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID;
  32static const char **syscalltbl_native = syscalltbl_powerpc_32;
  33#elif defined(__aarch64__)
  34#include <asm/syscalls.c>
  35const int syscalltbl_native_max_id = SYSCALLTBL_ARM64_MAX_ID;
  36static const char **syscalltbl_native = syscalltbl_arm64;
  37#endif
  38
  39struct syscall {
  40        int id;
  41        const char *name;
  42};
  43
  44static int syscallcmpname(const void *vkey, const void *ventry)
  45{
  46        const char *key = vkey;
  47        const struct syscall *entry = ventry;
  48
  49        return strcmp(key, entry->name);
  50}
  51
  52static int syscallcmp(const void *va, const void *vb)
  53{
  54        const struct syscall *a = va, *b = vb;
  55
  56        return strcmp(a->name, b->name);
  57}
  58
  59static int syscalltbl__init_native(struct syscalltbl *tbl)
  60{
  61        int nr_entries = 0, i, j;
  62        struct syscall *entries;
  63
  64        for (i = 0; i <= syscalltbl_native_max_id; ++i)
  65                if (syscalltbl_native[i])
  66                        ++nr_entries;
  67
  68        entries = tbl->syscalls.entries = malloc(sizeof(struct syscall) * nr_entries);
  69        if (tbl->syscalls.entries == NULL)
  70                return -1;
  71
  72        for (i = 0, j = 0; i <= syscalltbl_native_max_id; ++i) {
  73                if (syscalltbl_native[i]) {
  74                        entries[j].name = syscalltbl_native[i];
  75                        entries[j].id = i;
  76                        ++j;
  77                }
  78        }
  79
  80        qsort(tbl->syscalls.entries, nr_entries, sizeof(struct syscall), syscallcmp);
  81        tbl->syscalls.nr_entries = nr_entries;
  82        tbl->syscalls.max_id     = syscalltbl_native_max_id;
  83        return 0;
  84}
  85
  86struct syscalltbl *syscalltbl__new(void)
  87{
  88        struct syscalltbl *tbl = malloc(sizeof(*tbl));
  89        if (tbl) {
  90                if (syscalltbl__init_native(tbl)) {
  91                        free(tbl);
  92                        return NULL;
  93                }
  94        }
  95        return tbl;
  96}
  97
  98void syscalltbl__delete(struct syscalltbl *tbl)
  99{
 100        zfree(&tbl->syscalls.entries);
 101        free(tbl);
 102}
 103
 104const char *syscalltbl__name(const struct syscalltbl *tbl __maybe_unused, int id)
 105{
 106        return id <= syscalltbl_native_max_id ? syscalltbl_native[id]: NULL;
 107}
 108
 109int syscalltbl__id(struct syscalltbl *tbl, const char *name)
 110{
 111        struct syscall *sc = bsearch(name, tbl->syscalls.entries,
 112                                     tbl->syscalls.nr_entries, sizeof(*sc),
 113                                     syscallcmpname);
 114
 115        return sc ? sc->id : -1;
 116}
 117
 118int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
 119{
 120        int i;
 121        struct syscall *syscalls = tbl->syscalls.entries;
 122
 123        for (i = *idx + 1; i < tbl->syscalls.nr_entries; ++i) {
 124                if (strglobmatch(syscalls[i].name, syscall_glob)) {
 125                        *idx = i;
 126                        return syscalls[i].id;
 127                }
 128        }
 129
 130        return -1;
 131}
 132
 133int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
 134{
 135        *idx = -1;
 136        return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
 137}
 138
 139#else /* HAVE_SYSCALL_TABLE_SUPPORT */
 140
 141#include <libaudit.h>
 142
 143struct syscalltbl *syscalltbl__new(void)
 144{
 145        struct syscalltbl *tbl = malloc(sizeof(*tbl));
 146        if (tbl)
 147                tbl->audit_machine = audit_detect_machine();
 148        return tbl;
 149}
 150
 151void syscalltbl__delete(struct syscalltbl *tbl)
 152{
 153        free(tbl);
 154}
 155
 156const char *syscalltbl__name(const struct syscalltbl *tbl, int id)
 157{
 158        return audit_syscall_to_name(id, tbl->audit_machine);
 159}
 160
 161int syscalltbl__id(struct syscalltbl *tbl, const char *name)
 162{
 163        return audit_name_to_syscall(name, tbl->audit_machine);
 164}
 165
 166int syscalltbl__strglobmatch_next(struct syscalltbl *tbl __maybe_unused,
 167                                  const char *syscall_glob __maybe_unused, int *idx __maybe_unused)
 168{
 169        return -1;
 170}
 171
 172int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
 173{
 174        return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
 175}
 176#endif /* HAVE_SYSCALL_TABLE_SUPPORT */
 177