mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
More build-id work
svn path=/trunk/; revision=411
This commit is contained in:
@ -1,3 +1,7 @@
|
||||
Mon Apr 21 15:54:24 2008 Søren Sandmann <sandmann@redhat.com>
|
||||
|
||||
* binfile.c: More build-id support
|
||||
|
||||
Sun Apr 20 16:55:47 2008 Søren Sandmann <sandmann@redhat.com>
|
||||
|
||||
* elfparser.c (elf_parser_new_from_data): Initial build-id support
|
||||
|
||||
133
binfile.c
133
binfile.c
@ -88,42 +88,6 @@ already_warned (const char *name)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static ElfParser *
|
||||
separate_debug_file_exists (const char *name, guint32 crc)
|
||||
{
|
||||
guint32 file_crc;
|
||||
ElfParser *parser = elf_parser_new (name, NULL);
|
||||
|
||||
#if 0
|
||||
g_print (" trying %s: ", name);
|
||||
#endif
|
||||
if (!parser)
|
||||
{
|
||||
#if 0
|
||||
g_print ("no.\n");
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
file_crc = elf_parser_get_crc32 (parser);
|
||||
|
||||
if (file_crc != crc)
|
||||
{
|
||||
if (!already_warned (name))
|
||||
g_print ("warning: %s has wrong crc \n", name);
|
||||
|
||||
elf_parser_free (parser);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
g_print ("found\n");
|
||||
#endif
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
static const char *const debug_file_directory = DEBUGDIR;
|
||||
|
||||
static ElfParser *
|
||||
@ -135,9 +99,8 @@ get_debuglink_file (ElfParser *elf,
|
||||
const char *basename;
|
||||
char *dir;
|
||||
guint32 crc32;
|
||||
char *tries[N_TRIES];
|
||||
int i;
|
||||
ElfParser *result;
|
||||
GList *tries = NULL, *list;
|
||||
ElfParser *result = NULL;
|
||||
|
||||
if (!elf)
|
||||
return NULL;
|
||||
@ -153,32 +116,41 @@ get_debuglink_file (ElfParser *elf,
|
||||
|
||||
dir = g_path_get_dirname (filename);
|
||||
|
||||
tries[0] = g_build_filename (dir, basename, NULL);
|
||||
tries[1] = g_build_filename (dir, ".debug", basename, NULL);
|
||||
tries[2] = g_build_filename ("/usr", "lib", "debug", dir, basename, NULL);
|
||||
tries[3] = g_build_filename (debug_file_directory, dir, basename, NULL);
|
||||
tries = g_list_append (tries, g_build_filename (dir, basename, NULL));
|
||||
tries = g_list_append (tries, g_build_filename (dir, ".debug", basename, NULL));
|
||||
tries = g_list_append (tries, g_build_filename ("/usr", "lib", "debug", dir, basename, NULL));
|
||||
tries = g_list_append (tries, g_build_filename (debug_file_directory, dir, basename, NULL));
|
||||
|
||||
for (i = 0; i < N_TRIES; ++i)
|
||||
for (list = tries; list != NULL; list = list->next)
|
||||
{
|
||||
#if 0
|
||||
g_print ("trying: %s\n", tries[i]);
|
||||
#endif
|
||||
result = separate_debug_file_exists (tries[i], crc32);
|
||||
if (result)
|
||||
const char *name = list->data;
|
||||
ElfParser *parser = elf_parser_new (name, NULL);
|
||||
guint32 file_crc;
|
||||
|
||||
if (parser)
|
||||
{
|
||||
#if 0
|
||||
g_print (" found debug binary for %s: %s\n", filename, tries[i]);
|
||||
#endif
|
||||
if (new_name)
|
||||
*new_name = g_strdup (tries[i]);
|
||||
break;
|
||||
file_crc = elf_parser_get_crc32 (parser);
|
||||
|
||||
if (file_crc == crc32)
|
||||
{
|
||||
result = parser;
|
||||
*new_name = g_strdup (name);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!already_warned (name))
|
||||
g_print ("warning: %s has wrong crc \n", name);
|
||||
}
|
||||
|
||||
elf_parser_free (parser);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
g_free (dir);
|
||||
|
||||
for (i = 0; i < N_TRIES; ++i)
|
||||
g_free (tries[i]);
|
||||
g_list_foreach (tries, (GFunc)g_free, NULL);
|
||||
g_list_free (tries);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -188,7 +160,50 @@ get_build_id_file (ElfParser *elf,
|
||||
const char *filename,
|
||||
char **new_name)
|
||||
{
|
||||
return NULL;
|
||||
const char *build_id = elf_parser_get_build_id (elf);
|
||||
GList *tries = NULL, *list;
|
||||
char *init, *rest;
|
||||
ElfParser *result = NULL;
|
||||
|
||||
if (!build_id)
|
||||
return NULL;
|
||||
|
||||
if (strlen (build_id) < 4)
|
||||
return NULL;
|
||||
|
||||
init = g_strndup (build_id, 2);
|
||||
rest = g_strdup_printf (build_id + 2, ".debug");
|
||||
|
||||
tries = g_list_append (tries, g_build_filename ("/usr", "lib", "debug", ".build-id", init, rest, NULL));
|
||||
tries = g_list_append (tries, g_build_filename (debug_file_directory, ".build-id", init, rest, NULL));
|
||||
|
||||
for (list = tries; list != NULL; list = list->next)
|
||||
{
|
||||
const char *name = list->data;
|
||||
ElfParser *parser = elf_parser_new (name, NULL);
|
||||
|
||||
if (parser)
|
||||
{
|
||||
const char *file_id = elf_parser_get_build_id (parser);
|
||||
|
||||
if (file_id && strcmp (build_id, file_id) == 0)
|
||||
{
|
||||
*new_name = g_strdup (filename);
|
||||
result = parser;
|
||||
break;
|
||||
}
|
||||
|
||||
elf_parser_free (parser);
|
||||
}
|
||||
}
|
||||
|
||||
g_list_foreach (tries, (GFunc)g_free, NULL);
|
||||
g_list_free (tries);
|
||||
|
||||
g_free (init);
|
||||
g_free (rest);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static ElfParser *
|
||||
|
||||
44
elfparser.c
44
elfparser.c
@ -642,6 +642,27 @@ elf_parser_get_text_offset (ElfParser *parser)
|
||||
return parser->text_section->offset;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
make_hex_string (const guchar *data, int n_bytes)
|
||||
{
|
||||
GString *string = g_string_new (NULL);
|
||||
const char hex_digits[] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_bytes; ++i)
|
||||
{
|
||||
char c = data[i];
|
||||
|
||||
g_string_append_c (string, hex_digits[(c & 0xf0) >> 4]);
|
||||
g_string_append_c (string, hex_digits[(c & 0x0f)]);
|
||||
}
|
||||
|
||||
return g_string_free (string, FALSE);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
elf_parser_get_build_id (ElfParser *parser)
|
||||
{
|
||||
@ -652,11 +673,7 @@ elf_parser_get_build_id (ElfParser *parser)
|
||||
guint64 desc_size;
|
||||
guint64 type;
|
||||
const char *name;
|
||||
const char *desc;
|
||||
GString *string;
|
||||
int i;
|
||||
const char hex_digits[] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
const gchar *desc;
|
||||
|
||||
parser->checked_build_id = TRUE;
|
||||
|
||||
@ -668,22 +685,15 @@ elf_parser_get_build_id (ElfParser *parser)
|
||||
name_size = bin_parser_get_uint_field (parser->parser, parser->note_format, "name_size");
|
||||
desc_size = bin_parser_get_uint_field (parser->parser, parser->note_format, "desc_size");
|
||||
type = bin_parser_get_uint_field (parser->parser, parser->note_format, "type");
|
||||
|
||||
|
||||
bin_parser_seek_record (parser->parser, parser->note_format, 1);
|
||||
name = bin_parser_get_string (parser->parser);
|
||||
|
||||
|
||||
bin_parser_align (parser->parser, 4);
|
||||
|
||||
desc = bin_parser_get_string (parser->parser);
|
||||
|
||||
string = g_string_new (NULL);
|
||||
|
||||
for (i = 0; i < desc_size; ++i)
|
||||
{
|
||||
g_string_append_c (string, hex_digits[desc[i] & 0xf0]);
|
||||
g_string_append_c (string, hex_digits[desc[i] & 0x0f]);
|
||||
}
|
||||
|
||||
parser->build_id = g_string_free (string, FALSE);
|
||||
|
||||
parser->build_id = make_hex_string (desc, desc_size);
|
||||
}
|
||||
|
||||
return parser->build_id;
|
||||
|
||||
@ -41,7 +41,7 @@ main (int argc, char **argv)
|
||||
if (argc == 1)
|
||||
filename = "/usr/lib/libgtk-x11-2.0.so";
|
||||
else
|
||||
filename = argv[0];
|
||||
filename = argv[1];
|
||||
|
||||
elf = elf_parser_new (filename, NULL);
|
||||
|
||||
@ -57,7 +57,9 @@ main (int argc, char **argv)
|
||||
|
||||
elf_parser_get_crc32 (elf);
|
||||
|
||||
#if 0
|
||||
for (i = 0; i < 5000000; ++i)
|
||||
#endif
|
||||
{
|
||||
elf_parser_get_crc32 (elf);
|
||||
check (elf, 0x077c80f0 - (0x07787000 - 0)); /* gtk_about_dialog_set_artists (add - (map - offset)) */
|
||||
|
||||
Reference in New Issue
Block a user