| .. | .. |
|---|
| 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 | } |
|---|