// disassemble one instruction at laddr relative to memory, but at most memory+byteSize int disassembleForAtInSize(void *cpu, ulong laddr, void *memory, ulong byteSize) { gdblog_index = 0; // ignore the cpu disassemble_info* dis = (disassemble_info*) calloc(1, sizeof(disassemble_info)); init_disassemble_info ( dis, NULL, gdb_log_printf); dis->arch = bfd_arch_arm; dis->mach = bfd_mach_arm_unknown; // sets some fields in the structure dis to architecture specific values disassemble_init_for_target( dis ); dis->buffer_vma = 0; dis->buffer = memory; dis->buffer_length = byteSize; //prepend the address gdb_log_printf(NULL, "0x%p: ", laddr); //other possible functions are listed in opcodes/dissassemble.c unsigned int size = print_insn_little_arm((bfd_vma) laddr, dis); free(dis); // zero terminate the string gdb_log[gdblog_index+1] = 0; return size; }
struct disassemble_info* new_disasm_info( struct bfd* abfd ) { struct disassemble_info *di = (struct disassemble_info *) malloc( sizeof(struct disassemble_info) ); if ( !di ) error_exit( "failed to allocate disassemble_info" ); init_disassemble_info( di, stdout, (fprintf_ftype) fprintf ); di->flavour = bfd_get_flavour( abfd ); di->arch = bfd_get_arch( abfd ); di->mach = bfd_get_mach( abfd ); di->octets_per_byte = bfd_octets_per_byte( abfd ); di->disassembler_needs_relocs = FALSE; di->buffer = NULL; di->symtab = NULL; if ( bfd_big_endian( abfd ) ) di->display_endian = di->endian = BFD_ENDIAN_BIG; else if ( bfd_little_endian ( abfd ) ) di->display_endian = di->endian = BFD_ENDIAN_LITTLE; disassemble_init_for_target( di ); return di; }
static struct disassemble_info gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file) { struct disassemble_info di; init_disassemble_info (&di, file, fprintf_disasm); di.flavour = bfd_target_unknown_flavour; di.memory_error_func = dis_asm_memory_error; di.print_address_func = dis_asm_print_address; /* NOTE: cagney/2003-04-28: The original code, from the old Insight disassembler had a local optomization here. By default it would access the executable file, instead of the target memory (there was a growing list of exceptions though). Unfortunately, the heuristic was flawed. Commands like "disassemble &variable" didn't work as they relied on the access going to the target. Further, it has been supperseeded by trust-read-only-sections (although that should be superseeded by target_trust..._p()). */ di.read_memory_func = dis_asm_read_memory; di.arch = gdbarch_bfd_arch_info (gdbarch)->arch; di.mach = gdbarch_bfd_arch_info (gdbarch)->mach; di.endian = gdbarch_byte_order (gdbarch); di.endian_code = gdbarch_byte_order_for_code (gdbarch); di.application_data = gdbarch; disassemble_init_for_target (&di); return di; }
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; }
/* Initialize disassembler (libopcodes/libbfd) for given file. * * If the the function returns data with data.bfd_file = NULL, * then the function failed. */ static struct disasm_data disasm_init(const char *filename) { asection *section; struct disasm_data data; static bool initialized = false; if (!initialized) { bfd_init(); initialized = true; } data.bfd_file = bfd_openr(filename, NULL); if (data.bfd_file == NULL) { VERB1 log_bfd_error("bfd_openr", filename); return data; } if (!bfd_check_format(data.bfd_file, bfd_object)) { VERB1 log_bfd_error("bfd_check_format", filename); goto ret_fail; } section = bfd_get_section_by_name(data.bfd_file, ".text"); if (section == NULL) { VERB1 log_bfd_error("bfd_get_section_by_name", filename); goto ret_fail; } data.disassemble = disassembler(data.bfd_file); if (data.disassemble == NULL) { VERB1 log("Unable to find disassembler"); goto ret_fail; } init_disassemble_info(&data.info, NULL, buffer_printf); data.info.arch = bfd_get_arch(data.bfd_file); data.info.mach = bfd_get_mach(data.bfd_file); data.info.buffer_vma = section->vma; data.info.buffer_length = section->size; data.info.section = section; /*TODO: memory error func*/ bfd_malloc_and_get_section(data.bfd_file, section, &data.info.buffer); disassemble_init_for_target(&data.info); return data; ret_fail: bfd_close(data.bfd_file); data.bfd_file = NULL; return data; }
struct disassemble_info gdb_disassemble_info (unsigned char *mem_buf, char *output_buf) { struct disassemble_info di; init_disassemble_info (&di, output_buf, sprintf_disasm); di.buffer = mem_buf; di.buffer_length = UINT_MAX; di.print_address_func = dis_asm_sprint_address; di.flavour = bfd_target_unknown_flavour; di.arch = bfd_arch_m68k; di.mach = bfd_mach_m68000; di.endian = BFD_ENDIAN_BIG; disassemble_init_for_target (&di); return di; }
static void init_disasm_info(bfd *abfd, struct disassemble_info *disasm_info) { init_disassemble_info (disasm_info, stdout, (fprintf_ftype) fprintf); disasm_info->flavour = bfd_get_flavour (abfd); disasm_info->arch = bfd_get_arch (abfd); disasm_info->mach = bfd_get_mach (abfd); disasm_info->octets_per_byte = bfd_octets_per_byte (abfd); disasm_info->disassembler_needs_relocs = FALSE; if (bfd_big_endian (abfd)) disasm_info->display_endian = disasm_info->endian = BFD_ENDIAN_BIG; else if (bfd_little_endian (abfd)) disasm_info->display_endian = disasm_info->endian = BFD_ENDIAN_LITTLE; disassemble_init_for_target(disasm_info); disasm_info->read_memory_func = my_read_memory; }
void arch_bfdDisasm(pid_t pid, uint8_t * mem, size_t size, char *instr) { while (pthread_mutex_lock(&arch_bfd_mutex)) ; bfd_init(); char fname[PATH_MAX]; snprintf(fname, sizeof(fname), "/proc/%d/exe", pid); bfd *bfdh = bfd_openr(fname, NULL); if (bfdh == NULL) { LOGMSG(l_WARN, "bfd_openr('/proc/%d/exe') failed", pid); goto out; } if (!bfd_check_format(bfdh, bfd_object)) { LOGMSG(l_WARN, "bfd_check_format() failed"); goto out; } disassembler_ftype disassemble = disassembler(bfdh); if (disassemble == NULL) { LOGMSG(l_WARN, "disassembler() failed"); goto out; } struct disassemble_info info; init_disassemble_info(&info, instr, arch_bfdFPrintF); info.arch = bfd_get_arch(bfdh); info.mach = bfd_get_mach(bfdh); info.buffer = mem; info.buffer_length = size; info.section = NULL; info.endian = bfd_little_endian(bfdh) ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG; disassemble_init_for_target(&info); strcpy(instr, ""); if (disassemble(0, &info) <= 0) { snprintf(instr, _HF_INSTR_SZ, "[DIS-ASM_FAILURE]"); } out: bfdh ? bfd_close_all_done(bfdh) : 0; while (pthread_mutex_unlock(&arch_bfd_mutex)) ; return; }
int main () { unsigned int data[3] = {0xE3A01080, 0xE2810001, 0xE1A01001}; bfd_byte* buf = (bfd_byte*) &data[0]; disassemble_info* c = (struct disassemble_info*) calloc(1, sizeof(disassemble_info)); // void init_disassemble_info (struct disassemble_info *dinfo, void *stream, fprintf_ftype fprintf_func) init_disassemble_info ( c, stdout, my_fprintf); //c->application_data //c->memory_error_func // set architecture c->arch = bfd_arch_arm; // set the specific machine: unknown allows all instructions in the libraries database c->mach = bfd_mach_arm_unknown; // should set the disassembler field of c to the right function disassemble_init_for_target( c ); // given a bfd, the disassembler can find the arch by itself. //disassemble = disassembler( c ); c->buffer_vma = 0; c->buffer = buf; c->buffer_length = 12; // while-loop for calling single instruction decoding: unsigned int count = 0; size_t pos = 0; size_t length = c->buffer_length; size_t max_pos = c->buffer_vma+length; while(pos < max_pos) { //disassembler-function: print_insn_big_arm //other possible functions are listed in opcodes/dissassemble.c unsigned int size = print_insn_little_arm((bfd_vma) pos, c); pos += size; count++; fprintf(stdout, "\n"); } return 0; }
static void get_asm_insns(uint8_t *image, size_t len, unsigned long base, int opcodes) { int count, i, pc = 0; char tpath[256]; struct disassemble_info info; disassembler_ftype disassemble; bfd *bfdf; memset(tpath, 0, sizeof(tpath)); get_exec_path(tpath, sizeof(tpath)); bfdf = bfd_openr(tpath, NULL); assert(bfdf); assert(bfd_check_format(bfdf, bfd_object)); init_disassemble_info(&info, stdout, (fprintf_ftype) fprintf); info.arch = bfd_get_arch(bfdf); info.mach = bfd_get_mach(bfdf); info.buffer = image; info.buffer_length = len; disassemble_init_for_target(&info); disassemble = disassembler(bfdf); assert(disassemble); do { printf("%4x:\t", pc); count = disassemble(pc, &info); if (opcodes) { printf("\n\t"); for (i = 0; i < count; ++i) printf("%02x ", (uint8_t) image[pc + i]); } printf("\n"); pc += count; } while(count > 0 && pc < len); bfd_close(bfdf); }
void init_disasm_info(bfd *abfd, struct disassemble_info *disasm_info) { init_disassemble_info (disasm_info, stdout, (fprintf_ftype) fprintf); disasm_info->flavour = bfd_get_flavour (abfd); disasm_info->arch = bfd_get_arch (abfd); disasm_info->mach = bfd_get_mach (abfd); //disasm_info->disassembler_options = disassembler_options; disasm_info->octets_per_byte = bfd_octets_per_byte (abfd); //disasm_info->skip_zeroes = DEFAULT_SKIP_ZEROES; //disasm_info->skip_zeroes_at_end = DEFAULT_SKIP_ZEROES_AT_END; disasm_info->disassembler_needs_relocs = FALSE; if (bfd_big_endian (abfd)) disasm_info->display_endian = disasm_info->endian = BFD_ENDIAN_BIG; else if (bfd_little_endian (abfd)) disasm_info->display_endian = disasm_info->endian = BFD_ENDIAN_LITTLE; disassemble_init_for_target(disasm_info); disasm_info->read_memory_func = my_read_memory; }
static void gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch, struct disassemble_info *di, const gdb_byte *insn, int max_len, CORE_ADDR addr) { init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf); /* init_disassemble_info installs buffer_read_memory, etc. so we don't need to do that here. The cast is necessary until disassemble_info is const-ified. */ di->buffer = (gdb_byte *) insn; di->buffer_length = max_len; di->buffer_vma = addr; di->arch = gdbarch_bfd_arch_info (gdbarch)->arch; di->mach = gdbarch_bfd_arch_info (gdbarch)->mach; di->endian = gdbarch_byte_order (gdbarch); di->endian_code = gdbarch_byte_order_for_code (gdbarch); disassemble_init_for_target (di); }
bool disas_libopcode(FILE *fp_out, const char *machine, bool big_endian, uint64_t addr, void *buf, size_t len) { bfd *abfd = NULL; struct disassemble_info inf; const bfd_arch_info_type *arch_inf = bfd_scan_arch (machine); disassembler_ftype disas_fn; int size, pos; if (!arch_inf) { return false; } abfd = bfd_openr("/dev/null", "binary"); abfd->arch_info = arch_inf; init_disassemble_info (&inf, fp_out, (fprintf_ftype) fprintf); inf.buffer = buf; inf.buffer_vma = addr; inf.buffer_length = len; inf.endian = big_endian ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE; inf.print_address_func = print_address; disassemble_init_for_target(&inf); disas_fn = disassembler (abfd); pos = 0; do { fprintf(fp_out, "%" PRIx64 "\t", addr + pos); size = disas_fn(addr + pos, &inf); pos += size; fputc('\n', fp_out); } while (pos < len); bfd_close(abfd); return true; }
/* * Implementation */ void jit_init_debug(const char *progname) { #if DISASSEMBLER bfd_init(); if (progname) disasm_bfd = bfd_openr(progname, NULL); if (disasm_bfd == NULL) { #if defined(__linux__) disasm_bfd = bfd_openr("/proc/self/exe", NULL); if (disasm_bfd == NULL) #endif return; } bfd_check_format(disasm_bfd, bfd_object); bfd_check_format(disasm_bfd, bfd_archive); disasm_print = disassembler(disasm_bfd); assert(disasm_print); INIT_DISASSEMBLE_INFO(disasm_info, disasm_stream, fprintf); # if defined(__i386__) || defined(__x86_64__) disasm_info.arch = bfd_arch_i386; # if defined(__x86_64__) # if __WORDSIZE == 32 disasm_info.mach = bfd_mach_x64_32; # else disasm_info.mach = bfd_mach_x86_64; # endif # else disasm_info.mach = bfd_mach_i386_i386; # endif # endif # if defined(__powerpc__) disasm_info.arch = bfd_arch_powerpc; disasm_info.mach = bfd_mach_ppc64; # if HAVE_DISASSEMBLE_INIT_FOR_TARGET disassemble_init_for_target(&disasm_info); # elif HAVE_DISASSEMBLE_INIT_POWERPC disassemble_init_powerpc(&disasm_info); # endif # if defined(__powerpc64__) disasm_info.disassembler_options = "64"; # endif # if HAVE_DISASSEMBLE_INIT_FOR_TARGET disassemble_init_for_target(&disasm_info); # elif HAVE_DISASSEMBLE_INIT_POWERPC disassemble_init_powerpc(&disasm_info); # endif # endif # if defined(__sparc__) disasm_info.endian = disasm_info.display_endian = BFD_ENDIAN_BIG; # endif # if defined(__s390__) || defined(__s390x__) disasm_info.arch = bfd_arch_s390; # if __WORDSIZE == 32 disasm_info.mach = bfd_mach_s390_31; # else disasm_info.mach = bfd_mach_s390_64; # endif disasm_info.endian = disasm_info.display_endian = BFD_ENDIAN_BIG; disasm_info.disassembler_options = "zarch"; # endif # if defined(__alpha__) disasm_info.arch = bfd_arch_alpha; disasm_info.mach = bfd_mach_alpha_ev6; # endif disasm_info.print_address_func = disasm_print_address; if (bfd_get_file_flags(disasm_bfd) & HAS_SYMS) { asymbol **in; asymbol **out; asymbol *symbol; long offset; long sym_count; long dyn_count; long sym_storage; long dyn_storage; if ((sym_storage = bfd_get_symtab_upper_bound(disasm_bfd)) >= 0) { if (bfd_get_file_flags(disasm_bfd) & DYNAMIC) { dyn_storage = bfd_get_dynamic_symtab_upper_bound(disasm_bfd); # if defined(__alpha__) /* XXX */ if (dyn_storage < 0) dyn_storage = 0; # else assert(dyn_storage >= 0); # endif } else dyn_storage = 0; jit_alloc((jit_pointer_t *)&disasm_symbols, (sym_storage + dyn_storage) * sizeof(asymbol *)); sym_count = bfd_canonicalize_symtab(disasm_bfd, disasm_symbols); assert(sym_count >= 0); if (dyn_storage) { dyn_count = bfd_canonicalize_dynamic_symtab(disasm_bfd, disasm_symbols + sym_count); assert(dyn_count >= 0); } else dyn_count = 0; disasm_num_symbols = sym_count + dyn_count; disasm_num_synthetic = bfd_get_synthetic_symtab(disasm_bfd, sym_count, disasm_symbols, dyn_count, disasm_symbols + sym_count, &disasm_synthetic); if (disasm_num_synthetic > 0) { jit_realloc((jit_pointer_t *)&disasm_symbols, (sym_storage + dyn_storage) * sizeof(asymbol *), (sym_storage + dyn_storage + disasm_num_synthetic) * sizeof(asymbol *)); for (offset = 0; offset < disasm_num_synthetic; offset++) disasm_symbols[disasm_num_symbols++] = disasm_synthetic + offset; } /* remove symbols not useful for disassemble */ in = out = disasm_symbols; for (offset = 0; offset < disasm_num_symbols; offset++) { symbol = *in++; if (symbol->name && symbol->name[0] != '\0' && !(symbol->flags & (BSF_DEBUGGING | BSF_SECTION_SYM)) && !bfd_is_und_section(symbol->section) && !bfd_is_com_section(symbol->section)) *out++ = symbol; } disasm_num_symbols = out - disasm_symbols; qsort(disasm_symbols, disasm_num_symbols, sizeof(asymbol *), disasm_compare_symbols); } } #endif }
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; }
uv_err_t UVDBfdInstructionIterator::init() { bfd *a_bfd = NULL; uv_assert_ret(m_obj); uv_assert_ret(m_obj->m_bfd); a_bfd = m_obj->m_bfd; //Needs to be an object or an archive if( !bfd_check_format(a_bfd, bfd_object) && !bfd_check_format(a_bfd, bfd_archive) ) { //bfd_close(a_bfd); printf("bad file\n"); return UV_DEBUG(UV_ERR_GENERAL); } printf("BFD open and is object\n"); /* Standard disassemblers. Disassemble one instruction at the given target address. Return number of octets processed. typedef int (*disassembler_ftype) (bfd_vma, disassemble_info *); */ g_disassembler_function = disassembler(a_bfd); if( !g_disassembler_function ) { printf("failed \n"); return UV_DEBUG(UV_ERR_GENERAL); } memset(&m_disasm_info, 0, sizeof(m_disasm_info)); init_disassemble_info(&m_disasm_info, stdout, (fprintf_ftype) fprintf); m_disasm_info.flavour = bfd_get_flavour (a_bfd); m_disasm_info.arch = bfd_get_arch (a_bfd); m_disasm_info.mach = bfd_get_mach (a_bfd); m_disasm_info.disassembler_options = NULL; m_disasm_info.octets_per_byte = bfd_octets_per_byte(a_bfd); m_disasm_info.skip_zeroes = 0; m_disasm_info.skip_zeroes_at_end = 0; m_disasm_info.disassembler_needs_relocs = FALSE; m_disasm_info.display_endian = m_disasm_info.endian = BFD_ENDIAN_BIG; //Don't care m_disasm_info.application_data = NULL; m_disasm_info.print_address_func = objdump_print_address; m_disasm_info.symbol_at_address_func = objdump_symbol_at_address; disassemble_init_for_target(&m_disasm_info); //Wonder if these can be NULL? m_disasm_info.symtab = NULL; m_disasm_info.symtab_size = 0; /* This won't work since we want to step on our own accord bfd_map_over_sections(a_bfd, disassemble_section, &disasm_info); */ #if 0 void bfd_map_over_sections (bfd *abfd, void (*operation) (bfd *, asection *, void *), void *user_storage) { asection *sect; unsigned int i = 0; for (sect = abfd->sections; sect != NULL; i++, sect = sect->next) (*operation) (abfd, sect, user_storage); if (i != abfd->section_count) /* Debugging */ abort (); }
struct sr_disasm_state * sr_disasm_init(const char *file_name, char **error_message) { #if HAVE_LIBOPCODES struct sr_disasm_state *state = sr_malloc(sizeof(struct sr_disasm_state)); state->bfd_file = bfd_openr(file_name, NULL); if (!state->bfd_file) { *error_message = sr_asprintf("Failed to open file %s: %s", file_name, bfd_errmsg(bfd_get_error())); free(state); return NULL; } if (!bfd_check_format(state->bfd_file, bfd_object)) { *error_message = sr_asprintf("Invalid file format of %s: %s", file_name, bfd_errmsg(bfd_get_error())); bfd_close(state->bfd_file); free(state); return NULL; } asection *section = bfd_get_section_by_name(state->bfd_file, ".text"); if (!section) { *error_message = sr_asprintf( "Failed to find .text section in %s: %s", file_name, bfd_errmsg(bfd_get_error())); bfd_close(state->bfd_file); free(state); return NULL; } state->disassembler = disassembler(state->bfd_file); if (!state->disassembler) { *error_message = sr_asprintf( "Unable to find disassembler for %s", file_name); bfd_close(state->bfd_file); free(state); return NULL; } init_disassemble_info(&state->info, NULL, buffer_printf); state->info.arch = bfd_get_arch(state->bfd_file); state->info.mach = bfd_get_mach(state->bfd_file); state->info.buffer_vma = section->vma; state->info.buffer_length = section->size; state->info.section = section; /* TODO: memory error func */ bfd_malloc_and_get_section(state->bfd_file, section, &state->info.buffer); disassemble_init_for_target(&state->info); return state; #else // HAVE_LIBOPCODES *error_message = sr_asprintf("satyr compiled without libopcodes"); return NULL; #endif // HAVE_LIBOPCODES }
SIM_RC sim_create_inferior (SIM_DESC sd ATTRIBUTE_UNUSED, struct bfd * abfd, char * const *argv, char * const *env) { int argvlen = 0; int mach; char **arg; init (); if (abfd != NULL) { ARMul_SetPC (state, bfd_get_start_address (abfd)); mach = bfd_get_mach (abfd); } else { ARMul_SetPC (state, 0); /* ??? */ mach = 0; } #ifdef MODET if (abfd != NULL && (bfd_get_start_address (abfd) & 1)) SETT; #endif switch (mach) { default: (*sim_callback->printf_filtered) (sim_callback, "Unknown machine type '%d'; please update sim_create_inferior.\n", mach); /* fall through */ case 0: /* We wouldn't set the machine type with earlier toolchains, so we explicitly select a processor capable of supporting all ARMs in 32bit mode. */ ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_v6_Prop); break; case bfd_mach_arm_XScale: ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_v6_Prop); break; case bfd_mach_arm_iWMMXt2: case bfd_mach_arm_iWMMXt: { extern int SWI_vector_installed; ARMword i; if (! SWI_vector_installed) { /* Intialise the hardware vectors to zero. */ if (! SWI_vector_installed) for (i = ARMul_ResetV; i <= ARMFIQV; i += 4) ARMul_WriteWord (state, i, 0); /* ARM_WriteWord will have detected the write to the SWI vector, but we want SWI_vector_installed to remain at 0 so that thumb mode breakpoints will work. */ SWI_vector_installed = 0; } } ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_iWMMXt_Prop); break; case bfd_mach_arm_ep9312: ARMul_SelectProcessor (state, ARM_v4_Prop | ARM_ep9312_Prop); break; case bfd_mach_arm_5: if (bfd_family_coff (abfd)) { /* This is a special case in order to support COFF based ARM toolchains. The COFF header does not have enough room to store all the different kinds of ARM cpu, so the XScale, v5T and v5TE architectures all default to v5. (See coff_set_flags() in bdf/coffcode.h). So if we see a v5 machine type here, we assume it could be any of the above architectures and so select the most feature-full. */ ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop); break; } /* Otherwise drop through. */ case bfd_mach_arm_5T: ARMul_SelectProcessor (state, ARM_v5_Prop); break; case bfd_mach_arm_5TE: ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop); break; case bfd_mach_arm_4: case bfd_mach_arm_4T: ARMul_SelectProcessor (state, ARM_v4_Prop); break; case bfd_mach_arm_3: case bfd_mach_arm_3M: ARMul_SelectProcessor (state, ARM_Lock_Prop); break; case bfd_mach_arm_2: case bfd_mach_arm_2a: ARMul_SelectProcessor (state, ARM_Fix26_Prop); break; } memset (& info, 0, sizeof (info)); INIT_DISASSEMBLE_INFO (info, stdout, op_printf); info.read_memory_func = sim_dis_read; info.arch = bfd_get_arch (abfd); info.mach = bfd_get_mach (abfd); info.endian_code = BFD_ENDIAN_LITTLE; if (info.mach == 0) info.arch = bfd_arch_arm; disassemble_init_for_target (& info); if (argv != NULL) { /* Set up the command line by laboriously stringing together the environment carefully picked apart by our caller. */ /* Free any old stuff. */ if (state->CommandLine != NULL) { free (state->CommandLine); state->CommandLine = NULL; } /* See how much we need. */ for (arg = argv; *arg != NULL; arg++) argvlen += strlen (*arg) + 1; /* Allocate it. */ state->CommandLine = malloc (argvlen + 1); if (state->CommandLine != NULL) { arg = argv; state->CommandLine[0] = '\0'; for (arg = argv; *arg != NULL; arg++) { strcat (state->CommandLine, *arg); strcat (state->CommandLine, " "); } } } if (env != NULL) { /* Now see if there's a MEMSIZE spec in the environment. */ while (*env) { if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0) { char *end_of_num; /* Set up memory limit. */ state->MemSize = strtoul (*env + sizeof ("MEMSIZE=") - 1, &end_of_num, 0); } env++; } } return SIM_RC_OK; }