WorkModeDisasm::WorkModeDisasm(DataSource *ds) : WorkMode(ds) { disassembler_ftype disassemble_fn; disassemble_info info; INIT_DISASSEMBLE_INFO(info, stdout, disNone); info.flavour = bfd_target_unknown_flavour; info.arch = bfd_arch_i386; //info.arch = bfd_arch_arm; info.mach = bfd_mach_i386_i386; //info.mach = bfd_mach_arm_4; info.endian = BFD_ENDIAN_LITTLE; //info.endian = BFD_ENDIAN_BIG; disassemble_fn = (int (*)(bfd_vma, disassemble_info*))getBfdFunction(); info.read_memory_func = disReadMemory; // Prepare the application data for the disasm DisasmAppData appData; appData.ds = _dataSource; appData.wm = this; info.application_data = &appData; int bytes = 0; int size = _dataSource->size(); // index opcodes while (bytes < size) { _linies.push_back(bytes); bytes += (*disassemble_fn) (0 + bytes, &info); } }
u1 *disassinstr(u1 *code) { s4 seqlen; s4 i; if (!disass_initialized) { INIT_DISASSEMBLE_INFO(info, NULL, disass_printf); /* setting the struct members must be done after INIT_DISASSEMBLE_INFO */ info.mach = bfd_mach_x86_64; info.read_memory_func = &disass_buffer_read_memory; disass_initialized = true; } printf("0x%016lx: ", (s8) code); disass_len = 0; seqlen = print_insn_i386((bfd_vma) code, &info); for (i = 0; i < seqlen; i++, code++) { printf("%02x ", *code); } for (; i < 10; i++) { printf(" "); } printf(" %s\n", disass_buf); return code; }
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; }
int j3::JeiModule::disassemble(unsigned int *addr) { if (!initialised) { INIT_DISASSEMBLE_INFO(info, stdout, fprintf); info.flavour= bfd_target_elf_flavour; info.arch= bfd_arch_i386; info.mach= bfd_mach_i386_i386; info.endian= BFD_ENDIAN_LITTLE; info.buffer_length= 65536; } info.buffer= (bfd_byte *)addr; info.buffer_vma= (bfd_vma)(long)addr; return print_insn_i386_att((bfd_vma)(long)addr, &info); }
int j3::JeiModule::disassemble(unsigned int *addr) { if (!initialised) { INIT_DISASSEMBLE_INFO(info, stdout, fprintf); info.flavour= bfd_target_elf_flavour; info.arch= bfd_arch_powerpc; info.mach= bfd_mach_ppc_750; // generic(ish) == PPC G3 info.endian= BFD_ENDIAN_BIG; info.buffer_length= 65536; } info.buffer= (bfd_byte *)addr; info.buffer_vma= (bfd_vma)(long)addr; return print_insn_big_powerpc((bfd_vma)(long)addr, &info); }
int WorkModeDisasm::disasmOp(int offset, struct ASM_INSN *op) { // TODO: do the info initalization, for multi arch disassembler_ftype disassemble_fn; disassemble_info info; INIT_DISASSEMBLE_INFO(info, stdout, disPrintfWrapper); info.flavour = bfd_target_unknown_flavour; info.arch = bfd_arch_i386; //info.arch = bfd_arch_arm; info.mach = bfd_mach_i386_i386; //info.mach = bfd_mach_arm_4; info.endian = BFD_ENDIAN_LITTLE; //info.endian = BFD_ENDIAN_BIG; disassemble_fn = (int (*)(bfd_vma, disassemble_info*))getBfdFunction(); info.read_memory_func = disReadMemory; // Prepare the application data for the disasm DisasmAppData appData; appData.ds = _dataSource; Value *val = _dataSource->getProperty("SectionAddress"); long int sectionAddress = 0; if (val) { sectionAddress = val->getInt(); } appData.secvma = sectionAddress; val = _dataSource->getProperty("SectionOffset"); long int sectionOffset = 0; if (val) { sectionOffset = val->getInt(); } appData.secoff = sectionOffset; appData.wm = this; info.application_data = &appData; info.print_address_func = print_address_func; int size = 0; if (op != NULL) { // TODO: here will be a mutual exclusion memset(&curr_insn, 0, sizeof(struct ASM_INSN)); size = (*disassemble_fn)(offset, &info); memcpy(op, &curr_insn, sizeof(struct ASM_INSN)); } // TODO: here will finish the mutual exclusion return size; }
u1 *disassinstr(u1 *code) { if (!disass_initialized) { INIT_DISASSEMBLE_INFO(info, NULL, disass_printf); /* setting the struct members must be done after INIT_DISASSEMBLE_INFO */ info.read_memory_func = &disass_buffer_read_memory; disass_initialized = true; } printf("0x%016lx: %08x ", (s8) code, *((s4 *) code)); print_insn_big_powerpc((bfd_vma) code, &info); printf("\n"); return code + 4; }
void target_disas(FILE *out, target_ulong code, target_ulong size, int flags) { target_ulong pc; int count; struct disassemble_info disasm_info; int (*print_insn)(bfd_vma pc, disassemble_info *info); INIT_DISASSEMBLE_INFO(disasm_info, out, fprintf); disasm_info.read_memory_func = target_read_memory; disasm_info.buffer_vma = code; disasm_info.buffer_length = size; #ifdef TARGET_WORDS_BIGENDIAN disasm_info.endian = BFD_ENDIAN_BIG; #else disasm_info.endian = BFD_ENDIAN_LITTLE; #endif print_insn = print_insn_arm; for (pc = code; size > 0; pc += count, size -= count) { fprintf(out, "0x" TARGET_FMT_lx ": ", pc); count = print_insn(pc, &disasm_info); fprintf(out, "\n"); if (count < 0) break; if (size < count) { fprintf(out, "Disassembler disagrees with translator over instruction " "decoding\n" "Please report this to [email protected]\n"); break; } } }
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; }
static void disassemble_to_buffer(TranslationBlock *tb, DisasBuffer *str) { unsigned long pc; struct disassemble_info disasm_info; int (*print_insn)(bfd_vma pc, disassemble_info *info); INIT_DISASSEMBLE_INFO(disasm_info, (FILE *)str, disas_fprintf); disasm_info.buffer = tb->tc_ptr; disasm_info.buffer_vma = (unsigned long)tb->tc_ptr; disasm_info.buffer_length = tb->size; #ifdef HOST_WORDS_BIGENDIAN disasm_info.endian = BFD_ENDIAN_BIG; #else disasm_info.endian = BFD_ENDIAN_LITTLE; #endif #if defined(__i386__) disasm_info.mach = bfd_mach_i386_i386; print_insn = print_insn_i386; #elif defined(__x86_64__) disasm_info.mach = bfd_mach_x86_64; print_insn = print_insn_i386; #elif defined(_ARCH_PPC) print_insn = print_insn_ppc; #elif defined(__alpha__) print_insn = print_insn_alpha; #elif defined(__sparc__) print_insn = print_insn_sparc; #if defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__) disasm_info.mach = bfd_mach_sparc_v9b; #endif #elif defined(__arm__) print_insn = print_insn_arm; #elif defined(__MIPSEB__) print_insn = print_insn_big_mips; #elif defined(__MIPSEL__) print_insn = print_insn_little_mips; #elif defined(__m68k__) print_insn = print_insn_m68k; #elif defined(__s390__) print_insn = print_insn_s390; #elif defined(__hppa__) print_insn = print_insn_hppa; #elif defined(__ia64__) print_insn = print_insn_ia64; #else fprintf(out, "0x%lx: Asm output not supported on this arch\n", (long) code); return; #endif int icount = 0; int count = 0; for (pc = (unsigned long)tb->tc_ptr; icount < tb->size && count < DISAS_BUFFER_SIZE; ) { int before = str->size; print_insn(pc, &disasm_info); int after = str->size; if (after == DISAS_BUFFER_SIZE) break; icount += after - before; str->buffer[after++] = '\n'; pc += after - before; count += after - before; } str->buffer[count] = 0; }
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; }
/** * Get length of instruction at the current PC. * * @param value the PC value. * * @return length of instruction at PC address. * * @ingroup RuntimeAPI */ int CBTF_GetInstrLength(uint64_t pcvalue) { //fprintf(stderr, "ENTERED CBTF_GetInstrLength\n"); #if defined(__linux) && (defined(__i386) || defined(__x86_64)) disassemble_info disinfo; disassembler_ftype disassemble_fn; initdisassembler(); //fprintf(stderr, "CBTF_GetInstrLength CALLS INIT_DISASSEMBLE_INFO\n"); INIT_DISASSEMBLE_INFO(disinfo, stdout, fprintf); disinfo.flavour = bfd_get_flavour (abfd); disinfo.arch = bfd_get_arch (abfd); //disinfo.mach = bfd_get_mach (abfd); disinfo.mach = bfd_mach_i386_i386; disinfo.octets_per_byte = bfd_octets_per_byte (abfd); if (bfd_big_endian (abfd)) disinfo.display_endian = disinfo.endian = BFD_ENDIAN_BIG; else if (bfd_little_endian (abfd)) disinfo.display_endian = disinfo.endian = BFD_ENDIAN_LITTLE; else disinfo.endian = BFD_ENDIAN_UNKNOWN; disinfo.buffer_length = 8; unsigned char* ptr = (unsigned char*) pcvalue; disinfo.buffer_vma = pcvalue; disinfo.buffer = ptr; disinfo.fprintf_func=(fprintf_ftype) dummyprint; //fprintf(stderr, "CBTF_GetInstrLength CALLS print_insn_i386 with addr %#lx\n",pcvalue); int insbytes = print_insn_i386(pcvalue, &disinfo); //fprintf(stderr,"CBTF_GetInstrLength returns length %d\n",insbytes); return insbytes; #elif defined(__linux) && defined(__powerpc__) /* FROM: http://www.ibm.com/developerworks/library/l-ppc/ All PowerPCs (including 64-bit implementations) use fixed-length 32-bit instructions */ return 0x4; #elif defined(__linux) && defined(__powerpc64__) /* FROM: http://www.ibm.com/developerworks/library/l-ppc/ All PowerPCs (including 64-bit implementations) use fixed-length 32-bit instructions */ return 0x4; #elif defined(__linux) && defined(__ia64) /* IA64 bundles are 128 bits. The caller must find the address of the bundle that contains the exception address and add this return value to it prior to updating the context PC. */ return 0x10; #elif defined(__linux) && defined(__aarch64__) /* FROM: Arm architecture wiki page Armv8 (and also including 64-bit implementations) use fixed-length 32-bit instructions */ return 0x4; #elif defined(__linux) && defined(__arm__) /* FROM: Arm architecture wiki page Armv7 (and also including 64-bit implementations) use fixed-length 32-bit instructions */ return 0x4; #else #error "Platform/OS Combination Unsupported!" #endif }
/* * 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 }