1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 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);
}
|