1 // SPDX-License-Identifier: GPL-2.0 2 #include "symbol/kallsyms.h" 3 #include "api/io.h" 4 #include <stdio.h> 5 #include <sys/stat.h> 6 #include <fcntl.h> 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 /* 15 * While we find nice hex chars, build a long_val. 16 * Return number of chars processed. 17 */ 18 int hex2u64(const char *ptr, u64 *long_val) 19 { 20 char *p; 21 22 *long_val = strtoull(ptr, &p, 16); 23 24 return p - ptr; 25 } 26 27 bool kallsyms__is_function(char symbol_type) 28 { 29 symbol_type = toupper(symbol_type); 30 return symbol_type == 'T' || symbol_type == 'W'; 31 } 32 33 static void read_to_eol(struct io *io) 34 { 35 int ch; 36 37 for (;;) { 38 ch = io__get_char(io); 39 if (ch < 0 || ch == '\n') 40 return; 41 } 42 } 43 44 int kallsyms__parse(const char *filename, void *arg, 45 int (*process_symbol)(void *arg, const char *name, 46 char type, u64 start)) 47 { 48 struct io io; 49 char bf[BUFSIZ]; 50 int err; 51 52 io.fd = open(filename, O_RDONLY, 0); 53 54 if (io.fd < 0) 55 return -1; 56 57 io__init(&io, io.fd, bf, sizeof(bf)); 58 59 err = 0; 60 while (!io.eof) { 61 __u64 start; 62 int ch; 63 size_t i; 64 char symbol_type; 65 char symbol_name[KSYM_NAME_LEN + 1]; 66 67 if (io__get_hex(&io, &start) != ' ') { 68 read_to_eol(&io); 69 continue; 70 } 71 symbol_type = io__get_char(&io); 72 if (io__get_char(&io) != ' ') { 73 read_to_eol(&io); 74 continue; 75 } 76 for (i = 0; i < sizeof(symbol_name); i++) { 77 ch = io__get_char(&io); 78 if (ch < 0 || ch == '\n') 79 break; 80 symbol_name[i] = ch; 81 } 82 symbol_name[i] = '\0'; 83 84 err = process_symbol(arg, symbol_name, symbol_type, start); 85 if (err) 86 break; 87 } 88 89 close(io.fd); 90 return err; 91 } 92