mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-12 08:00:53 +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>
|
Sun Apr 20 16:55:47 2008 Søren Sandmann <sandmann@redhat.com>
|
||||||
|
|
||||||
* elfparser.c (elf_parser_new_from_data): Initial build-id support
|
* elfparser.c (elf_parser_new_from_data): Initial build-id support
|
||||||
|
|||||||
131
binfile.c
131
binfile.c
@ -88,42 +88,6 @@ already_warned (const char *name)
|
|||||||
return FALSE;
|
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 const char *const debug_file_directory = DEBUGDIR;
|
||||||
|
|
||||||
static ElfParser *
|
static ElfParser *
|
||||||
@ -135,9 +99,8 @@ get_debuglink_file (ElfParser *elf,
|
|||||||
const char *basename;
|
const char *basename;
|
||||||
char *dir;
|
char *dir;
|
||||||
guint32 crc32;
|
guint32 crc32;
|
||||||
char *tries[N_TRIES];
|
GList *tries = NULL, *list;
|
||||||
int i;
|
ElfParser *result = NULL;
|
||||||
ElfParser *result;
|
|
||||||
|
|
||||||
if (!elf)
|
if (!elf)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -153,32 +116,41 @@ get_debuglink_file (ElfParser *elf,
|
|||||||
|
|
||||||
dir = g_path_get_dirname (filename);
|
dir = g_path_get_dirname (filename);
|
||||||
|
|
||||||
tries[0] = g_build_filename (dir, basename, NULL);
|
tries = g_list_append (tries, g_build_filename (dir, basename, NULL));
|
||||||
tries[1] = g_build_filename (dir, ".debug", basename, NULL);
|
tries = g_list_append (tries, g_build_filename (dir, ".debug", basename, NULL));
|
||||||
tries[2] = g_build_filename ("/usr", "lib", "debug", dir, basename, NULL);
|
tries = g_list_append (tries, 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 (debug_file_directory, dir, basename, NULL));
|
||||||
|
|
||||||
for (i = 0; i < N_TRIES; ++i)
|
for (list = tries; list != NULL; list = list->next)
|
||||||
{
|
{
|
||||||
#if 0
|
const char *name = list->data;
|
||||||
g_print ("trying: %s\n", tries[i]);
|
ElfParser *parser = elf_parser_new (name, NULL);
|
||||||
#endif
|
guint32 file_crc;
|
||||||
result = separate_debug_file_exists (tries[i], crc32);
|
|
||||||
if (result)
|
if (parser)
|
||||||
{
|
{
|
||||||
#if 0
|
file_crc = elf_parser_get_crc32 (parser);
|
||||||
g_print (" found debug binary for %s: %s\n", filename, tries[i]);
|
|
||||||
#endif
|
if (file_crc == crc32)
|
||||||
if (new_name)
|
{
|
||||||
*new_name = g_strdup (tries[i]);
|
result = parser;
|
||||||
break;
|
*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);
|
g_free (dir);
|
||||||
|
|
||||||
for (i = 0; i < N_TRIES; ++i)
|
g_list_foreach (tries, (GFunc)g_free, NULL);
|
||||||
g_free (tries[i]);
|
g_list_free (tries);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -188,7 +160,50 @@ get_build_id_file (ElfParser *elf,
|
|||||||
const char *filename,
|
const char *filename,
|
||||||
char **new_name)
|
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 *
|
static ElfParser *
|
||||||
|
|||||||
38
elfparser.c
38
elfparser.c
@ -642,6 +642,27 @@ elf_parser_get_text_offset (ElfParser *parser)
|
|||||||
return parser->text_section->offset;
|
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 *
|
const gchar *
|
||||||
elf_parser_get_build_id (ElfParser *parser)
|
elf_parser_get_build_id (ElfParser *parser)
|
||||||
{
|
{
|
||||||
@ -652,11 +673,7 @@ elf_parser_get_build_id (ElfParser *parser)
|
|||||||
guint64 desc_size;
|
guint64 desc_size;
|
||||||
guint64 type;
|
guint64 type;
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *desc;
|
const gchar *desc;
|
||||||
GString *string;
|
|
||||||
int i;
|
|
||||||
const char hex_digits[] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
|
||||||
'a', 'b', 'c', 'd', 'e', 'f' };
|
|
||||||
|
|
||||||
parser->checked_build_id = TRUE;
|
parser->checked_build_id = TRUE;
|
||||||
|
|
||||||
@ -669,21 +686,14 @@ elf_parser_get_build_id (ElfParser *parser)
|
|||||||
desc_size = bin_parser_get_uint_field (parser->parser, parser->note_format, "desc_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");
|
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);
|
name = bin_parser_get_string (parser->parser);
|
||||||
|
|
||||||
bin_parser_align (parser->parser, 4);
|
bin_parser_align (parser->parser, 4);
|
||||||
|
|
||||||
desc = bin_parser_get_string (parser->parser);
|
desc = bin_parser_get_string (parser->parser);
|
||||||
|
|
||||||
string = g_string_new (NULL);
|
parser->build_id = make_hex_string (desc, desc_size);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return parser->build_id;
|
return parser->build_id;
|
||||||
|
|||||||
@ -41,7 +41,7 @@ main (int argc, char **argv)
|
|||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
filename = "/usr/lib/libgtk-x11-2.0.so";
|
filename = "/usr/lib/libgtk-x11-2.0.so";
|
||||||
else
|
else
|
||||||
filename = argv[0];
|
filename = argv[1];
|
||||||
|
|
||||||
elf = elf_parser_new (filename, NULL);
|
elf = elf_parser_new (filename, NULL);
|
||||||
|
|
||||||
@ -57,7 +57,9 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
elf_parser_get_crc32 (elf);
|
elf_parser_get_crc32 (elf);
|
||||||
|
|
||||||
|
#if 0
|
||||||
for (i = 0; i < 5000000; ++i)
|
for (i = 0; i < 5000000; ++i)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
elf_parser_get_crc32 (elf);
|
elf_parser_get_crc32 (elf);
|
||||||
check (elf, 0x077c80f0 - (0x07787000 - 0)); /* gtk_about_dialog_set_artists (add - (map - offset)) */
|
check (elf, 0x077c80f0 - (0x07787000 - 0)); /* gtk_about_dialog_set_artists (add - (map - offset)) */
|
||||||
|
|||||||
Reference in New Issue
Block a user