kallsyms.c 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <ctype.h>
  3. #include "symbol/kallsyms.h"
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. u8 kallsyms2elf_type(char type)
  7. {
  8. type = tolower(type);
  9. return (type == 't' || type == 'w') ? STT_FUNC : STT_OBJECT;
  10. }
  11. bool kallsyms__is_function(char symbol_type)
  12. {
  13. symbol_type = toupper(symbol_type);
  14. return symbol_type == 'T' || symbol_type == 'W';
  15. }
  16. int kallsyms__parse(const char *filename, void *arg,
  17. int (*process_symbol)(void *arg, const char *name,
  18. char type, u64 start))
  19. {
  20. char *line = NULL;
  21. size_t n;
  22. int err = -1;
  23. FILE *file = fopen(filename, "r");
  24. if (file == NULL)
  25. goto out_failure;
  26. err = 0;
  27. while (!feof(file)) {
  28. u64 start;
  29. int line_len, len;
  30. char symbol_type;
  31. char *symbol_name;
  32. line_len = getline(&line, &n, file);
  33. if (line_len < 0 || !line)
  34. break;
  35. line[--line_len] = '\0'; /* \n */
  36. len = hex2u64(line, &start);
  37. /* Skip the line if we failed to parse the address. */
  38. if (!len)
  39. continue;
  40. len++;
  41. if (len + 2 >= line_len)
  42. continue;
  43. symbol_type = line[len];
  44. len += 2;
  45. symbol_name = line + len;
  46. len = line_len - len;
  47. if (len >= KSYM_NAME_LEN) {
  48. err = -1;
  49. break;
  50. }
  51. err = process_symbol(arg, symbol_name, symbol_type, start);
  52. if (err)
  53. break;
  54. }
  55. free(line);
  56. fclose(file);
  57. return err;
  58. out_failure:
  59. return -1;
  60. }