xref: /linux/tools/lib/symbol/kallsyms.c (revision 0526b56cbc3c489642bd6a5fe4b718dea7ef0ee8)
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 bool kallsyms__is_function(char symbol_type)
15 {
16 	symbol_type = toupper(symbol_type);
17 	return symbol_type == 'T' || symbol_type == 'W';
18 }
19 
20 static void read_to_eol(struct io *io)
21 {
22 	int ch;
23 
24 	for (;;) {
25 		ch = io__get_char(io);
26 		if (ch < 0 || ch == '\n')
27 			return;
28 	}
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 	struct io io;
36 	char bf[BUFSIZ];
37 	int err;
38 
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));
45 
46 	err = 0;
47 	while (!io.eof) {
48 		__u64 start;
49 		int ch;
50 		size_t i;
51 		char symbol_type;
52 		char symbol_name[KSYM_NAME_LEN + 1];
53 
54 		if (io__get_hex(&io, &start) != ' ') {
55 			read_to_eol(&io);
56 			continue;
57 		}
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';
70 
71 		err = process_symbol(arg, symbol_name, symbol_type, start);
72 		if (err)
73 			break;
74 	}
75 
76 	close(io.fd);
77 	return err;
78 }
79