Beispiel #1
0
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);
	}
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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);
}
Beispiel #5
0
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);
  
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
        }
    }
}
Beispiel #9
0
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;
}
Beispiel #10
0
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;
}
Beispiel #11
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
}
Beispiel #13
0
/*
 * 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
}