More build-id work

svn path=/trunk/; revision=411
This commit is contained in:
Søren Sandmann Pedersen
2008-04-21 20:12:36 +00:00
parent 90d1fa1de5
commit f49c3b5d2e
4 changed files with 108 additions and 77 deletions

View File

@ -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
View File

@ -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 *

View File

@ -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;

View File

@ -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)) */