linux/tools/lib/symbol/kallsyms.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include "symbol/kallsyms.h"
   3#include <stdio.h>
   4#include <stdlib.h>
   5
   6u8 kallsyms2elf_type(char type)
   7{
   8        type = tolower(type);
   9        return (type == 't' || type == 'w') ? STT_FUNC : STT_OBJECT;
  10}
  11
  12bool 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 */
  22int 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
  31int 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
  86out_failure:
  87        return -1;
  88}
  89