Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0 |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 2 | #include "symbol/kallsyms.h" |
Olivier Deprez | 157378f | 2022-04-04 15:47:50 +0200 | [diff] [blame^] | 3 | #include "api/io.h" |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 4 | #include <stdio.h> |
Olivier Deprez | 157378f | 2022-04-04 15:47:50 +0200 | [diff] [blame^] | 5 | #include <sys/stat.h> |
| 6 | #include <fcntl.h> |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 7 | |
| 8 | u8 kallsyms2elf_type(char type) |
| 9 | { |
| 10 | type = tolower(type); |
| 11 | return (type == 't' || type == 'w') ? STT_FUNC : STT_OBJECT; |
| 12 | } |
| 13 | |
| 14 | bool kallsyms__is_function(char symbol_type) |
| 15 | { |
| 16 | symbol_type = toupper(symbol_type); |
| 17 | return symbol_type == 'T' || symbol_type == 'W'; |
| 18 | } |
| 19 | |
Olivier Deprez | 157378f | 2022-04-04 15:47:50 +0200 | [diff] [blame^] | 20 | static void read_to_eol(struct io *io) |
David Brazdil | 0f672f6 | 2019-12-10 10:32:29 +0000 | [diff] [blame] | 21 | { |
Olivier Deprez | 157378f | 2022-04-04 15:47:50 +0200 | [diff] [blame^] | 22 | int ch; |
David Brazdil | 0f672f6 | 2019-12-10 10:32:29 +0000 | [diff] [blame] | 23 | |
Olivier Deprez | 157378f | 2022-04-04 15:47:50 +0200 | [diff] [blame^] | 24 | for (;;) { |
| 25 | ch = io__get_char(io); |
| 26 | if (ch < 0 || ch == '\n') |
| 27 | return; |
| 28 | } |
David Brazdil | 0f672f6 | 2019-12-10 10:32:29 +0000 | [diff] [blame] | 29 | } |
| 30 | |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 31 | int kallsyms__parse(const char *filename, void *arg, |
| 32 | int (*process_symbol)(void *arg, const char *name, |
| 33 | char type, u64 start)) |
| 34 | { |
Olivier Deprez | 157378f | 2022-04-04 15:47:50 +0200 | [diff] [blame^] | 35 | struct io io; |
| 36 | char bf[BUFSIZ]; |
| 37 | int err; |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 38 | |
Olivier Deprez | 157378f | 2022-04-04 15:47:50 +0200 | [diff] [blame^] | 39 | 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 Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 45 | |
| 46 | err = 0; |
Olivier Deprez | 157378f | 2022-04-04 15:47:50 +0200 | [diff] [blame^] | 47 | while (!io.eof) { |
| 48 | __u64 start; |
| 49 | int ch; |
| 50 | size_t i; |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 51 | char symbol_type; |
Olivier Deprez | 157378f | 2022-04-04 15:47:50 +0200 | [diff] [blame^] | 52 | char symbol_name[KSYM_NAME_LEN + 1]; |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 53 | |
Olivier Deprez | 157378f | 2022-04-04 15:47:50 +0200 | [diff] [blame^] | 54 | if (io__get_hex(&io, &start) != ' ') { |
| 55 | read_to_eol(&io); |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 56 | continue; |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 57 | } |
Olivier Deprez | 157378f | 2022-04-04 15:47:50 +0200 | [diff] [blame^] | 58 | 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 Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 70 | |
| 71 | err = process_symbol(arg, symbol_name, symbol_type, start); |
| 72 | if (err) |
| 73 | break; |
| 74 | } |
| 75 | |
Olivier Deprez | 157378f | 2022-04-04 15:47:50 +0200 | [diff] [blame^] | 76 | close(io.fd); |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 77 | return err; |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 78 | } |