int msp430_get_current_source_location (int mypc, const char ** pfilename, const char ** pfunctionname, unsigned int * plineno) { static int initted = 0; if (current_bfd == NULL) { printf("no bfd\n"); return 0; } if (!initted) { int storage; asection * s; initted = 1; memset (& info, 0, sizeof (info)); INIT_DISASSEMBLE_INFO (info, stdout, op_printf); info.read_memory_func = sim_dis_read; info.arch = bfd_get_arch (current_bfd); info.mach = bfd_get_mach (current_bfd); if (info.mach == 0) info.arch = bfd_arch_msp430; disassemble_init_for_target (& info); storage = bfd_get_symtab_upper_bound (current_bfd); if (storage > 0) { symtab = (asymbol **) xmalloc (storage); symcount = bfd_canonicalize_symtab (current_bfd, symtab); symcount = remove_useless_symbols (symtab, symcount); qsort (symtab, symcount, sizeof (asymbol *), compare_symbols); } for (s = current_bfd->sections; s; s = s->next) { if (s->flags & SEC_CODE || code_section == 0) { code_section = s; code_base = bfd_section_lma (current_bfd, s); break; } } } *pfilename = *pfunctionname = NULL; *plineno = 0; bfd_find_nearest_line (current_bfd, code_section, symtab, mypc - code_base, pfilename, pfunctionname, plineno); return 1; }
void sim_disasm_one (void) { static int initted = 0; static asymbol **symtab = 0; static int symcount = 0; static int last_sym = -1; static struct disassemble_info info; int storage, sym, bestaddr; int min, max, i; static asection *code_section = 0; static bfd_vma code_base = 0; asection *s; int save_trace = trace; static const char *prev_filename = ""; static int prev_lineno = 0; const char *filename; const char *functionname; unsigned int lineno; int mypc = get_reg (pc); if (current_bfd == 0) return; trace = 0; if (!initted) { initted = 1; memset (&info, 0, sizeof (info)); INIT_DISASSEMBLE_INFO (info, stdout, op_printf); info.read_memory_func = sim_dis_read; info.arch = bfd_get_arch (current_bfd); info.mach = bfd_get_mach (current_bfd); if (info.mach == 0) { info.arch = bfd_arch_m32c; info.mach = default_machine; } disassemble_init_for_target (&info); storage = bfd_get_symtab_upper_bound (current_bfd); if (storage > 0) { symtab = (asymbol **) malloc (storage); symcount = bfd_canonicalize_symtab (current_bfd, symtab); symcount = remove_useless_symbols (symtab, symcount); qsort (symtab, symcount, sizeof (asymbol *), compare_symbols); } for (s = current_bfd->sections; s; s = s->next) { if (s->flags & SEC_CODE || code_section == 0) { code_section = s; code_base = bfd_section_lma (current_bfd, s); break; } } } filename = functionname = 0; lineno = 0; if (bfd_find_nearest_line (current_bfd, code_section, symtab, mypc - code_base, &filename, &functionname, &lineno)) { if (filename && functionname && lineno) { if (lineno != prev_lineno || strcmp (prev_filename, filename)) { char *the_line = load_file_and_line (filename, lineno); const char *slash = strrchr (filename, '/'); if (!slash) slash = filename; else slash++; printf ("========================================" "=====================================\n"); printf ("\033[37;41m %s:%d: \033[33;40m %s\033[K\033[0m\n", slash, lineno, the_line); } prev_lineno = lineno; prev_filename = filename; } } { min = -1; max = symcount; while (min < max - 1) { bfd_vma sa; sym = (min + max) / 2; sa = bfd_asymbol_value (symtab[sym]); /*printf("checking %4d %08x %s\n", sym, sa, bfd_asymbol_name (symtab[sym])); */ if (sa > mypc) max = sym; else if (sa < mypc) min = sym; else { min = sym; break; } } if (min != -1 && min != last_sym) { bestaddr = bfd_asymbol_value (symtab[min]); printf ("\033[43;30m%s", bfd_asymbol_name (symtab[min])); if (bestaddr != mypc) printf ("+%d", mypc - bestaddr); printf (":\t\t\t\033[0m\n"); last_sym = min; #if 0 if (trace == 1) if (strcmp (bfd_asymbol_name (symtab[min]), "abort") == 0 || strcmp (bfd_asymbol_name (symtab[min]), "exit") == 0) trace = 0; #endif } } opbuf[0] = 0; printf ("\033[33m%06x: ", mypc); max = print_insn_m32c (mypc, &info); for (i = 0; i < max; i++) printf ("%02x", mem_get_qi (mypc + i)); for (; i < 6; i++) printf (" "); printf ("%-16s ", opbuf); printf ("\033[0m\n"); trace = save_trace; }
vine_symbols_t * get_symbols_of_file(const char *filename) { asymbol** syms = NULL; long symcount = 0; long sorted_symcount = 0; asymbol** dynsyms = NULL; long dynsymcount = 0; asymbol* synthsyms = NULL; long synthcount = 0; long storage; vector<vine_symbol_t *> *ret = new vector<vine_symbol_t *>(); // asm_program_t *prog = new asm_program_t; // printf("initializing bfd\n\n"); bfd *abfd = initialize_bfd(filename); // printf("done\n\n"); // printf("initializing sections...\n\n"); // initialize_sections(abfd, prog); // printf("done\n\n"); asymbol *sym; if (bfd_get_file_flags (abfd) & HAS_SYMS) { storage = bfd_get_symtab_upper_bound (abfd); assert (storage >= 0); if (storage > 0) syms = (asymbol**) xmalloc(storage); symcount = bfd_canonicalize_symtab (abfd, syms); assert (symcount >= 0); sorted_symcount = remove_useless_symbols(syms, symcount); qsort(syms, sorted_symcount, sizeof(asymbol *), compare_symbols); for(int i= 0; i < sorted_symcount; i++){ vine_symbol_t *temp = new vine_symbol_t; temp->name = string(bfd_asymbol_name((syms[i]))); temp->addr = bfd_asymbol_value((syms[i])); sym = syms[i]; temp->is_function = (sym->flags & BSF_FUNCTION) != 0; temp->is_dynamic = 0; ret->push_back(temp); } } storage = bfd_get_dynamic_symtab_upper_bound (abfd); if (storage > 0) { dynsyms = (asymbol**) xmalloc(storage); dynsymcount = bfd_canonicalize_dynamic_symtab (abfd, dynsyms); } synthcount = bfd_get_synthetic_symtab (abfd, symcount, syms, dynsymcount, dynsyms, &synthsyms); if (synthcount < 0) synthcount = 0; for (int i=0; i<synthcount; i++) { vine_symbol_t *temp = new vine_symbol_t; temp->name = string(bfd_asymbol_name(&(synthsyms[i]))); temp->addr = bfd_asymbol_value(&(synthsyms[i])); temp->is_function = (synthsyms[i].flags & BSF_FUNCTION) != 0; temp->is_dynamic = 1; ret->push_back(temp); } if (synthsyms) free(synthsyms); if (dynsyms) free(dynsyms); if (syms) free(syms); bfd_close(abfd); return ret; }
map<address_t, asm_function_t *> identify_functions(const map<address_t, section_t *> sections, bfd *abfd) { map<address_t, asm_function_t *> funcs; //set<asm_function_t *> funcs; long storage_needed; asymbol **symtbl; long symcount, sorted_symcount; /* We could identify function boundries in stripped binaries by looking for the function prologue. TBD. */ if(!(bfd_get_file_flags(abfd) & HAS_SYMS)){ return get_stripped_binary_functions( abfd); //fatal("identify_functions", //"No support for stripped binaries (yet)"); } //assert(bfd_get_flavour(abfd) == bfd_target_elf_flavour); /* instead of handling only elf format binary, allow other types with a warning -- pongsin */ if (bfd_get_flavour(abfd) != bfd_target_elf_flavour) cerr << "Warning! The binary is not in ELF format. " << "Other formats haven't been thoroughly tested." << endl; storage_needed = bfd_get_symtab_upper_bound(abfd); if(storage_needed <= 0){ fatal("identify_functions", "symbol table damaged"); } symtbl = (asymbol **) xmalloc(storage_needed); symcount = bfd_canonicalize_symtab(abfd, symtbl); if(symcount <= 0) fatal("initialize_symtable", "symbol table damaged"); sorted_symcount = remove_useless_symbols(symtbl, symcount); qsort(symtbl, sorted_symcount, sizeof(asymbol *), compare_symbols); long i, place; asymbol *sym, *nextsym; for(i = 0; i < sorted_symcount; i++){ sym = symtbl[i]; /* if(sym->name != NULL){ printf("name: %s %u F:%x\n", sym->name, sym->flags & BSF_FUNCTION, sym->flags); } */ if(sym->flags & BSF_FUNCTION){ asm_function_t *f = new asm_function_t; f->start_addr = sym->section->vma + sym->value; f->name = sym->name; // memcpy(&(s->symbol), sym, sizeof(asymbol)); place = i; // FIXME: this still doesn't do the right thing for _init on ARM // also, this doesn't work for the last symbol while(place < sorted_symcount && (bfd_asymbol_value(sym) >= bfd_asymbol_value(symtbl[place])) ) place++; nextsym = symtbl[place]; // FIXME: We could approximate end_addr better, eg, by looking at where // the section ends. /* end addrress is approximation. the last valid address may be before this value */ f->end_addr = nextsym->value + nextsym->section->vma; //bfd_symbol_info(sym, &(s->info)); // end_addr so far is really the start_addr of the next function // subtract one if possible. if(f->end_addr != f->start_addr) f->end_addr--; if(funcs.find(f->start_addr) != funcs.end()){ asm_function_t *old = funcs[f->start_addr]; // Replace old functions with the new one if the new // one is bigger. if( (f->end_addr - f->start_addr) > (old->end_addr - old->start_addr)){ funcs[f->start_addr] = f; } } else { funcs[f->start_addr] = f; } } } free(symtbl); return funcs; }