| // 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 < KSYM_NAME_LEN; i++) { | |
| ch = io__get_char(&io); | |
| if (ch < 0 || ch == '\n') | |
| break; | |
| symbol_name[i] = ch; | |
| } | |
| symbol_name[i] = '\0'; | |
| if (i == KSYM_NAME_LEN) | |
| read_to_eol(&io); | |
| err = process_symbol(arg, symbol_name, symbol_type, start); | |
| if (err) | |
| break; | |
| } | |
| close(io.fd); | |
| return err; | |
| } |