Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add libdw-based functions for loading and querying debuginfo. Load debuginfo from the system and the linux-user loaders. This is useful for the upcoming perf support, which can then put human-readable guest symbols instead of raw guest PCs into perfmap and jitdump files. Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Message-Id: <20230112152013.125680-3-iii@linux.ibm.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
- Loading branch information
Showing
7 changed files
with
191 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/* | ||
* Debug information support. | ||
* | ||
* SPDX-License-Identifier: GPL-2.0-or-later | ||
*/ | ||
|
||
#include "qemu/osdep.h" | ||
#include "qemu/lockable.h" | ||
|
||
#include <elfutils/libdwfl.h> | ||
|
||
#include "debuginfo.h" | ||
|
||
static QemuMutex lock; | ||
static Dwfl *dwfl; | ||
static const Dwfl_Callbacks dwfl_callbacks = { | ||
.find_elf = NULL, | ||
.find_debuginfo = dwfl_standard_find_debuginfo, | ||
.section_address = NULL, | ||
.debuginfo_path = NULL, | ||
}; | ||
|
||
__attribute__((constructor)) | ||
static void debuginfo_init(void) | ||
{ | ||
qemu_mutex_init(&lock); | ||
} | ||
|
||
void debuginfo_report_elf(const char *name, int fd, uint64_t bias) | ||
{ | ||
QEMU_LOCK_GUARD(&lock); | ||
|
||
if (dwfl) { | ||
dwfl_report_begin_add(dwfl); | ||
} else { | ||
dwfl = dwfl_begin(&dwfl_callbacks); | ||
} | ||
|
||
if (dwfl) { | ||
dwfl_report_elf(dwfl, name, name, fd, bias, true); | ||
dwfl_report_end(dwfl, NULL, NULL); | ||
} | ||
} | ||
|
||
void debuginfo_lock(void) | ||
{ | ||
qemu_mutex_lock(&lock); | ||
} | ||
|
||
void debuginfo_query(struct debuginfo_query *q, size_t n) | ||
{ | ||
const char *symbol, *file; | ||
Dwfl_Module *dwfl_module; | ||
Dwfl_Line *dwfl_line; | ||
GElf_Off dwfl_offset; | ||
GElf_Sym dwfl_sym; | ||
size_t i; | ||
int line; | ||
|
||
if (!dwfl) { | ||
return; | ||
} | ||
|
||
for (i = 0; i < n; i++) { | ||
dwfl_module = dwfl_addrmodule(dwfl, q[i].address); | ||
if (!dwfl_module) { | ||
continue; | ||
} | ||
|
||
if (q[i].flags & DEBUGINFO_SYMBOL) { | ||
symbol = dwfl_module_addrinfo(dwfl_module, q[i].address, | ||
&dwfl_offset, &dwfl_sym, | ||
NULL, NULL, NULL); | ||
if (symbol) { | ||
q[i].symbol = symbol; | ||
q[i].offset = dwfl_offset; | ||
} | ||
} | ||
|
||
if (q[i].flags & DEBUGINFO_LINE) { | ||
dwfl_line = dwfl_module_getsrc(dwfl_module, q[i].address); | ||
if (dwfl_line) { | ||
file = dwfl_lineinfo(dwfl_line, NULL, &line, 0, NULL, NULL); | ||
if (file) { | ||
q[i].file = file; | ||
q[i].line = line; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
void debuginfo_unlock(void) | ||
{ | ||
qemu_mutex_unlock(&lock); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* Debug information support. | ||
* | ||
* SPDX-License-Identifier: GPL-2.0-or-later | ||
*/ | ||
|
||
#ifndef ACCEL_TCG_DEBUGINFO_H | ||
#define ACCEL_TCG_DEBUGINFO_H | ||
|
||
/* | ||
* Debuginfo describing a certain address. | ||
*/ | ||
struct debuginfo_query { | ||
uint64_t address; /* Input: address. */ | ||
int flags; /* Input: debuginfo subset. */ | ||
const char *symbol; /* Symbol that the address is part of. */ | ||
uint64_t offset; /* Offset from the symbol. */ | ||
const char *file; /* Source file associated with the address. */ | ||
int line; /* Line number in the source file. */ | ||
}; | ||
|
||
/* | ||
* Debuginfo subsets. | ||
*/ | ||
#define DEBUGINFO_SYMBOL BIT(1) | ||
#define DEBUGINFO_LINE BIT(2) | ||
|
||
#if defined(CONFIG_TCG) && defined(CONFIG_LIBDW) | ||
/* | ||
* Load debuginfo for the specified guest ELF image. | ||
* Return true on success, false on failure. | ||
*/ | ||
void debuginfo_report_elf(const char *name, int fd, uint64_t bias); | ||
|
||
/* | ||
* Take the debuginfo lock. | ||
*/ | ||
void debuginfo_lock(void); | ||
|
||
/* | ||
* Fill each on N Qs with the debuginfo about Q->ADDRESS as specified by | ||
* Q->FLAGS: | ||
* | ||
* - DEBUGINFO_SYMBOL: update Q->SYMBOL and Q->OFFSET. If symbol debuginfo is | ||
* missing, then leave them as is. | ||
* - DEBUINFO_LINE: update Q->FILE and Q->LINE. If line debuginfo is missing, | ||
* then leave them as is. | ||
* | ||
* This function must be called under the debuginfo lock. The results can be | ||
* accessed only until the debuginfo lock is released. | ||
*/ | ||
void debuginfo_query(struct debuginfo_query *q, size_t n); | ||
|
||
/* | ||
* Release the debuginfo lock. | ||
*/ | ||
void debuginfo_unlock(void); | ||
#else | ||
static inline void debuginfo_report_elf(const char *image_name, int image_fd, | ||
uint64_t load_bias) | ||
{ | ||
} | ||
|
||
static inline void debuginfo_lock(void) | ||
{ | ||
} | ||
|
||
static inline void debuginfo_query(struct debuginfo_query *q, size_t n) | ||
{ | ||
} | ||
|
||
static inline void debuginfo_unlock(void) | ||
{ | ||
} | ||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters