.. | .. |
---|
1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
---|
2 | | -#include <ctype.h> |
---|
3 | 2 | #include "symbol/kallsyms.h" |
---|
| 3 | +#include "api/io.h" |
---|
4 | 4 | #include <stdio.h> |
---|
5 | | -#include <stdlib.h> |
---|
| 5 | +#include <sys/stat.h> |
---|
| 6 | +#include <fcntl.h> |
---|
6 | 7 | |
---|
7 | 8 | u8 kallsyms2elf_type(char type) |
---|
8 | 9 | { |
---|
.. | .. |
---|
16 | 17 | return symbol_type == 'T' || symbol_type == 'W'; |
---|
17 | 18 | } |
---|
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 | + |
---|
19 | 31 | int kallsyms__parse(const char *filename, void *arg, |
---|
20 | 32 | int (*process_symbol)(void *arg, const char *name, |
---|
21 | 33 | char type, u64 start)) |
---|
22 | 34 | { |
---|
23 | | - char *line = NULL; |
---|
24 | | - size_t n; |
---|
25 | | - int err = -1; |
---|
26 | | - FILE *file = fopen(filename, "r"); |
---|
| 35 | + struct io io; |
---|
| 36 | + char bf[BUFSIZ]; |
---|
| 37 | + int err; |
---|
27 | 38 | |
---|
28 | | - if (file == NULL) |
---|
29 | | - goto out_failure; |
---|
| 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)); |
---|
30 | 45 | |
---|
31 | 46 | err = 0; |
---|
32 | | - |
---|
33 | | - while (!feof(file)) { |
---|
34 | | - u64 start; |
---|
35 | | - int line_len, len; |
---|
| 47 | + while (!io.eof) { |
---|
| 48 | + __u64 start; |
---|
| 49 | + int ch; |
---|
| 50 | + size_t i; |
---|
36 | 51 | char symbol_type; |
---|
37 | | - char *symbol_name; |
---|
| 52 | + char symbol_name[KSYM_NAME_LEN + 1]; |
---|
38 | 53 | |
---|
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) |
---|
| 54 | + if (io__get_hex(&io, &start) != ' ') { |
---|
| 55 | + read_to_eol(&io); |
---|
49 | 56 | 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 | 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'; |
---|
64 | 70 | |
---|
65 | 71 | err = process_symbol(arg, symbol_name, symbol_type, start); |
---|
66 | 72 | if (err) |
---|
67 | 73 | break; |
---|
68 | 74 | } |
---|
69 | 75 | |
---|
70 | | - free(line); |
---|
71 | | - fclose(file); |
---|
| 76 | + close(io.fd); |
---|
72 | 77 | return err; |
---|
73 | | - |
---|
74 | | -out_failure: |
---|
75 | | - return -1; |
---|
76 | 78 | } |
---|