linux/tools/testing/selftests/bpf/trace_helpers.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <stdio.h>
   3#include <stdlib.h>
   4#include <string.h>
   5#include <assert.h>
   6#include <errno.h>
   7#include <poll.h>
   8#include <unistd.h>
   9#include <linux/perf_event.h>
  10#include <sys/mman.h>
  11#include "trace_helpers.h"
  12
  13#define MAX_SYMS 300000
  14static struct ksym syms[MAX_SYMS];
  15static int sym_cnt;
  16
  17static int ksym_cmp(const void *p1, const void *p2)
  18{
  19        return ((struct ksym *)p1)->addr - ((struct ksym *)p2)->addr;
  20}
  21
  22int load_kallsyms(void)
  23{
  24        FILE *f = fopen("/proc/kallsyms", "r");
  25        char func[256], buf[256];
  26        char symbol;
  27        void *addr;
  28        int i = 0;
  29
  30        if (!f)
  31                return -ENOENT;
  32
  33        while (fgets(buf, sizeof(buf), f)) {
  34                if (sscanf(buf, "%p %c %s", &addr, &symbol, func) != 3)
  35                        break;
  36                if (!addr)
  37                        continue;
  38                syms[i].addr = (long) addr;
  39                syms[i].name = strdup(func);
  40                i++;
  41        }
  42        fclose(f);
  43        sym_cnt = i;
  44        qsort(syms, sym_cnt, sizeof(struct ksym), ksym_cmp);
  45        return 0;
  46}
  47
  48struct ksym *ksym_search(long key)
  49{
  50        int start = 0, end = sym_cnt;
  51        int result;
  52
  53        /* kallsyms not loaded. return NULL */
  54        if (sym_cnt <= 0)
  55                return NULL;
  56
  57        while (start < end) {
  58                size_t mid = start + (end - start) / 2;
  59
  60                result = key - syms[mid].addr;
  61                if (result < 0)
  62                        end = mid;
  63                else if (result > 0)
  64                        start = mid + 1;
  65                else
  66                        return &syms[mid];
  67        }
  68
  69        if (start >= 1 && syms[start - 1].addr < key &&
  70            key < syms[start].addr)
  71                /* valid ksym */
  72                return &syms[start - 1];
  73
  74        /* out of range. return _stext */
  75        return &syms[0];
  76}
  77
  78long ksym_get_addr(const char *name)
  79{
  80        int i;
  81
  82        for (i = 0; i < sym_cnt; i++) {
  83                if (strcmp(syms[i].name, name) == 0)
  84                        return syms[i].addr;
  85        }
  86
  87        return 0;
  88}
  89