root/tools/testing/selftests/bpf/trace_helpers.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ksym_cmp
  2. load_kallsyms
  3. ksym_search
  4. ksym_get_addr

   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
  14 static struct ksym syms[MAX_SYMS];
  15 static int sym_cnt;
  16 
  17 static int ksym_cmp(const void *p1, const void *p2)
  18 {
  19         return ((struct ksym *)p1)->addr - ((struct ksym *)p2)->addr;
  20 }
  21 
  22 int 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 
  48 struct 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 
  78 long 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 }

/* [<][>][^][v][top][bottom][index][help] */