qapi: allow unions to contain further unions
[qemu/armbru.git] / accel / tcg / debuginfo.c
blob71c66d04d1217bf76cc6b066353f59d642b204ce
1 /*
2 * Debug information support.
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
7 #include "qemu/osdep.h"
8 #include "qemu/lockable.h"
10 #include <elfutils/libdwfl.h>
12 #include "debuginfo.h"
14 static QemuMutex lock;
15 static Dwfl *dwfl;
16 static const Dwfl_Callbacks dwfl_callbacks = {
17 .find_elf = NULL,
18 .find_debuginfo = dwfl_standard_find_debuginfo,
19 .section_address = NULL,
20 .debuginfo_path = NULL,
23 __attribute__((constructor))
24 static void debuginfo_init(void)
26 qemu_mutex_init(&lock);
29 void debuginfo_report_elf(const char *name, int fd, uint64_t bias)
31 QEMU_LOCK_GUARD(&lock);
33 if (dwfl) {
34 dwfl_report_begin_add(dwfl);
35 } else {
36 dwfl = dwfl_begin(&dwfl_callbacks);
39 if (dwfl) {
40 dwfl_report_elf(dwfl, name, name, fd, bias, true);
41 dwfl_report_end(dwfl, NULL, NULL);
45 void debuginfo_lock(void)
47 qemu_mutex_lock(&lock);
50 void debuginfo_query(struct debuginfo_query *q, size_t n)
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;
60 if (!dwfl) {
61 return;
64 for (i = 0; i < n; i++) {
65 dwfl_module = dwfl_addrmodule(dwfl, q[i].address);
66 if (!dwfl_module) {
67 continue;
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;
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;
93 void debuginfo_unlock(void)
95 qemu_mutex_unlock(&lock);