mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
libsysprof-analyze: leave some notes on elf symbolizing
This commit is contained in:
@ -24,6 +24,9 @@ libsysprof_analyze_public_sources = [
|
||||
]
|
||||
|
||||
libsysprof_analyze_private_sources = [
|
||||
'../libsysprof/binfile.c',
|
||||
'../libsysprof/demangle.cpp',
|
||||
'../libsysprof/elfparser.c',
|
||||
'sysprof-address-layout.c',
|
||||
'sysprof-document-bitset-index.c',
|
||||
'sysprof-document-symbols.c',
|
||||
|
||||
@ -20,6 +20,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "../libsysprof/binfile.h"
|
||||
|
||||
#include "sysprof-elf-symbolizer.h"
|
||||
#include "sysprof-document-private.h"
|
||||
#include "sysprof-strings-private.h"
|
||||
@ -28,7 +30,8 @@
|
||||
|
||||
struct _SysprofElfSymbolizer
|
||||
{
|
||||
SysprofSymbolizer parent_instance;
|
||||
SysprofSymbolizer parent_instance;
|
||||
GHashTable *bin_file_cache;
|
||||
};
|
||||
|
||||
struct _SysprofElfSymbolizerClass
|
||||
@ -45,11 +48,79 @@ sysprof_elf_symbolizer_symbolize (SysprofSymbolizer *symbolizer,
|
||||
SysprofAddressContext context,
|
||||
SysprofAddress address)
|
||||
{
|
||||
if (context != SYSPROF_ADDRESS_CONTEXT_NONE &&
|
||||
context != SYSPROF_ADDRESS_CONTEXT_USER)
|
||||
SysprofElfSymbolizer *self = (SysprofElfSymbolizer *)symbolizer;
|
||||
SysprofDocumentMmap *map;
|
||||
g_autofree char *name = NULL;
|
||||
g_auto(GStrv) translations = NULL;
|
||||
GMappedFile *mapped_file = NULL;
|
||||
const char *path;
|
||||
|
||||
if (process_info == NULL ||
|
||||
process_info->address_layout == NULL ||
|
||||
process_info->mount_namespace == NULL ||
|
||||
(context != SYSPROF_ADDRESS_CONTEXT_NONE &&
|
||||
context != SYSPROF_ADDRESS_CONTEXT_USER))
|
||||
return NULL;
|
||||
|
||||
return NULL;
|
||||
/* First find out what was mapped at that address */
|
||||
if (!(map = sysprof_address_layout_lookup (process_info->address_layout, address)))
|
||||
return NULL;
|
||||
|
||||
/* The file could be available at a number of locations in case there
|
||||
* is an overlayfs, flatpak runtime, etc. Additionally, we may need
|
||||
* to resolve through various debug directories. All of those also
|
||||
* need to get translated to a location where this process can access
|
||||
* then (which itself might be via /var/run/host/... or similar).
|
||||
*/
|
||||
path = sysprof_document_mmap_get_file (map);
|
||||
|
||||
/* TODO:
|
||||
*
|
||||
* We need something like bin_file_t here that will let us look at
|
||||
* all of our possible translations for the file (overlayfs, etc)
|
||||
* and add debug directories on top of that. The debug directories
|
||||
* can be used to follow .gnu_debuglink through debug dirs.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
if (!(translations = sysprof_mount_namespace_translate (process_info->mount_namespace, path)))
|
||||
goto fallback;
|
||||
|
||||
for (guint i = 0; translations[i]; i++)
|
||||
{
|
||||
/* If the file exists within our cache already, re-use that instead
|
||||
* of re-opening a binfile.
|
||||
*/
|
||||
if ((mapped_file = g_hash_table_lookup (self->bin_file_cache, translations[i])))
|
||||
break;
|
||||
|
||||
if ((mapped_file = g_mapped_file_new (translations[i], FALSE, NULL)))
|
||||
{
|
||||
g_hash_table_insert (self->bin_file_cache,
|
||||
g_strdup (translations[i]),
|
||||
mapped_file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mapped_file == NULL)
|
||||
goto fallback;
|
||||
#endif
|
||||
|
||||
fallback:
|
||||
/* Fallback, we failed to locate the symbol within a file we can
|
||||
* access, so tell the user about what file contained the symbol
|
||||
* and the offset of the ELF section mapped.
|
||||
*/
|
||||
name = g_strdup_printf ("In file %s <+0x%"G_GINT64_MODIFIER"x>",
|
||||
sysprof_document_mmap_get_file (map),
|
||||
sysprof_document_mmap_get_file_offset (map));
|
||||
|
||||
return _sysprof_symbol_new (sysprof_strings_get (strings, name),
|
||||
NULL,
|
||||
NULL,
|
||||
sysprof_document_mmap_get_start_address (map),
|
||||
sysprof_document_mmap_get_end_address (map));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -57,6 +128,8 @@ sysprof_elf_symbolizer_finalize (GObject *object)
|
||||
{
|
||||
SysprofElfSymbolizer *self = (SysprofElfSymbolizer *)object;
|
||||
|
||||
g_clear_pointer (&self->bin_file_cache, g_hash_table_unref);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_elf_symbolizer_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@ -74,6 +147,10 @@ sysprof_elf_symbolizer_class_init (SysprofElfSymbolizerClass *klass)
|
||||
static void
|
||||
sysprof_elf_symbolizer_init (SysprofElfSymbolizer *self)
|
||||
{
|
||||
self->bin_file_cache = g_hash_table_new_full (g_str_hash,
|
||||
g_str_equal,
|
||||
g_free,
|
||||
(GDestroyNotify)bin_file_free);
|
||||
}
|
||||
|
||||
SysprofSymbolizer *
|
||||
|
||||
Reference in New Issue
Block a user