mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
perf tools: Add util/debuginfo.[ch] files
Split debuginfo data structure and related functions into a separate file so that it can be used by other components than the probe-finder. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Masami Hiramatsu (Google) <mhiramat@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: linux-toolchains@vger.kernel.org Cc: linux-trace-devel@vger.kernel.org Link: https://lore.kernel.org/r/20231110000012.3538610-4-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
fb7fd2a14a
commit
6f1b6291cf
|
|
@ -195,6 +195,7 @@ endif
|
||||||
perf-$(CONFIG_DWARF) += probe-finder.o
|
perf-$(CONFIG_DWARF) += probe-finder.o
|
||||||
perf-$(CONFIG_DWARF) += dwarf-aux.o
|
perf-$(CONFIG_DWARF) += dwarf-aux.o
|
||||||
perf-$(CONFIG_DWARF) += dwarf-regs.o
|
perf-$(CONFIG_DWARF) += dwarf-regs.o
|
||||||
|
perf-$(CONFIG_DWARF) += debuginfo.o
|
||||||
|
|
||||||
perf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
|
perf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
|
||||||
perf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind-local.o
|
perf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind-local.o
|
||||||
|
|
|
||||||
205
tools/perf/util/debuginfo.c
Normal file
205
tools/perf/util/debuginfo.c
Normal file
|
|
@ -0,0 +1,205 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
/*
|
||||||
|
* DWARF debug information handling code. Copied from probe-finder.c.
|
||||||
|
*
|
||||||
|
* Written by Masami Hiramatsu <mhiramat@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <linux/zalloc.h>
|
||||||
|
|
||||||
|
#include "build-id.h"
|
||||||
|
#include "dso.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "debuginfo.h"
|
||||||
|
#include "symbol.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_DEBUGINFOD_SUPPORT
|
||||||
|
#include <elfutils/debuginfod.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Dwarf FL wrappers */
|
||||||
|
static char *debuginfo_path; /* Currently dummy */
|
||||||
|
|
||||||
|
static const Dwfl_Callbacks offline_callbacks = {
|
||||||
|
.find_debuginfo = dwfl_standard_find_debuginfo,
|
||||||
|
.debuginfo_path = &debuginfo_path,
|
||||||
|
|
||||||
|
.section_address = dwfl_offline_section_address,
|
||||||
|
|
||||||
|
/* We use this table for core files too. */
|
||||||
|
.find_elf = dwfl_build_id_find_elf,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Get a Dwarf from offline image */
|
||||||
|
static int debuginfo__init_offline_dwarf(struct debuginfo *dbg,
|
||||||
|
const char *path)
|
||||||
|
{
|
||||||
|
GElf_Addr dummy;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = open(path, O_RDONLY);
|
||||||
|
if (fd < 0)
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
dbg->dwfl = dwfl_begin(&offline_callbacks);
|
||||||
|
if (!dbg->dwfl)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
dwfl_report_begin(dbg->dwfl);
|
||||||
|
dbg->mod = dwfl_report_offline(dbg->dwfl, "", "", fd);
|
||||||
|
if (!dbg->mod)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
dbg->dbg = dwfl_module_getdwarf(dbg->mod, &dbg->bias);
|
||||||
|
if (!dbg->dbg)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
dwfl_module_build_id(dbg->mod, &dbg->build_id, &dummy);
|
||||||
|
|
||||||
|
dwfl_report_end(dbg->dwfl, NULL, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
if (dbg->dwfl)
|
||||||
|
dwfl_end(dbg->dwfl);
|
||||||
|
else
|
||||||
|
close(fd);
|
||||||
|
memset(dbg, 0, sizeof(*dbg));
|
||||||
|
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct debuginfo *__debuginfo__new(const char *path)
|
||||||
|
{
|
||||||
|
struct debuginfo *dbg = zalloc(sizeof(*dbg));
|
||||||
|
if (!dbg)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (debuginfo__init_offline_dwarf(dbg, path) < 0)
|
||||||
|
zfree(&dbg);
|
||||||
|
if (dbg)
|
||||||
|
pr_debug("Open Debuginfo file: %s\n", path);
|
||||||
|
return dbg;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum dso_binary_type distro_dwarf_types[] = {
|
||||||
|
DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
|
||||||
|
DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
|
||||||
|
DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO,
|
||||||
|
DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
|
||||||
|
DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO,
|
||||||
|
DSO_BINARY_TYPE__NOT_FOUND,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct debuginfo *debuginfo__new(const char *path)
|
||||||
|
{
|
||||||
|
enum dso_binary_type *type;
|
||||||
|
char buf[PATH_MAX], nil = '\0';
|
||||||
|
struct dso *dso;
|
||||||
|
struct debuginfo *dinfo = NULL;
|
||||||
|
struct build_id bid;
|
||||||
|
|
||||||
|
/* Try to open distro debuginfo files */
|
||||||
|
dso = dso__new(path);
|
||||||
|
if (!dso)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* Set the build id for DSO_BINARY_TYPE__BUILDID_DEBUGINFO */
|
||||||
|
if (is_regular_file(path) && filename__read_build_id(path, &bid) > 0)
|
||||||
|
dso__set_build_id(dso, &bid);
|
||||||
|
|
||||||
|
for (type = distro_dwarf_types;
|
||||||
|
!dinfo && *type != DSO_BINARY_TYPE__NOT_FOUND;
|
||||||
|
type++) {
|
||||||
|
if (dso__read_binary_type_filename(dso, *type, &nil,
|
||||||
|
buf, PATH_MAX) < 0)
|
||||||
|
continue;
|
||||||
|
dinfo = __debuginfo__new(buf);
|
||||||
|
}
|
||||||
|
dso__put(dso);
|
||||||
|
|
||||||
|
out:
|
||||||
|
/* if failed to open all distro debuginfo, open given binary */
|
||||||
|
return dinfo ? : __debuginfo__new(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void debuginfo__delete(struct debuginfo *dbg)
|
||||||
|
{
|
||||||
|
if (dbg) {
|
||||||
|
if (dbg->dwfl)
|
||||||
|
dwfl_end(dbg->dwfl);
|
||||||
|
free(dbg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For the kernel module, we need a special code to get a DIE */
|
||||||
|
int debuginfo__get_text_offset(struct debuginfo *dbg, Dwarf_Addr *offs,
|
||||||
|
bool adjust_offset)
|
||||||
|
{
|
||||||
|
int n, i;
|
||||||
|
Elf32_Word shndx;
|
||||||
|
Elf_Scn *scn;
|
||||||
|
Elf *elf;
|
||||||
|
GElf_Shdr mem, *shdr;
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
elf = dwfl_module_getelf(dbg->mod, &dbg->bias);
|
||||||
|
if (!elf)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Get the number of relocations */
|
||||||
|
n = dwfl_module_relocations(dbg->mod);
|
||||||
|
if (n < 0)
|
||||||
|
return -ENOENT;
|
||||||
|
/* Search the relocation related .text section */
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
p = dwfl_module_relocation_info(dbg->mod, i, &shndx);
|
||||||
|
if (strcmp(p, ".text") == 0) {
|
||||||
|
/* OK, get the section header */
|
||||||
|
scn = elf_getscn(elf, shndx);
|
||||||
|
if (!scn)
|
||||||
|
return -ENOENT;
|
||||||
|
shdr = gelf_getshdr(scn, &mem);
|
||||||
|
if (!shdr)
|
||||||
|
return -ENOENT;
|
||||||
|
*offs = shdr->sh_addr;
|
||||||
|
if (adjust_offset)
|
||||||
|
*offs -= shdr->sh_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_DEBUGINFOD_SUPPORT
|
||||||
|
int get_source_from_debuginfod(const char *raw_path,
|
||||||
|
const char *sbuild_id, char **new_path)
|
||||||
|
{
|
||||||
|
debuginfod_client *c = debuginfod_begin();
|
||||||
|
const char *p = raw_path;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if (!c)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
fd = debuginfod_find_source(c, (const unsigned char *)sbuild_id,
|
||||||
|
0, p, new_path);
|
||||||
|
pr_debug("Search %s from debuginfod -> %d\n", p, fd);
|
||||||
|
if (fd >= 0)
|
||||||
|
close(fd);
|
||||||
|
debuginfod_end(c);
|
||||||
|
if (fd < 0) {
|
||||||
|
pr_debug("Failed to find %s in debuginfod (%s)\n",
|
||||||
|
raw_path, sbuild_id);
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
pr_debug("Got a source %s\n", *new_path);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_DEBUGINFOD_SUPPORT */
|
||||||
64
tools/perf/util/debuginfo.h
Normal file
64
tools/perf/util/debuginfo.h
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
#ifndef _PERF_DEBUGINFO_H
|
||||||
|
#define _PERF_DEBUGINFO_H
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_DWARF_SUPPORT
|
||||||
|
|
||||||
|
#include "dwarf-aux.h"
|
||||||
|
|
||||||
|
/* debug information structure */
|
||||||
|
struct debuginfo {
|
||||||
|
Dwarf *dbg;
|
||||||
|
Dwfl_Module *mod;
|
||||||
|
Dwfl *dwfl;
|
||||||
|
Dwarf_Addr bias;
|
||||||
|
const unsigned char *build_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This also tries to open distro debuginfo */
|
||||||
|
struct debuginfo *debuginfo__new(const char *path);
|
||||||
|
void debuginfo__delete(struct debuginfo *dbg);
|
||||||
|
|
||||||
|
int debuginfo__get_text_offset(struct debuginfo *dbg, Dwarf_Addr *offs,
|
||||||
|
bool adjust_offset);
|
||||||
|
|
||||||
|
#else /* HAVE_DWARF_SUPPORT */
|
||||||
|
|
||||||
|
/* dummy debug information structure */
|
||||||
|
struct debuginfo {
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct debuginfo *debuginfo__new(const char *path __maybe_unused)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void debuginfo__delete(struct debuginfo *dbg __maybe_unused)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int debuginfo__get_text_offset(struct debuginfo *dbg __maybe_unused,
|
||||||
|
Dwarf_Addr *offs __maybe_unused,
|
||||||
|
bool adjust_offset __maybe_unused)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_DWARF_SUPPORT */
|
||||||
|
|
||||||
|
#ifdef HAVE_DEBUGINFOD_SUPPORT
|
||||||
|
int get_source_from_debuginfod(const char *raw_path, const char *sbuild_id,
|
||||||
|
char **new_path);
|
||||||
|
#else /* HAVE_DEBUGINFOD_SUPPORT */
|
||||||
|
static inline int get_source_from_debuginfod(const char *raw_path __maybe_unused,
|
||||||
|
const char *sbuild_id __maybe_unused,
|
||||||
|
char **new_path __maybe_unused)
|
||||||
|
{
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_DEBUGINFOD_SUPPORT */
|
||||||
|
|
||||||
|
#endif /* _PERF_DEBUGINFO_H */
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "dso.h"
|
#include "dso.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "debuginfo.h"
|
||||||
#include "intlist.h"
|
#include "intlist.h"
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
#include "strlist.h"
|
#include "strlist.h"
|
||||||
|
|
@ -31,128 +32,9 @@
|
||||||
#include "probe-file.h"
|
#include "probe-file.h"
|
||||||
#include "string2.h"
|
#include "string2.h"
|
||||||
|
|
||||||
#ifdef HAVE_DEBUGINFOD_SUPPORT
|
|
||||||
#include <elfutils/debuginfod.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Kprobe tracer basic type is up to u64 */
|
/* Kprobe tracer basic type is up to u64 */
|
||||||
#define MAX_BASIC_TYPE_BITS 64
|
#define MAX_BASIC_TYPE_BITS 64
|
||||||
|
|
||||||
/* Dwarf FL wrappers */
|
|
||||||
static char *debuginfo_path; /* Currently dummy */
|
|
||||||
|
|
||||||
static const Dwfl_Callbacks offline_callbacks = {
|
|
||||||
.find_debuginfo = dwfl_standard_find_debuginfo,
|
|
||||||
.debuginfo_path = &debuginfo_path,
|
|
||||||
|
|
||||||
.section_address = dwfl_offline_section_address,
|
|
||||||
|
|
||||||
/* We use this table for core files too. */
|
|
||||||
.find_elf = dwfl_build_id_find_elf,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Get a Dwarf from offline image */
|
|
||||||
static int debuginfo__init_offline_dwarf(struct debuginfo *dbg,
|
|
||||||
const char *path)
|
|
||||||
{
|
|
||||||
GElf_Addr dummy;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
fd = open(path, O_RDONLY);
|
|
||||||
if (fd < 0)
|
|
||||||
return fd;
|
|
||||||
|
|
||||||
dbg->dwfl = dwfl_begin(&offline_callbacks);
|
|
||||||
if (!dbg->dwfl)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
dwfl_report_begin(dbg->dwfl);
|
|
||||||
dbg->mod = dwfl_report_offline(dbg->dwfl, "", "", fd);
|
|
||||||
if (!dbg->mod)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
dbg->dbg = dwfl_module_getdwarf(dbg->mod, &dbg->bias);
|
|
||||||
if (!dbg->dbg)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
dwfl_module_build_id(dbg->mod, &dbg->build_id, &dummy);
|
|
||||||
|
|
||||||
dwfl_report_end(dbg->dwfl, NULL, NULL);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
error:
|
|
||||||
if (dbg->dwfl)
|
|
||||||
dwfl_end(dbg->dwfl);
|
|
||||||
else
|
|
||||||
close(fd);
|
|
||||||
memset(dbg, 0, sizeof(*dbg));
|
|
||||||
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct debuginfo *__debuginfo__new(const char *path)
|
|
||||||
{
|
|
||||||
struct debuginfo *dbg = zalloc(sizeof(*dbg));
|
|
||||||
if (!dbg)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (debuginfo__init_offline_dwarf(dbg, path) < 0)
|
|
||||||
zfree(&dbg);
|
|
||||||
if (dbg)
|
|
||||||
pr_debug("Open Debuginfo file: %s\n", path);
|
|
||||||
return dbg;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum dso_binary_type distro_dwarf_types[] = {
|
|
||||||
DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
|
|
||||||
DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
|
|
||||||
DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO,
|
|
||||||
DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
|
|
||||||
DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO,
|
|
||||||
DSO_BINARY_TYPE__NOT_FOUND,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct debuginfo *debuginfo__new(const char *path)
|
|
||||||
{
|
|
||||||
enum dso_binary_type *type;
|
|
||||||
char buf[PATH_MAX], nil = '\0';
|
|
||||||
struct dso *dso;
|
|
||||||
struct debuginfo *dinfo = NULL;
|
|
||||||
struct build_id bid;
|
|
||||||
|
|
||||||
/* Try to open distro debuginfo files */
|
|
||||||
dso = dso__new(path);
|
|
||||||
if (!dso)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* Set the build id for DSO_BINARY_TYPE__BUILDID_DEBUGINFO */
|
|
||||||
if (is_regular_file(path) && filename__read_build_id(path, &bid) > 0)
|
|
||||||
dso__set_build_id(dso, &bid);
|
|
||||||
|
|
||||||
for (type = distro_dwarf_types;
|
|
||||||
!dinfo && *type != DSO_BINARY_TYPE__NOT_FOUND;
|
|
||||||
type++) {
|
|
||||||
if (dso__read_binary_type_filename(dso, *type, &nil,
|
|
||||||
buf, PATH_MAX) < 0)
|
|
||||||
continue;
|
|
||||||
dinfo = __debuginfo__new(buf);
|
|
||||||
}
|
|
||||||
dso__put(dso);
|
|
||||||
|
|
||||||
out:
|
|
||||||
/* if failed to open all distro debuginfo, open given binary */
|
|
||||||
return dinfo ? : __debuginfo__new(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
void debuginfo__delete(struct debuginfo *dbg)
|
|
||||||
{
|
|
||||||
if (dbg) {
|
|
||||||
if (dbg->dwfl)
|
|
||||||
dwfl_end(dbg->dwfl);
|
|
||||||
free(dbg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Probe finder related functions
|
* Probe finder related functions
|
||||||
*/
|
*/
|
||||||
|
|
@ -1677,44 +1559,6 @@ int debuginfo__find_available_vars_at(struct debuginfo *dbg,
|
||||||
return (ret < 0) ? ret : af.nvls;
|
return (ret < 0) ? ret : af.nvls;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For the kernel module, we need a special code to get a DIE */
|
|
||||||
int debuginfo__get_text_offset(struct debuginfo *dbg, Dwarf_Addr *offs,
|
|
||||||
bool adjust_offset)
|
|
||||||
{
|
|
||||||
int n, i;
|
|
||||||
Elf32_Word shndx;
|
|
||||||
Elf_Scn *scn;
|
|
||||||
Elf *elf;
|
|
||||||
GElf_Shdr mem, *shdr;
|
|
||||||
const char *p;
|
|
||||||
|
|
||||||
elf = dwfl_module_getelf(dbg->mod, &dbg->bias);
|
|
||||||
if (!elf)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/* Get the number of relocations */
|
|
||||||
n = dwfl_module_relocations(dbg->mod);
|
|
||||||
if (n < 0)
|
|
||||||
return -ENOENT;
|
|
||||||
/* Search the relocation related .text section */
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
p = dwfl_module_relocation_info(dbg->mod, i, &shndx);
|
|
||||||
if (strcmp(p, ".text") == 0) {
|
|
||||||
/* OK, get the section header */
|
|
||||||
scn = elf_getscn(elf, shndx);
|
|
||||||
if (!scn)
|
|
||||||
return -ENOENT;
|
|
||||||
shdr = gelf_getshdr(scn, &mem);
|
|
||||||
if (!shdr)
|
|
||||||
return -ENOENT;
|
|
||||||
*offs = shdr->sh_addr;
|
|
||||||
if (adjust_offset)
|
|
||||||
*offs -= shdr->sh_offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reverse search */
|
/* Reverse search */
|
||||||
int debuginfo__find_probe_point(struct debuginfo *dbg, u64 addr,
|
int debuginfo__find_probe_point(struct debuginfo *dbg, u64 addr,
|
||||||
struct perf_probe_point *ppt)
|
struct perf_probe_point *ppt)
|
||||||
|
|
@ -2009,41 +1853,6 @@ int debuginfo__find_line_range(struct debuginfo *dbg, struct line_range *lr)
|
||||||
return (ret < 0) ? ret : lf.found;
|
return (ret < 0) ? ret : lf.found;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_DEBUGINFOD_SUPPORT
|
|
||||||
/* debuginfod doesn't require the comp_dir but buildid is required */
|
|
||||||
static int get_source_from_debuginfod(const char *raw_path,
|
|
||||||
const char *sbuild_id, char **new_path)
|
|
||||||
{
|
|
||||||
debuginfod_client *c = debuginfod_begin();
|
|
||||||
const char *p = raw_path;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
if (!c)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
fd = debuginfod_find_source(c, (const unsigned char *)sbuild_id,
|
|
||||||
0, p, new_path);
|
|
||||||
pr_debug("Search %s from debuginfod -> %d\n", p, fd);
|
|
||||||
if (fd >= 0)
|
|
||||||
close(fd);
|
|
||||||
debuginfod_end(c);
|
|
||||||
if (fd < 0) {
|
|
||||||
pr_debug("Failed to find %s in debuginfod (%s)\n",
|
|
||||||
raw_path, sbuild_id);
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
|
||||||
pr_debug("Got a source %s\n", *new_path);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static inline int get_source_from_debuginfod(const char *raw_path __maybe_unused,
|
|
||||||
const char *sbuild_id __maybe_unused,
|
|
||||||
char **new_path __maybe_unused)
|
|
||||||
{
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* Find a src file from a DWARF tag path. Prepend optional source path prefix
|
* Find a src file from a DWARF tag path. Prepend optional source path prefix
|
||||||
* and chop off leading directories that do not exist. Result is passed back as
|
* and chop off leading directories that do not exist. Result is passed back as
|
||||||
|
|
|
||||||
|
|
@ -24,21 +24,7 @@ static inline int is_c_varname(const char *name)
|
||||||
#ifdef HAVE_DWARF_SUPPORT
|
#ifdef HAVE_DWARF_SUPPORT
|
||||||
|
|
||||||
#include "dwarf-aux.h"
|
#include "dwarf-aux.h"
|
||||||
|
#include "debuginfo.h"
|
||||||
/* TODO: export debuginfo data structure even if no dwarf support */
|
|
||||||
|
|
||||||
/* debug information structure */
|
|
||||||
struct debuginfo {
|
|
||||||
Dwarf *dbg;
|
|
||||||
Dwfl_Module *mod;
|
|
||||||
Dwfl *dwfl;
|
|
||||||
Dwarf_Addr bias;
|
|
||||||
const unsigned char *build_id;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This also tries to open distro debuginfo */
|
|
||||||
struct debuginfo *debuginfo__new(const char *path);
|
|
||||||
void debuginfo__delete(struct debuginfo *dbg);
|
|
||||||
|
|
||||||
/* Find probe_trace_events specified by perf_probe_event from debuginfo */
|
/* Find probe_trace_events specified by perf_probe_event from debuginfo */
|
||||||
int debuginfo__find_trace_events(struct debuginfo *dbg,
|
int debuginfo__find_trace_events(struct debuginfo *dbg,
|
||||||
|
|
@ -49,9 +35,6 @@ int debuginfo__find_trace_events(struct debuginfo *dbg,
|
||||||
int debuginfo__find_probe_point(struct debuginfo *dbg, u64 addr,
|
int debuginfo__find_probe_point(struct debuginfo *dbg, u64 addr,
|
||||||
struct perf_probe_point *ppt);
|
struct perf_probe_point *ppt);
|
||||||
|
|
||||||
int debuginfo__get_text_offset(struct debuginfo *dbg, Dwarf_Addr *offs,
|
|
||||||
bool adjust_offset);
|
|
||||||
|
|
||||||
/* Find a line range */
|
/* Find a line range */
|
||||||
int debuginfo__find_line_range(struct debuginfo *dbg, struct line_range *lr);
|
int debuginfo__find_line_range(struct debuginfo *dbg, struct line_range *lr);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user