1 // SPDX-License-Identifier: GPL-2.0 2 #include "symbol/kallsyms.h" 3 #include <stdio.h> 4 #include <stdlib.h> 5 6 u8 kallsyms2elf_type(char type) 7 { 8 type = tolower(type); 9 return (type == 't' || type == 'w') ? STT_FUNC : STT_OBJECT; 10 } 11 12 bool kallsyms__is_function(char symbol_type) 13 { 14 symbol_type = toupper(symbol_type); 15 return symbol_type == 'T' || symbol_type == 'W'; 16 } 17 18 /* 19 * While we find nice hex chars, build a long_val. 20 * Return number of chars processed. 21 */ 22 int hex2u64(const char *ptr, u64 *long_val) 23 { 24 char *p; 25 26 *long_val = strtoull(ptr, &p, 16); 27 28 return p - ptr; 29 } 30 31 int kallsyms__parse(const char *filename, void *arg, 32 int (*process_symbol)(void *arg, const char *name, 33 char type, u64 start)) 34 { 35 char *line = NULL; 36 size_t n; 37 int err = -1; 38 FILE *file = fopen(filename, "r"); 39 40 if (file == NULL) 41 goto out_failure; 42 43 err = 0; 44 45 while (!feof(file)) { 46 u64 start; 47 int line_len, len; 48 char symbol_type; 49 char *symbol_name; 50 51 line_len = getline(&line, &n, file); 52 if (line_len < 0 || !line) 53 break; 54 55 line[--line_len] = '\0'; /* \n */ 56 57 len = hex2u64(line, &start); 58 59 /* Skip the line if we failed to parse the address. */ 60 if (!len) 61 continue; 62 63 len++; 64 if (len + 2 >= line_len) 65 continue; 66 67 symbol_type = line[len]; 68 len += 2; 69 symbol_name = line + len; 70 len = line_len - len; 71 72 if (len >= KSYM_NAME_LEN) { 73 err = -1; 74 break; 75 } 76 77 err = process_symbol(arg, symbol_name, symbol_type, start); 78 if (err) 79 break; 80 } 81 82 free(line); 83 fclose(file); 84 return err; 85 86 out_failure: 87 return -1; 88 } 89