xref: /openbmc/linux/tools/lib/symbol/kallsyms.c (revision 53df2b93)
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