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