root/tools/lib/symbol/kallsyms.c
// SPDX-License-Identifier: GPL-2.0
#include "symbol/kallsyms.h"
#include "api/io.h"
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>

u8 kallsyms2elf_type(char type)
{
        type = tolower(type);
        return (type == 't' || type == 'w') ? STT_FUNC : STT_OBJECT;
}

bool kallsyms__is_function(char symbol_type)
{
        symbol_type = toupper(symbol_type);
        return symbol_type == 'T' || symbol_type == 'W';
}

static void read_to_eol(struct io *io)
{
        int ch;

        for (;;) {
                ch = io__get_char(io);
                if (ch < 0 || ch == '\n')
                        return;
        }
}

int kallsyms__parse(const char *filename, void *arg,
                    int (*process_symbol)(void *arg, const char *name,
                                          char type, u64 start))
{
        struct io io;
        char bf[BUFSIZ];
        int err;

        io.fd = open(filename, O_RDONLY, 0);

        if (io.fd < 0)
                return -1;

        io__init(&io, io.fd, bf, sizeof(bf));

        err = 0;
        while (!io.eof) {
                __u64 start;
                int ch;
                size_t i;
                char symbol_type;
                char symbol_name[KSYM_NAME_LEN + 1];

                if (io__get_hex(&io, &start) != ' ') {
                        read_to_eol(&io);
                        continue;
                }
                symbol_type = io__get_char(&io);
                if (io__get_char(&io) != ' ') {
                        read_to_eol(&io);
                        continue;
                }
                for (i = 0; i < sizeof(symbol_name); i++) {
                        ch = io__get_char(&io);
                        if (ch < 0 || ch == '\n')
                                break;
                        symbol_name[i]  = ch;
                }
                symbol_name[i]  = '\0';

                err = process_symbol(arg, symbol_name, symbol_type, start);
                if (err)
                        break;
        }

        close(io.fd);
        return err;
}