int main(int argc, char** argv) { ElfFile* f = elf_open(argv[1]); stabinfo_t *s = stab_load(f); if (!s) { printf("No debug info"); return 0; } char* addr; while (scanf("%x", (unsigned int*)&addr) == 1) { stab_line_t *r = stab_find(s, (char*)addr); if (s->fns[r->fn].begin <= addr && addr < s->fns[r->fn].end) { printf("0x%08x:%s:%s:%x:%d\n", (unsigned int)addr, s->srcs[s->fns[r->fn].src].name, s->fns[r->fn].name, addr - s->fns[r->fn].begin, r->line); } else { printf("0x%08x::::\n", (unsigned int)addr); } } stab_delete(s); elf_close(f); }
int elf_dump(const char *path, uint32_t *entry, unsigned char *mem, size_t memsz) { struct elf_file file; int retval = 0; retval = elf_open(&file, path); if (retval != 0) { error(0, 0, "couldn't get started on the ELF file."); return retval; } *entry = file.ehdr.e_entry; retval = copy_all_segments(&file, mem, memsz); if (retval != 0) { error(0, 0, "couldn't read prog segments."); return retval; } return elf_close(&file); }
void kernel_binary_analyze(char *file_name) { struct elf_file_t *elf; struct elf_symbol_t *sym; int i; char file_name_prefix[MAX_STRING_SIZE]; char subdir[MAX_STRING_SIZE]; int len; char file_name_dest[MAX_STRING_SIZE]; void *section_buf; uint32_t section_size; char *section_name; /* Get file name prefix */ strcpy(file_name_prefix, file_name); len = strlen(file_name); if (len > 4 && !strcmp(file_name + len - 4, ".bin")) file_name_prefix[len - 4] = '\0'; /* Create subdirectory */ snprintf(subdir, sizeof subdir, "%s_files", file_name_prefix); mkdir(subdir, 0755); /* Analyze ELF file */ elf_debug_file = fopen("/dev/null", "wt"); elf = elf_open(file_name); if (!elf) fatal("%s: cannot open ELF file", file_name); /* List ELF sections */ printf("ELF sections:\n"); for (i = 0; i < elf_section_count(elf); i++) { uint32_t addr, offset, size, flags; elf_section_info(elf, i, §ion_name, &addr, &offset, &size, &flags); if (!size) continue; /* Dump to file */ section_buf = elf_section_read(elf, i); sprintf(file_name_dest, "%s/%s.%s", subdir, file_name_prefix, *section_name == '.' ? section_name + 1 : section_name); write_buffer(file_name_dest, section_buf, size); elf_section_free(section_buf); /* Info */ printf(" section '%s': addr=0x%x, offset=0x%x, size=%d, flags=0x%x\n", section_name, addr, offset, size, flags); } /* Get symbols */ for (i = 0; i < elf->symtab_count; i++) { char kernel_func_name[MAX_STRING_SIZE]; int kernel_func_len; int sym_len; sym = &elf->symtab[i]; if (strncmp(sym->name, "__OpenCL_", 9)) continue; sym_len = strlen(sym->name); if (!sym->size) continue; /* Read section */ elf_section_info(elf, sym->section, §ion_name, NULL, NULL, §ion_size, NULL); section_buf = elf_section_read(elf, sym->section); assert(sym->value + sym->size <= section_size); /* Dump to files */ if (str_suffix(sym->name, "_metadata")) { kernel_func_len = sym_len - 18; strncpy(kernel_func_name, sym->name + 9, kernel_func_len); kernel_func_name[kernel_func_len] = '\0'; sprintf(file_name_dest, "%s/%s.%s.metadata", subdir, file_name_prefix, kernel_func_name); write_buffer(file_name_dest, section_buf + sym->value, sym->size); printf("\t%s: meta data dumped\n", file_name_dest); } else if (str_suffix(sym->name, "_kernel")) { kernel_func_len = sym_len - 16; strncpy(kernel_func_name, sym->name + 9, kernel_func_len); kernel_func_name[kernel_func_len] = '\0'; sprintf(file_name_dest, "%s/%s.%s.kernel", subdir, file_name_prefix, kernel_func_name); write_buffer(file_name_dest, section_buf + sym->value, sym->size); printf("\t%s: inner ELF file dumped\n", file_name_dest); kernel_binary_analyze_inner_elf(file_name_dest); } /* Free section */ elf_section_free(section_buf); } /* Close file */ elf_close(elf); }