예제 #1
0
static ElfParser *
get_build_id_file (ElfParser *elf)
{
    const char *build_id;
    GList *tries = NULL, *list;
    char *init, *rest;
    ElfParser *result = NULL;
    char *tmp;

    build_id = elf_parser_get_build_id (elf);

    if (!build_id)
        return NULL;

    if (strlen (build_id) < 4)
        return NULL;

    init = g_strndup (build_id, 2);
    rest = g_strdup_printf ("%s%s", build_id + 2, ".debug");

    tmp = g_build_filename (
        "/usr", "lib", "debug", ".build-id", init, rest, NULL);
    tries = g_list_append (tries, tmp);

    tmp = g_build_filename (
        debug_file_directory, ".build-id", init, rest, NULL);
    tries = g_list_append (tries, tmp);

    for (list = tries; list != NULL; list = list->next)
    {
        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)
            {
                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;
}
예제 #2
0
int
main (int argc, char **argv)
{
    ElfParser *elf;
    const char *build_id;
    const char *filename;

    if (argc == 1)
	filename = "/usr/lib/libgtk-x11-2.0.so";
    else
	filename = argv[1];

    elf = elf_parser_new (filename, NULL);

    if (!elf)
    {
	g_print ("NO ELF!!!!\n");
	return -1;
    }

    build_id = elf_parser_get_build_id (elf);

    g_print ("build ID: %s\n", build_id);
    
    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)) */
	
	check (elf, 0x077c80f0 - (0x07787000 - 0)); /* same (but in the middle of the function */
    }
    return 0;
}
예제 #3
0
static ElfParser *
get_debuglink_file (ElfParser   *elf,
                    const char  *filename,
                    char       **new_name)
{
#define N_TRIES 4
    const char *basename;
    char *dir;
    guint32 crc32;
    GList *tries = NULL, *list;
    ElfParser *result = NULL;
    const char *build_id;

    if (!elf)
        return NULL;

    basename = elf_parser_get_debug_link (elf, &crc32);

    build_id = elf_parser_get_build_id (elf);

#if 0
    g_print ("   debug link for %s is %s\n", filename, basename);
#endif

    if (!basename)
        return NULL;

    dir = g_path_get_dirname (filename);

    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 (list = tries; list != NULL; list = list->next)
    {
        const char *name = list->data;
        ElfParser *parser = elf_parser_new (name, NULL);
        guint32 file_crc;
        const char *file_build_id;

        if (parser)
        {
            /* If both files have build ids, and they don't match,
             * there is no point computing a CRC32 that we know
             * will fail
             */
            file_build_id = elf_parser_get_build_id (parser);
            if (build_id && file_build_id && strcmp (build_id, file_build_id) != 0)
                goto skip;

            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 %x, %s has crc %x)\n",
                             name, file_crc, filename, crc32);
                }
            }

        skip:
            elf_parser_free (parser);
        }
    }

    g_free (dir);

    g_list_foreach (tries, (GFunc)g_free, NULL);
    g_list_free (tries);

    return result;
}