2
0

debuginfo.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. * Debug information support.
  3. *
  4. * SPDX-License-Identifier: GPL-2.0-or-later
  5. */
  6. #include "qemu/osdep.h"
  7. #include "qemu/lockable.h"
  8. #include "tcg/debuginfo.h"
  9. #include <elfutils/libdwfl.h>
  10. static QemuMutex lock;
  11. static Dwfl *dwfl;
  12. static const Dwfl_Callbacks dwfl_callbacks = {
  13. .find_elf = NULL,
  14. .find_debuginfo = dwfl_standard_find_debuginfo,
  15. .section_address = NULL,
  16. .debuginfo_path = NULL,
  17. };
  18. __attribute__((constructor))
  19. static void debuginfo_init(void)
  20. {
  21. qemu_mutex_init(&lock);
  22. }
  23. void debuginfo_report_elf(const char *name, int fd, uint64_t bias)
  24. {
  25. QEMU_LOCK_GUARD(&lock);
  26. if (dwfl) {
  27. dwfl_report_begin_add(dwfl);
  28. } else {
  29. dwfl = dwfl_begin(&dwfl_callbacks);
  30. }
  31. if (dwfl) {
  32. dwfl_report_elf(dwfl, name, name, fd, bias, true);
  33. dwfl_report_end(dwfl, NULL, NULL);
  34. }
  35. }
  36. void debuginfo_lock(void)
  37. {
  38. qemu_mutex_lock(&lock);
  39. }
  40. void debuginfo_query(struct debuginfo_query *q, size_t n)
  41. {
  42. const char *symbol, *file;
  43. Dwfl_Module *dwfl_module;
  44. Dwfl_Line *dwfl_line;
  45. GElf_Off dwfl_offset;
  46. GElf_Sym dwfl_sym;
  47. size_t i;
  48. int line;
  49. if (!dwfl) {
  50. return;
  51. }
  52. for (i = 0; i < n; i++) {
  53. dwfl_module = dwfl_addrmodule(dwfl, q[i].address);
  54. if (!dwfl_module) {
  55. continue;
  56. }
  57. if (q[i].flags & DEBUGINFO_SYMBOL) {
  58. symbol = dwfl_module_addrinfo(dwfl_module, q[i].address,
  59. &dwfl_offset, &dwfl_sym,
  60. NULL, NULL, NULL);
  61. if (symbol) {
  62. q[i].symbol = symbol;
  63. q[i].offset = dwfl_offset;
  64. }
  65. }
  66. if (q[i].flags & DEBUGINFO_LINE) {
  67. dwfl_line = dwfl_module_getsrc(dwfl_module, q[i].address);
  68. if (dwfl_line) {
  69. file = dwfl_lineinfo(dwfl_line, NULL, &line, 0, NULL, NULL);
  70. if (file) {
  71. q[i].file = file;
  72. q[i].line = line;
  73. }
  74. }
  75. }
  76. }
  77. }
  78. void debuginfo_unlock(void)
  79. {
  80. qemu_mutex_unlock(&lock);
  81. }