Merge tag 'printk-for-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/pmladek...
[platform/kernel/linux-starfive.git] / tools / lib / symbol / kallsyms.c
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 }