hc
2024-08-16 a24a44ff9ca902811b99aa9663d697cf452e08ef
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// SPDX-License-Identifier: GPL-2.0
#include "symbol/kallsyms.h"
#include "api/io.h"
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
 
u8 kallsyms2elf_type(char type)
{
   type = tolower(type);
   return (type == 't' || type == 'w') ? STT_FUNC : STT_OBJECT;
}
 
bool kallsyms__is_function(char symbol_type)
{
   symbol_type = toupper(symbol_type);
   return symbol_type == 'T' || symbol_type == 'W';
}
 
static void read_to_eol(struct io *io)
{
   int ch;
 
   for (;;) {
       ch = io__get_char(io);
       if (ch < 0 || ch == '\n')
           return;
   }
}
 
int kallsyms__parse(const char *filename, void *arg,
           int (*process_symbol)(void *arg, const char *name,
                     char type, u64 start))
{
   struct io io;
   char bf[BUFSIZ];
   int err;
 
   io.fd = open(filename, O_RDONLY, 0);
 
   if (io.fd < 0)
       return -1;
 
   io__init(&io, io.fd, bf, sizeof(bf));
 
   err = 0;
   while (!io.eof) {
       __u64 start;
       int ch;
       size_t i;
       char symbol_type;
       char symbol_name[KSYM_NAME_LEN + 1];
 
       if (io__get_hex(&io, &start) != ' ') {
           read_to_eol(&io);
           continue;
       }
       symbol_type = io__get_char(&io);
       if (io__get_char(&io) != ' ') {
           read_to_eol(&io);
           continue;
       }
       for (i = 0; i < sizeof(symbol_name); i++) {
           ch = io__get_char(&io);
           if (ch < 0 || ch == '\n')
               break;
           symbol_name[i]  = ch;
       }
       symbol_name[i]  = '\0';
 
       err = process_symbol(arg, symbol_name, symbol_type, start);
       if (err)
           break;
   }
 
   close(io.fd);
   return err;
}