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