mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-10 15:10:53 +00:00
source tree cleanup
The lib/ directory was getting a bit out of hand, so this tries to organize things a bit so it is easier going forward to locate the code people want to patch.
This commit is contained in:
306
lib/symbols/sp-elf-symbol-resolver.c
Normal file
306
lib/symbols/sp-elf-symbol-resolver.c
Normal file
@ -0,0 +1,306 @@
|
||||
/* sp-elf-symbol-resolver.c
|
||||
*
|
||||
* Copyright (C) 2016 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "symbols/sp-elf-symbol-resolver.h"
|
||||
#include "util/binfile.h"
|
||||
#include "util/elfparser.h"
|
||||
#include "util/sp-map-lookaside.h"
|
||||
|
||||
struct _SpElfSymbolResolver
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GHashTable *lookasides;
|
||||
GHashTable *bin_files;
|
||||
GHashTable *tag_cache;
|
||||
};
|
||||
|
||||
static void symbol_resolver_iface_init (SpSymbolResolverInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (SpElfSymbolResolver,
|
||||
sp_elf_symbol_resolver,
|
||||
G_TYPE_OBJECT,
|
||||
0,
|
||||
G_IMPLEMENT_INTERFACE (SP_TYPE_SYMBOL_RESOLVER,
|
||||
symbol_resolver_iface_init))
|
||||
|
||||
static void
|
||||
sp_elf_symbol_resolver_finalize (GObject *object)
|
||||
{
|
||||
SpElfSymbolResolver *self = (SpElfSymbolResolver *)object;
|
||||
|
||||
g_clear_pointer (&self->bin_files, g_hash_table_unref);
|
||||
g_clear_pointer (&self->lookasides, g_hash_table_unref);
|
||||
g_clear_pointer (&self->tag_cache, g_hash_table_unref);
|
||||
|
||||
G_OBJECT_CLASS (sp_elf_symbol_resolver_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
sp_elf_symbol_resolver_class_init (SpElfSymbolResolverClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = sp_elf_symbol_resolver_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
sp_elf_symbol_resolver_init (SpElfSymbolResolver *self)
|
||||
{
|
||||
self->lookasides = g_hash_table_new_full (NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
(GDestroyNotify)sp_map_lookaside_free);
|
||||
|
||||
self->bin_files = g_hash_table_new_full (g_str_hash,
|
||||
g_str_equal,
|
||||
g_free,
|
||||
(GDestroyNotify)bin_file_free);
|
||||
|
||||
self->tag_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
sp_elf_symbol_resolver_load (SpSymbolResolver *resolver,
|
||||
SpCaptureReader *reader)
|
||||
{
|
||||
SpElfSymbolResolver *self = (SpElfSymbolResolver *)resolver;
|
||||
SpCaptureFrameType type;
|
||||
|
||||
g_assert (SP_IS_SYMBOL_RESOLVER (resolver));
|
||||
g_assert (reader != NULL);
|
||||
|
||||
sp_capture_reader_reset (reader);
|
||||
|
||||
while (sp_capture_reader_peek_type (reader, &type))
|
||||
{
|
||||
const SpCaptureMap *ev;
|
||||
SpMapLookaside *lookaside;
|
||||
SpMap map;
|
||||
|
||||
if (type != SP_CAPTURE_FRAME_MAP)
|
||||
{
|
||||
if (!sp_capture_reader_skip (reader))
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
ev = sp_capture_reader_read_map (reader);
|
||||
|
||||
map.start = ev->start;
|
||||
map.end = ev->end;
|
||||
map.offset = ev->offset;
|
||||
map.inode = ev->inode;
|
||||
map.filename = ev->filename;
|
||||
|
||||
lookaside = g_hash_table_lookup (self->lookasides, GINT_TO_POINTER (ev->frame.pid));
|
||||
|
||||
if (lookaside == NULL)
|
||||
{
|
||||
lookaside = sp_map_lookaside_new ();
|
||||
g_hash_table_insert (self->lookasides, GINT_TO_POINTER (ev->frame.pid), lookaside);
|
||||
}
|
||||
|
||||
sp_map_lookaside_insert (lookaside, &map);
|
||||
}
|
||||
}
|
||||
|
||||
static bin_file_t *
|
||||
sp_elf_symbol_resolver_get_bin_file (SpElfSymbolResolver *self,
|
||||
const gchar *filename)
|
||||
{
|
||||
bin_file_t *bin_file;
|
||||
|
||||
g_assert (SP_IS_ELF_SYMBOL_RESOLVER (self));
|
||||
|
||||
bin_file = g_hash_table_lookup (self->bin_files, filename);
|
||||
|
||||
if (bin_file == NULL)
|
||||
{
|
||||
const gchar *alternate = filename;
|
||||
|
||||
/*
|
||||
* If we are in a new mount namespace, then rely on the sp_symbol_dirs
|
||||
* to find us a locate to resolve the file where the CRC will match.
|
||||
*
|
||||
* TODO: We need to translate the path here so that we can locate the
|
||||
* binary behind it (which then has links to the debug file in
|
||||
* the section header).
|
||||
*/
|
||||
if (g_str_has_prefix (filename, "/newroot/"))
|
||||
alternate += strlen ("/newroot");
|
||||
|
||||
bin_file = bin_file_new (alternate);
|
||||
g_hash_table_insert (self->bin_files, g_strdup (filename), bin_file);
|
||||
}
|
||||
|
||||
return bin_file;
|
||||
}
|
||||
|
||||
static GQuark
|
||||
guess_tag (SpElfSymbolResolver *self,
|
||||
const SpMap *map)
|
||||
{
|
||||
g_assert (map != NULL);
|
||||
g_assert (map->filename != NULL);
|
||||
|
||||
if (!g_hash_table_contains (self->tag_cache, map->filename))
|
||||
{
|
||||
GQuark tag = 0;
|
||||
|
||||
if (strstr (map->filename, "/libgobject-2.0."))
|
||||
tag = g_quark_from_static_string ("GObject");
|
||||
|
||||
else if (strstr (map->filename, "/libglib-2.0."))
|
||||
tag = g_quark_from_static_string ("GLib");
|
||||
|
||||
else if (strstr (map->filename, "/libgio-2.0."))
|
||||
tag = g_quark_from_static_string ("Gio");
|
||||
|
||||
else if (strstr (map->filename, "/libgirepository-1.0."))
|
||||
tag = g_quark_from_static_string ("Introspection");
|
||||
|
||||
else if (strstr (map->filename, "/libgtk-3."))
|
||||
tag = g_quark_from_static_string ("Gtk+");
|
||||
|
||||
else if (strstr (map->filename, "/libgdk-3."))
|
||||
tag = g_quark_from_static_string ("Gdk");
|
||||
|
||||
else if (strstr (map->filename, "/libgtksourceview-3.0"))
|
||||
tag = g_quark_from_static_string ("GtkSourceView");
|
||||
|
||||
else if (strstr (map->filename, "/libpixman-1"))
|
||||
tag = g_quark_from_static_string ("Pixman");
|
||||
|
||||
else if (strstr (map->filename, "/libcairo."))
|
||||
tag = g_quark_from_static_string ("cairo");
|
||||
|
||||
else if (strstr (map->filename, "/libgstreamer-1."))
|
||||
tag = g_quark_from_static_string ("GStreamer");
|
||||
|
||||
else if (strstr (map->filename, "/libX11."))
|
||||
tag = g_quark_from_static_string ("X11");
|
||||
|
||||
else if (strstr (map->filename, "/libpango-1.0."))
|
||||
tag = g_quark_from_static_string ("Pango");
|
||||
|
||||
else if (strstr (map->filename, "/libpangocairo-1.0."))
|
||||
tag = g_quark_from_static_string ("Pango");
|
||||
|
||||
else if (strstr (map->filename, "/libpangomm-1.4."))
|
||||
tag = g_quark_from_static_string ("Pango");
|
||||
|
||||
else if (strstr (map->filename, "/libpangoft2-1.0"))
|
||||
tag = g_quark_from_static_string ("Pango");
|
||||
|
||||
else if (strstr (map->filename, "/libpangoxft-1.0."))
|
||||
tag = g_quark_from_static_string ("Pango");
|
||||
|
||||
else if (strstr (map->filename, "/libclutter-"))
|
||||
tag = g_quark_from_static_string ("Clutter");
|
||||
|
||||
else if (strstr (map->filename, "/libcogl.") ||
|
||||
strstr (map->filename, "/libcogl-"))
|
||||
tag = g_quark_from_static_string ("Cogl");
|
||||
|
||||
else if (strstr (map->filename, "/libffi."))
|
||||
tag = g_quark_from_static_string ("libffi");
|
||||
|
||||
else if (strstr (map->filename, "/libwayland-"))
|
||||
tag = g_quark_from_static_string ("Wayland");
|
||||
|
||||
else if (strstr (map->filename, "/libinput."))
|
||||
tag = g_quark_from_static_string ("libinput");
|
||||
|
||||
else if (strstr (map->filename, "/libgjs."))
|
||||
tag = g_quark_from_static_string ("Gjs");
|
||||
|
||||
else if (strstr (map->filename, "/libmozjs-"))
|
||||
tag = g_quark_from_static_string ("MozJS");
|
||||
|
||||
else if (strstr (map->filename, "/libGL."))
|
||||
tag = g_quark_from_static_string ("GL");
|
||||
|
||||
else if (strstr (map->filename, "/libEGL."))
|
||||
tag = g_quark_from_static_string ("EGL");
|
||||
|
||||
g_hash_table_insert (self->tag_cache,
|
||||
g_strdup (map->filename),
|
||||
GSIZE_TO_POINTER (tag));
|
||||
}
|
||||
|
||||
return GPOINTER_TO_SIZE (g_hash_table_lookup (self->tag_cache, map->filename));
|
||||
}
|
||||
|
||||
static gchar *
|
||||
sp_elf_symbol_resolver_resolve (SpSymbolResolver *resolver,
|
||||
guint64 time,
|
||||
GPid pid,
|
||||
SpCaptureAddress address,
|
||||
GQuark *tag)
|
||||
{
|
||||
SpElfSymbolResolver *self = (SpElfSymbolResolver *)resolver;
|
||||
const bin_symbol_t *bin_sym;
|
||||
SpMapLookaside *lookaside;
|
||||
const gchar *bin_sym_name;
|
||||
const SpMap *map;
|
||||
bin_file_t *bin_file;
|
||||
|
||||
g_assert (SP_IS_ELF_SYMBOL_RESOLVER (self));
|
||||
|
||||
lookaside = g_hash_table_lookup (self->lookasides, GINT_TO_POINTER (pid));
|
||||
if (lookaside == NULL)
|
||||
return NULL;
|
||||
|
||||
map = sp_map_lookaside_lookup (lookaside, address);
|
||||
if (map == NULL)
|
||||
return NULL;
|
||||
|
||||
address -= map->start;
|
||||
address += map->offset;
|
||||
|
||||
bin_file = sp_elf_symbol_resolver_get_bin_file (self, map->filename);
|
||||
|
||||
g_assert (bin_file != NULL);
|
||||
|
||||
if (map->inode && !bin_file_check_inode (bin_file, map->inode))
|
||||
return g_strdup_printf ("%s: inode mismatch", map->filename);
|
||||
|
||||
bin_sym = bin_file_lookup_symbol (bin_file, address);
|
||||
bin_sym_name = bin_symbol_get_name (bin_file, bin_sym);
|
||||
|
||||
if (map->filename)
|
||||
*tag = guess_tag (self, map);
|
||||
|
||||
return elf_demangle (bin_sym_name);
|
||||
}
|
||||
|
||||
static void
|
||||
symbol_resolver_iface_init (SpSymbolResolverInterface *iface)
|
||||
{
|
||||
iface->load = sp_elf_symbol_resolver_load;
|
||||
iface->resolve = sp_elf_symbol_resolver_resolve;
|
||||
}
|
||||
|
||||
SpSymbolResolver *
|
||||
sp_elf_symbol_resolver_new (void)
|
||||
{
|
||||
return g_object_new (SP_TYPE_ELF_SYMBOL_RESOLVER, NULL);
|
||||
}
|
||||
34
lib/symbols/sp-elf-symbol-resolver.h
Normal file
34
lib/symbols/sp-elf-symbol-resolver.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* sp-elf-symbol-resolver.h
|
||||
*
|
||||
* Copyright (C) 2016 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SP_ELF_SYMBOL_RESOLVER_H
|
||||
#define SP_ELF_SYMBOL_RESOLVER_H
|
||||
|
||||
#include "symbols/sp-symbol-resolver.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define SP_TYPE_ELF_SYMBOL_RESOLVER (sp_elf_symbol_resolver_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (SpElfSymbolResolver, sp_elf_symbol_resolver, SP, ELF_SYMBOL_RESOLVER, GObject)
|
||||
|
||||
SpSymbolResolver *sp_elf_symbol_resolver_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* SP_ELF_SYMBOL_RESOLVER_H */
|
||||
121
lib/symbols/sp-jitmap-symbol-resolver.c
Normal file
121
lib/symbols/sp-jitmap-symbol-resolver.c
Normal file
@ -0,0 +1,121 @@
|
||||
/* sp-jitmap-symbol-resolver.c
|
||||
*
|
||||
* Copyright (C) 2016 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "symbols/sp-kernel-symbol.h"
|
||||
#include "symbols/sp-jitmap-symbol-resolver.h"
|
||||
|
||||
struct _SpJitmapSymbolResolver
|
||||
{
|
||||
GObject parent_instance;
|
||||
GHashTable *jitmap;
|
||||
};
|
||||
|
||||
static void symbol_resolver_iface_init (SpSymbolResolverInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (SpJitmapSymbolResolver,
|
||||
sp_jitmap_symbol_resolver,
|
||||
G_TYPE_OBJECT,
|
||||
0,
|
||||
G_IMPLEMENT_INTERFACE (SP_TYPE_SYMBOL_RESOLVER,
|
||||
symbol_resolver_iface_init))
|
||||
|
||||
static void
|
||||
sp_jitmap_symbol_resolver_finalize (GObject *object)
|
||||
{
|
||||
SpJitmapSymbolResolver *self = (SpJitmapSymbolResolver *)object;
|
||||
|
||||
g_clear_pointer (&self->jitmap, g_hash_table_unref);
|
||||
|
||||
G_OBJECT_CLASS (sp_jitmap_symbol_resolver_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
sp_jitmap_symbol_resolver_class_init (SpJitmapSymbolResolverClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = sp_jitmap_symbol_resolver_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
sp_jitmap_symbol_resolver_init (SpJitmapSymbolResolver *self)
|
||||
{
|
||||
self->jitmap = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
sp_jitmap_symbol_resolver_load (SpSymbolResolver *resolver,
|
||||
SpCaptureReader *reader)
|
||||
{
|
||||
SpJitmapSymbolResolver *self = (SpJitmapSymbolResolver *)resolver;
|
||||
SpCaptureFrameType type;
|
||||
|
||||
g_assert (SP_IS_JITMAP_SYMBOL_RESOLVER (self));
|
||||
g_assert (reader != NULL);
|
||||
|
||||
while (sp_capture_reader_peek_type (reader, &type))
|
||||
{
|
||||
g_autoptr(GHashTable) jitmap = NULL;
|
||||
GHashTableIter iter;
|
||||
SpCaptureAddress addr;
|
||||
const gchar *str;
|
||||
|
||||
if (type != SP_CAPTURE_FRAME_JITMAP)
|
||||
{
|
||||
if (!sp_capture_reader_skip (reader))
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(jitmap = sp_capture_reader_read_jitmap (reader)))
|
||||
return;
|
||||
|
||||
g_hash_table_iter_init (&iter, jitmap);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&addr, (gpointer *)&str))
|
||||
g_hash_table_insert (self->jitmap, GSIZE_TO_POINTER (addr), g_strdup (str));
|
||||
}
|
||||
}
|
||||
|
||||
static gchar *
|
||||
sp_jitmap_symbol_resolver_resolve (SpSymbolResolver *resolver,
|
||||
guint64 time,
|
||||
GPid pid,
|
||||
SpCaptureAddress address,
|
||||
GQuark *tag)
|
||||
{
|
||||
SpJitmapSymbolResolver *self = (SpJitmapSymbolResolver *)resolver;
|
||||
|
||||
g_assert (SP_IS_JITMAP_SYMBOL_RESOLVER (self));
|
||||
|
||||
*tag = 0;
|
||||
|
||||
return g_strdup (g_hash_table_lookup (self->jitmap, GSIZE_TO_POINTER (address)));
|
||||
}
|
||||
|
||||
static void
|
||||
symbol_resolver_iface_init (SpSymbolResolverInterface *iface)
|
||||
{
|
||||
iface->load = sp_jitmap_symbol_resolver_load;
|
||||
iface->resolve = sp_jitmap_symbol_resolver_resolve;
|
||||
}
|
||||
|
||||
SpSymbolResolver *
|
||||
sp_jitmap_symbol_resolver_new (void)
|
||||
{
|
||||
return g_object_new (SP_TYPE_JITMAP_SYMBOL_RESOLVER, NULL);
|
||||
}
|
||||
34
lib/symbols/sp-jitmap-symbol-resolver.h
Normal file
34
lib/symbols/sp-jitmap-symbol-resolver.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* sp-jitmap-symbol-resolver.h
|
||||
*
|
||||
* Copyright (C) 2016 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SP_JITMAP_SYMBOL_RESOLVER_H
|
||||
#define SP_JITMAP_SYMBOL_RESOLVER_H
|
||||
|
||||
#include "symbols/sp-symbol-resolver.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define SP_TYPE_JITMAP_SYMBOL_RESOLVER (sp_jitmap_symbol_resolver_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (SpJitmapSymbolResolver, sp_jitmap_symbol_resolver, SP, JITMAP_SYMBOL_RESOLVER, GObject)
|
||||
|
||||
SpSymbolResolver *sp_jitmap_symbol_resolver_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* SP_JITMAP_SYMBOL_RESOLVER_H */
|
||||
79
lib/symbols/sp-kernel-symbol-resolver.c
Normal file
79
lib/symbols/sp-kernel-symbol-resolver.c
Normal file
@ -0,0 +1,79 @@
|
||||
/* sp-kernel-symbol-resolver.c
|
||||
*
|
||||
* Copyright (C) 2016 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "symbols/sp-kernel-symbol.h"
|
||||
#include "symbols/sp-kernel-symbol-resolver.h"
|
||||
|
||||
struct _SpKernelSymbolResolver
|
||||
{
|
||||
GObject parent_instance;
|
||||
};
|
||||
|
||||
static void symbol_resolver_iface_init (SpSymbolResolverInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (SpKernelSymbolResolver,
|
||||
sp_kernel_symbol_resolver,
|
||||
G_TYPE_OBJECT,
|
||||
0,
|
||||
G_IMPLEMENT_INTERFACE (SP_TYPE_SYMBOL_RESOLVER,
|
||||
symbol_resolver_iface_init))
|
||||
|
||||
static GQuark linux_quark;
|
||||
|
||||
static void
|
||||
sp_kernel_symbol_resolver_class_init (SpKernelSymbolResolverClass *klass)
|
||||
{
|
||||
linux_quark = g_quark_from_static_string ("Linux");
|
||||
}
|
||||
|
||||
static void
|
||||
sp_kernel_symbol_resolver_init (SpKernelSymbolResolver *skernel)
|
||||
{
|
||||
}
|
||||
|
||||
static gchar *
|
||||
sp_kernel_symbol_resolver_resolve (SpSymbolResolver *resolver,
|
||||
guint64 time,
|
||||
GPid pid,
|
||||
SpCaptureAddress address,
|
||||
GQuark *tag)
|
||||
{
|
||||
const SpKernelSymbol *sym;
|
||||
|
||||
g_assert (SP_IS_SYMBOL_RESOLVER (resolver));
|
||||
|
||||
if (NULL != (sym = sp_kernel_symbol_from_address (address)))
|
||||
{
|
||||
*tag = linux_quark;
|
||||
return g_strdup (sym->name);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
symbol_resolver_iface_init (SpSymbolResolverInterface *iface)
|
||||
{
|
||||
iface->resolve = sp_kernel_symbol_resolver_resolve;
|
||||
}
|
||||
|
||||
SpSymbolResolver *
|
||||
sp_kernel_symbol_resolver_new (void)
|
||||
{
|
||||
return g_object_new (SP_TYPE_KERNEL_SYMBOL_RESOLVER, NULL);
|
||||
}
|
||||
34
lib/symbols/sp-kernel-symbol-resolver.h
Normal file
34
lib/symbols/sp-kernel-symbol-resolver.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* sp-kernel-symbol-resolver.h
|
||||
*
|
||||
* Copyright (C) 2016 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SP_KERNEL_SYMBOL_RESOLVER_H
|
||||
#define SP_KERNEL_SYMBOL_RESOLVER_H
|
||||
|
||||
#include "symbols/sp-symbol-resolver.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define SP_TYPE_KERNEL_SYMBOL_RESOLVER (sp_kernel_symbol_resolver_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (SpKernelSymbolResolver, sp_kernel_symbol_resolver, SP, KERNEL_SYMBOL_RESOLVER, GObject)
|
||||
|
||||
SpSymbolResolver *sp_kernel_symbol_resolver_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* SP_KERNEL_SYMBOL_RESOLVER_H */
|
||||
205
lib/symbols/sp-kernel-symbol.c
Normal file
205
lib/symbols/sp-kernel-symbol.c
Normal file
@ -0,0 +1,205 @@
|
||||
/* sp-kernel-symbol.c
|
||||
*
|
||||
* Copyright (C) 2016 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "util/sp-line-reader.h"
|
||||
#include "symbols/sp-kernel-symbol.h"
|
||||
|
||||
static GArray *kernel_symbols;
|
||||
static const gchar *kernel_symbols_skip[] = {
|
||||
/* IRQ stack */
|
||||
"common_interrupt",
|
||||
"apic_timer_interrupt",
|
||||
"smp_apic_timer_interrupt",
|
||||
"hrtimer_interrupt",
|
||||
"__run_hrtimer",
|
||||
"perf_swevent_hrtimer",
|
||||
"perf_event_overflow",
|
||||
"__perf_event_overflow",
|
||||
"perf_prepare_sample",
|
||||
"perf_callchain",
|
||||
"perf_swcounter_hrtimer",
|
||||
"perf_counter_overflow",
|
||||
"__perf_counter_overflow",
|
||||
"perf_counter_output",
|
||||
|
||||
/* NMI stack */
|
||||
"nmi_stack_correct",
|
||||
"do_nmi",
|
||||
"notify_die",
|
||||
"atomic_notifier_call_chain",
|
||||
"notifier_call_chain",
|
||||
"perf_event_nmi_handler",
|
||||
"perf_counter_nmi_handler",
|
||||
"intel_pmu_handle_irq",
|
||||
"perf_event_overflow",
|
||||
"perf_counter_overflow",
|
||||
"__perf_event_overflow",
|
||||
"perf_prepare_sample",
|
||||
"perf_callchain",
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
static gint
|
||||
sp_kernel_symbol_compare (gconstpointer a,
|
||||
gconstpointer b)
|
||||
{
|
||||
const SpKernelSymbol *syma = a;
|
||||
const SpKernelSymbol *symb = b;
|
||||
|
||||
if (syma->address > symb->address)
|
||||
return 1;
|
||||
else if (syma->address == symb->address)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sp_kernel_symbol_load (void)
|
||||
{
|
||||
g_autofree gchar *contents = NULL;
|
||||
g_autoptr(GArray) ar = NULL;
|
||||
g_autoptr(GHashTable) skip = NULL;
|
||||
g_autoptr(SpLineReader) reader = NULL;
|
||||
const gchar *line;
|
||||
gsize len;
|
||||
guint i;
|
||||
|
||||
skip = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
for (i = 0; kernel_symbols_skip [i]; i++)
|
||||
g_hash_table_insert (skip, (gchar *)kernel_symbols_skip [i], NULL);
|
||||
|
||||
ar = g_array_new (FALSE, TRUE, sizeof (SpKernelSymbol));
|
||||
|
||||
if (!g_file_get_contents ("/proc/kallsyms", &contents, &len, NULL))
|
||||
{
|
||||
g_warning ("/proc/kallsyms is missing, kernel symbols will not be available");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
reader = sp_line_reader_new (contents, len);
|
||||
|
||||
while (NULL != (line = sp_line_reader_next (reader, &len)))
|
||||
{
|
||||
gchar **tokens;
|
||||
|
||||
((gchar *)line) [len] = '\0';
|
||||
|
||||
tokens = g_strsplit_set (line, " \t", -1);
|
||||
|
||||
if (tokens [0] && tokens [1] && tokens [2])
|
||||
{
|
||||
SpCaptureAddress address;
|
||||
gchar *endptr;
|
||||
|
||||
if (g_hash_table_contains (skip, tokens [2]))
|
||||
continue;
|
||||
|
||||
address = g_ascii_strtoull (tokens [0], &endptr, 16);
|
||||
|
||||
if (*endptr == '\0' &&
|
||||
(g_str_equal (tokens [1], "T") || g_str_equal (tokens [1], "t")))
|
||||
{
|
||||
SpKernelSymbol sym;
|
||||
|
||||
sym.address = address;
|
||||
sym.name = g_steal_pointer (&tokens [2]);
|
||||
|
||||
g_array_append_val (ar, sym);
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev (tokens);
|
||||
}
|
||||
|
||||
if (ar->len == 0)
|
||||
return FALSE;
|
||||
|
||||
g_array_sort (ar, sp_kernel_symbol_compare);
|
||||
|
||||
kernel_symbols = g_steal_pointer (&ar);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const SpKernelSymbol *
|
||||
sp_kernel_symbol_lookup (SpKernelSymbol *symbols,
|
||||
SpCaptureAddress address,
|
||||
guint first,
|
||||
guint last)
|
||||
{
|
||||
if (address >= symbols [last].address)
|
||||
{
|
||||
return &symbols [last];
|
||||
}
|
||||
else if (last - first < 3)
|
||||
{
|
||||
while (last >= first)
|
||||
{
|
||||
if (address >= symbols[last].address)
|
||||
return &symbols [last];
|
||||
|
||||
last--;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
int mid = (first + last) / 2;
|
||||
|
||||
if (symbols [mid].address > address)
|
||||
return sp_kernel_symbol_lookup (symbols, address, first, mid);
|
||||
else
|
||||
return sp_kernel_symbol_lookup (symbols, address, mid, last);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sp_kernel_symbol_from_address:
|
||||
* @address: the address of the instruction pointer
|
||||
*
|
||||
* Locates the kernel symbol that contains @address.
|
||||
*
|
||||
* Returns: (transfer none): An #SpKernelSymbol or %NULL.
|
||||
*/
|
||||
const SpKernelSymbol *
|
||||
sp_kernel_symbol_from_address (SpCaptureAddress address)
|
||||
{
|
||||
const SpKernelSymbol *first;
|
||||
|
||||
if (G_UNLIKELY (kernel_symbols == NULL))
|
||||
{
|
||||
if (!sp_kernel_symbol_load ())
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_assert (kernel_symbols != NULL);
|
||||
g_assert (kernel_symbols->len > 0);
|
||||
|
||||
/* Short circuit if this is out of range */
|
||||
first = &g_array_index (kernel_symbols, SpKernelSymbol, 0);
|
||||
if (address < first->address)
|
||||
return NULL;
|
||||
|
||||
return sp_kernel_symbol_lookup ((SpKernelSymbol *)(gpointer)kernel_symbols->data,
|
||||
address,
|
||||
0,
|
||||
kernel_symbols->len - 1);
|
||||
}
|
||||
36
lib/symbols/sp-kernel-symbol.h
Normal file
36
lib/symbols/sp-kernel-symbol.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* sp-kernel-symbol.h
|
||||
*
|
||||
* Copyright (C) 2016 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SP_KERNEL_SYMBOL_H
|
||||
#define SP_KERNEL_SYMBOL_H
|
||||
|
||||
#include "capture/sp-capture-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SpCaptureAddress address;
|
||||
const gchar *name;
|
||||
} SpKernelSymbol;
|
||||
|
||||
const SpKernelSymbol *sp_kernel_symbol_from_address (SpCaptureAddress address);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* SP_KERNEL_SYMBOL_H */
|
||||
124
lib/symbols/sp-symbol-dirs.c
Normal file
124
lib/symbols/sp-symbol-dirs.c
Normal file
@ -0,0 +1,124 @@
|
||||
/* sp-symbol-dirs.c
|
||||
*
|
||||
* Copyright (C) 2017 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "symbols/sp-symbol-dirs.h"
|
||||
|
||||
static GPtrArray *sp_symbol_dirs;
|
||||
|
||||
G_LOCK_DEFINE (sp_symbol_dirs);
|
||||
|
||||
static GPtrArray *
|
||||
sp_get_symbol_dirs_locked (void)
|
||||
{
|
||||
if (sp_symbol_dirs == NULL)
|
||||
{
|
||||
sp_symbol_dirs = g_ptr_array_new ();
|
||||
g_ptr_array_add (sp_symbol_dirs, g_strdup ("/usr/lib/debug"));
|
||||
}
|
||||
|
||||
return sp_symbol_dirs;
|
||||
}
|
||||
|
||||
void
|
||||
sp_symbol_dirs_add (const gchar *path)
|
||||
{
|
||||
GPtrArray *ar;
|
||||
|
||||
G_LOCK (sp_symbol_dirs);
|
||||
|
||||
ar = sp_get_symbol_dirs_locked ();
|
||||
|
||||
for (guint i = 0; i < ar->len; i++)
|
||||
{
|
||||
const gchar *ele = g_ptr_array_index (ar, i);
|
||||
|
||||
if (g_strcmp0 (path, ele) == 0)
|
||||
goto skip;
|
||||
}
|
||||
|
||||
g_ptr_array_add (ar, g_strdup (path));
|
||||
|
||||
skip:
|
||||
G_UNLOCK (sp_symbol_dirs);
|
||||
}
|
||||
|
||||
void
|
||||
sp_symbol_dirs_remove (const gchar *path)
|
||||
{
|
||||
GPtrArray *ar;
|
||||
|
||||
G_LOCK (sp_symbol_dirs);
|
||||
|
||||
ar = sp_get_symbol_dirs_locked ();
|
||||
|
||||
for (guint i = 0; i < ar->len; i++)
|
||||
{
|
||||
const gchar *ele = g_ptr_array_index (ar, i);
|
||||
|
||||
if (g_strcmp0 (path, ele) == 0)
|
||||
{
|
||||
g_ptr_array_remove_index (ar, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
G_UNLOCK (sp_symbol_dirs);
|
||||
}
|
||||
|
||||
/**
|
||||
* sp_symbol_dirs_get_paths:
|
||||
* @dir: the directory containing the library
|
||||
* @name: the name of the file in @dir
|
||||
*
|
||||
* This function will build an array of files to look at to resolve the
|
||||
* debug symbols for the file at path "dir/name".
|
||||
*
|
||||
* Returns: (transfer full): A #GStrv of possible paths.
|
||||
*/
|
||||
gchar **
|
||||
sp_symbol_dirs_get_paths (const gchar *dir,
|
||||
const gchar *name)
|
||||
{
|
||||
GPtrArray *ret = g_ptr_array_new ();
|
||||
GPtrArray *ar;
|
||||
|
||||
g_ptr_array_add (ret, g_build_filename (dir, name, NULL));
|
||||
|
||||
G_LOCK (sp_symbol_dirs);
|
||||
|
||||
ar = sp_get_symbol_dirs_locked ();
|
||||
|
||||
for (guint i = 0; i < ar->len; i++)
|
||||
{
|
||||
const gchar *ele = g_ptr_array_index (ar, i);
|
||||
|
||||
g_ptr_array_add (ret, g_build_filename (ele, name, NULL));
|
||||
g_ptr_array_add (ret, g_build_filename (ele, dir, name, NULL));
|
||||
}
|
||||
|
||||
g_ptr_array_add (ret, g_build_filename (dir, ".debug", name, NULL));
|
||||
g_ptr_array_add (ret, g_build_filename (DEBUGDIR, dir, name, NULL));
|
||||
|
||||
G_UNLOCK (sp_symbol_dirs);
|
||||
|
||||
g_ptr_array_add (ret, NULL);
|
||||
|
||||
return (gchar **)g_ptr_array_free (ret, FALSE);
|
||||
}
|
||||
33
lib/symbols/sp-symbol-dirs.h
Normal file
33
lib/symbols/sp-symbol-dirs.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* sp-symbol-dirs.h
|
||||
*
|
||||
* Copyright (C) 2017 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SP_SYMBOL_DIRS_H
|
||||
#define SP_SYMBOL_DIRS_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void sp_symbol_dirs_add (const gchar *dir);
|
||||
void sp_symbol_dirs_remove (const gchar *dir);
|
||||
gchar **sp_symbol_dirs_get_paths (const gchar *dir,
|
||||
const gchar *name);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* SP_SYMBOL_DIRS_H */
|
||||
72
lib/symbols/sp-symbol-resolver.c
Normal file
72
lib/symbols/sp-symbol-resolver.c
Normal file
@ -0,0 +1,72 @@
|
||||
/* sp-symbol-resolver.c
|
||||
*
|
||||
* Copyright (C) 2016 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "symbols/sp-symbol-resolver.h"
|
||||
|
||||
G_DEFINE_INTERFACE (SpSymbolResolver, sp_symbol_resolver, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
sp_symbol_resolver_default_init (SpSymbolResolverInterface *iface)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
sp_symbol_resolver_load (SpSymbolResolver *self,
|
||||
SpCaptureReader *reader)
|
||||
{
|
||||
g_return_if_fail (SP_IS_SYMBOL_RESOLVER (self));
|
||||
g_return_if_fail (reader != NULL);
|
||||
|
||||
if (SP_SYMBOL_RESOLVER_GET_IFACE (self)->load)
|
||||
SP_SYMBOL_RESOLVER_GET_IFACE (self)->load (self, reader);
|
||||
}
|
||||
|
||||
/**
|
||||
* sp_symbol_resolver_resolve:
|
||||
* @self: A #SpSymbolResolver
|
||||
* @time: The time of the sample
|
||||
* @pid: The process generating the sample
|
||||
* @address: the sample address
|
||||
* @tag: (out): A tag for the symbol.
|
||||
*
|
||||
* Gets the symbol name for @address that was part of process @pid
|
||||
* at @time. Optionally, you can set @tag to a quark describing the
|
||||
* symbol. This can be used to provide a bit more information when
|
||||
* rendering the treeview. You might choose to describe the library
|
||||
* such as "GObject" or "GTK+" or "Linux" for the kernel.
|
||||
*
|
||||
* Returns: (nullable) (transfer full): A newly allocated string, or %NULL.
|
||||
*/
|
||||
gchar *
|
||||
sp_symbol_resolver_resolve (SpSymbolResolver *self,
|
||||
guint64 time,
|
||||
GPid pid,
|
||||
SpCaptureAddress address,
|
||||
GQuark *tag)
|
||||
{
|
||||
GQuark dummy;
|
||||
|
||||
g_return_val_if_fail (SP_IS_SYMBOL_RESOLVER (self), NULL);
|
||||
|
||||
if (tag == NULL)
|
||||
tag = &dummy;
|
||||
|
||||
*tag = 0;
|
||||
|
||||
return SP_SYMBOL_RESOLVER_GET_IFACE (self)->resolve (self, time, pid, address, tag);
|
||||
}
|
||||
55
lib/symbols/sp-symbol-resolver.h
Normal file
55
lib/symbols/sp-symbol-resolver.h
Normal file
@ -0,0 +1,55 @@
|
||||
/* sp-symbol-resolver.h
|
||||
*
|
||||
* Copyright (C) 2016 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SP_SYMBOL_RESOLVER_H
|
||||
#define SP_SYMBOL_RESOLVER_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "capture/sp-capture-reader.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define SP_TYPE_SYMBOL_RESOLVER (sp_symbol_resolver_get_type())
|
||||
|
||||
G_DECLARE_INTERFACE (SpSymbolResolver, sp_symbol_resolver, SP, SYMBOL_RESOLVER, GObject)
|
||||
|
||||
struct _SpSymbolResolverInterface
|
||||
{
|
||||
GTypeInterface parent_interface;
|
||||
|
||||
void (*load) (SpSymbolResolver *self,
|
||||
SpCaptureReader *reader);
|
||||
gchar *(*resolve) (SpSymbolResolver *self,
|
||||
guint64 time,
|
||||
GPid pid,
|
||||
SpCaptureAddress address,
|
||||
GQuark *tag);
|
||||
};
|
||||
|
||||
void sp_symbol_resolver_load (SpSymbolResolver *self,
|
||||
SpCaptureReader *reader);
|
||||
gchar *sp_symbol_resolver_resolve (SpSymbolResolver *self,
|
||||
guint64 time,
|
||||
GPid pid,
|
||||
SpCaptureAddress address,
|
||||
GQuark *tag);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* SP_SYMBOL_RESOLVER_H */
|
||||
Reference in New Issue
Block a user