static int cmd_profile(char *args) { long long ins = -1; bool forever = false; if (args) { if (0 == sscanf(args, "%llu", &ins)) { printf("Invalid argument: %s\n", args); return 0; } } else forever = true; if (ins < 0) forever = true; int count = 0; while (forever || ins > 0) { cpu_exec(10000); const char *func_name = elf_find_func(cpu.eip); if (func_name && strlen(func_name) != 0) { profile_record(func_name); } ins -= 10000; count++; if (count % 1000 == 0) { count = 0; profile_print_result(); printf("\n"); } if (nemu_state == END) break; } profile_print_result(); return 0; }
unsigned int elf_get_func_len(void *e_obj, unsigned int func) { struct elf_obj *obj = e_obj; Elf32_Sym *func_sym = elf_find_func(obj, func); if(func_sym) return func_sym->st_size; return 0; }
char *elf_get_func_name(void *e_obj, unsigned int func) { struct elf_obj *obj = e_obj; Elf32_Sym *func_sym = elf_find_func(obj, func); if(func_sym) return obj->e_sections[obj->e_sym_str_tab] + func_sym->st_name; return NULL; }
void *elf_get_func_start(void *e_obj, unsigned int func) { struct elf_obj *obj = e_obj; Elf32_Sym *func_sym = elf_find_func(obj, func); if(!func_sym) return NULL; if(func_sym->st_shndx == SHN_COMMON) { fprintf(stderr, "Don't know how to handle SHN_COMMON section header\n"); return NULL; } return obj->e_sections[func_sym->st_shndx] + func_sym->st_value; }
int elf_get_func_reloc(void *e_obj, unsigned int func, unsigned int relocn, struct reloc *reloc) { struct elf_obj *obj = e_obj; Elf32_Sym *func_sym = elf_find_func(obj, func); Elf32_Rel *cur; Elf32_Rela *cura; int i, j; /* if(obj->e_rel_sec != func_sym->st_shndx) { fprintf(stderr, "Don't know what to do: Function does not have a relocation table\n"); return 0; } */ for(i = 0, j = 0, cur = obj->e_rels; i < obj->e_rel_num; i++, cur++) { if((cur->r_offset - func_sym->st_value) > func_sym->st_size) continue; if(relocn == j) { reloc->name = elf_get_sym_name(obj, ELF32_R_SYM(cur->r_info)); reloc->func_offset = cur->r_offset - func_sym->st_value; reloc->type = ELF32_R_TYPE(cur->r_info); /* FIXME: Byte-swap */ reloc->addend = *(uint32_t *)(obj->e_sections[obj->e_rel_sec] + cur->r_offset); return 1; } j++; } if(!obj->e_relas) return 0; for(i = 0, cura = obj->e_relas; i < obj->e_rela_num; i++, cura++) { if((cura->r_offset - func_sym->st_value) > func_sym->st_size) continue; if(relocn == j) { reloc->name = elf_get_sym_name(obj, ELF32_R_SYM(cur->r_info)); reloc->func_offset = cura->r_offset - func_sym->st_value; reloc->type = ELF32_R_TYPE(cur->r_info); reloc->addend = cura->r_addend; return 1; } j++; } return 0; }
static int cmd_bt(char *args) { static bool called = false; if (called) { // in panicking return 1; } called = true; StackFrameBottom st; st.prev_ebp = cpu.ebp; st.ret_addr = cpu.eip; int count = 0; do { swaddr_t eip_temp = st.ret_addr; swaddr_t ebp_temp = st.prev_ebp; swaddr_read_bytes(&st, ebp_temp, sizeof(StackFrameBottom), sreg_index(ss)); const char *func_name = elf_find_func(eip_temp); if (func_name == NULL) func_name = "??"; printf("#%d\t0x%08x in %s (%#x, %#x, %#x, %#x)\n", count, eip_temp, func_name, st.args[0] , st.args[1], st.args[2], st.args[3]); count++; } while (st.prev_ebp); called = false; return 0; }