qemu/accel/tcg/debuginfo.c
<<
>>
Prefs
   1/*
   2 * Debug information support.
   3 *
   4 * SPDX-License-Identifier: GPL-2.0-or-later
   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