blob: e335ac2b9e19725790b347e5aee4a30d9f04e738 [file] [log] [blame]
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001// SPDX-License-Identifier: GPL-2.0
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002#include "symbol/kallsyms.h"
Olivier Deprez157378f2022-04-04 15:47:50 +02003#include "api/io.h"
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00004#include <stdio.h>
Olivier Deprez157378f2022-04-04 15:47:50 +02005#include <sys/stat.h>
6#include <fcntl.h>
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00007
8u8 kallsyms2elf_type(char type)
9{
10 type = tolower(type);
11 return (type == 't' || type == 'w') ? STT_FUNC : STT_OBJECT;
12}
13
14bool kallsyms__is_function(char symbol_type)
15{
16 symbol_type = toupper(symbol_type);
17 return symbol_type == 'T' || symbol_type == 'W';
18}
19
Olivier Deprez157378f2022-04-04 15:47:50 +020020static void read_to_eol(struct io *io)
David Brazdil0f672f62019-12-10 10:32:29 +000021{
Olivier Deprez157378f2022-04-04 15:47:50 +020022 int ch;
David Brazdil0f672f62019-12-10 10:32:29 +000023
Olivier Deprez157378f2022-04-04 15:47:50 +020024 for (;;) {
25 ch = io__get_char(io);
26 if (ch < 0 || ch == '\n')
27 return;
28 }
David Brazdil0f672f62019-12-10 10:32:29 +000029}
30
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000031int kallsyms__parse(const char *filename, void *arg,
32 int (*process_symbol)(void *arg, const char *name,
33 char type, u64 start))
34{
Olivier Deprez157378f2022-04-04 15:47:50 +020035 struct io io;
36 char bf[BUFSIZ];
37 int err;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000038
Olivier Deprez157378f2022-04-04 15:47:50 +020039 io.fd = open(filename, O_RDONLY, 0);
40
41 if (io.fd < 0)
42 return -1;
43
44 io__init(&io, io.fd, bf, sizeof(bf));
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000045
46 err = 0;
Olivier Deprez157378f2022-04-04 15:47:50 +020047 while (!io.eof) {
48 __u64 start;
49 int ch;
50 size_t i;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000051 char symbol_type;
Olivier Deprez157378f2022-04-04 15:47:50 +020052 char symbol_name[KSYM_NAME_LEN + 1];
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000053
Olivier Deprez157378f2022-04-04 15:47:50 +020054 if (io__get_hex(&io, &start) != ' ') {
55 read_to_eol(&io);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000056 continue;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000057 }
Olivier Deprez157378f2022-04-04 15:47:50 +020058 symbol_type = io__get_char(&io);
59 if (io__get_char(&io) != ' ') {
60 read_to_eol(&io);
61 continue;
62 }
63 for (i = 0; i < sizeof(symbol_name); i++) {
64 ch = io__get_char(&io);
65 if (ch < 0 || ch == '\n')
66 break;
67 symbol_name[i] = ch;
68 }
69 symbol_name[i] = '\0';
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000070
71 err = process_symbol(arg, symbol_name, symbol_type, start);
72 if (err)
73 break;
74 }
75
Olivier Deprez157378f2022-04-04 15:47:50 +020076 close(io.fd);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000077 return err;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000078}