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; }
bin_file_t * bin_file_new (const char *filename) { ElfParser *elf = NULL; bin_file_t *bf; bf = g_new0 (bin_file_t, 1); bf->inode_check = FALSE; bf->filename = g_strdup (filename); bf->undefined_name = g_strdup_printf ("In file %s", filename); bf->ref_count = 1; bf->elf_files = NULL; if (strcmp (filename, "[vdso]") == 0) { const guint8 *vdso_bytes; gsize length; vdso_bytes = get_vdso_bytes (&length); if (vdso_bytes) elf = elf_parser_new_from_data (vdso_bytes, length); } else { elf = elf_parser_new (filename, NULL); } if (elf) { /* We need the text offset of the actual binary, not the * (potential) debug binaries */ bf->text_offset = elf_parser_get_text_offset (elf); bf->elf_files = get_debug_binaries (bf->elf_files, elf, filename); bf->elf_files = g_list_append (bf->elf_files, elf); bf->inode = read_inode (filename); } return bf; }
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; }
int main (int argc, char **argv) { const guchar *data; ElfParser *elf; if (argc == 1) { g_print ("no arg\n"); return -1; } elf = elf_parser_new (argv[1], NULL); if (!elf) { g_print ("NO ELF!!!!\n"); return -1; } unwind (elf); return 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; }