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