Beispiel #1
0
static bfd_boolean
MY(write_object_contents)(bfd *abfd)
{
  struct external_exec exec_bytes;
  struct internal_exec *execp = exec_hdr(abfd);

  /* Magic number, maestro, please!  */
  switch (bfd_get_arch(abfd))
    {
    case bfd_arch_m68k:
      switch (bfd_get_mach (abfd))
	{
	case bfd_mach_m68010:
	  N_SET_MACHTYPE (*execp, M_68010);
	  break;
	default:
	case bfd_mach_m68020:
	  N_SET_MACHTYPE (*execp, M_68020);
	  break;
	}
      break;
    case bfd_arch_sparc:
      N_SET_MACHTYPE (*execp, M_SPARC);
      break;
    case bfd_arch_i386:
      N_SET_MACHTYPE (*execp, M_386);
      break;
    case bfd_arch_a29k:
      N_SET_MACHTYPE (*execp, M_29K);
      break;
    case bfd_arch_mips:
      switch (bfd_get_mach (abfd))
	{
	case bfd_mach_mips4000:
	case bfd_mach_mips6000:
	  N_SET_MACHTYPE (*execp, M_MIPS2);
	  break;
	default:
	  N_SET_MACHTYPE (*execp, M_MIPS1);
	  break;
	}
      break;
    default:
      N_SET_MACHTYPE (*execp, M_UNKNOWN);
    }

  MY (choose_reloc_size) (abfd);

  WRITE_HEADERS (abfd, execp);

  return TRUE;
}
Beispiel #2
0
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 void
elf32_sparc_final_write_processing (bfd *abfd,
				    bfd_boolean linker ATTRIBUTE_UNUSED)
{
  switch (bfd_get_mach (abfd))
    {
    case bfd_mach_sparc :
    case bfd_mach_sparc_sparclet :
    case bfd_mach_sparc_sparclite :
      break; /* nothing to do */
    case bfd_mach_sparc_v8plus :
      elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS;
      elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK;
      elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS;
      break;
    case bfd_mach_sparc_v8plusa :
      elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS;
      elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK;
      elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS | EF_SPARC_SUN_US1;
      break;
    case bfd_mach_sparc_v8plusb :
      elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS;
      elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK;
      elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS | EF_SPARC_SUN_US1
				       | EF_SPARC_SUN_US3;
      break;
    case bfd_mach_sparc_sparclite_le :
      elf_elfheader (abfd)->e_flags |= EF_SPARC_LEDATA;
      break;
    default :
      abort ();
      break;
    }
}
Beispiel #4
0
SIM_DESC
sim_open (SIM_OPEN_KIND kind,
	  struct host_callback_struct *callback,
	  struct bfd *abfd, char **argv)
{
  setbuf (stdout, 0);
  if (open)
    fprintf (stderr, "m32c minisim: re-opened sim\n");

  /* The 'run' interface doesn't use this function, so we don't care
     about KIND; it's always SIM_OPEN_DEBUG.  */
  if (kind != SIM_OPEN_DEBUG)
    fprintf (stderr, "m32c minisim: sim_open KIND != SIM_OPEN_DEBUG: %d\n",
	     kind);

  if (abfd)
    m32c_set_mach (bfd_get_mach (abfd));

  /* We can use ABFD, if non-NULL to select the appropriate
     architecture.  But we only support the r8c right now.  */

  set_callbacks (callback);

  /* We don't expect any command-line arguments.  */

  init_mem ();
  init_regs ();

  open = 1;
  return &the_minisim;
}
Beispiel #5
0
bfd_vma
bfd_h8300_pad_address (bfd *abfd, bfd_vma address)
{
  /* Cope with bfd_vma's larger than 32 bits.  */
  address &= 0xffffffffu;

  switch (bfd_get_mach (abfd))
    {
    case bfd_mach_h8300:
    case bfd_mach_h8300hn:
    case bfd_mach_h8300sn:
    case bfd_mach_h8300sxn:
      /* Sign extend a 16-bit address.  */
      if (address >= 0x8000)
	return address | 0xffff0000u;
      return address;

    case bfd_mach_h8300h:
      /* Sign extend a 24-bit address.  */
      if (address >= 0x800000)
	return address | 0xff000000u;
      return address;

    case bfd_mach_h8300s:
    case bfd_mach_h8300sx:
      return address;

    default:
      abort ();
    }
}
Beispiel #6
0
static bfd_boolean
MY(write_object_contents) (bfd *abfd)
{
  struct external_exec exec_bytes;
  struct internal_exec *execp = exec_hdr (abfd);

  obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;

  BFD_ASSERT (bfd_get_arch (abfd) == bfd_arch_ns32k);
  switch (bfd_get_mach (abfd))
    {
    case 32032:
      N_SET_MACHTYPE (execp, M_NS32032);
      break;
    case 32532:
    default:
      N_SET_MACHTYPE (execp, M_NS32532);
      break;
    }
  N_SET_FLAGS (execp, aout_backend_info (abfd)->exec_hdr_flags);

  WRITE_HEADERS (abfd, execp);

  return TRUE;
}
Beispiel #7
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 #8
0
static bfd_boolean
elf32_sparc_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
{
  bfd *obfd = info->output_bfd;
  bfd_boolean error;
  unsigned long ibfd_mach;
  /* FIXME: This should not be static.  */
  static unsigned long previous_ibfd_e_flags = (unsigned long) -1;

  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
    return TRUE;

  error = FALSE;

  ibfd_mach = bfd_get_mach (ibfd);
  if (bfd_mach_sparc_64bit_p (ibfd_mach))
    {
      error = TRUE;
      _bfd_error_handler
	(_("%B: compiled for a 64 bit system and target is 32 bit"), ibfd);
    }
  else if ((ibfd->flags & DYNAMIC) == 0)
    {
      if (bfd_get_mach (obfd) < ibfd_mach)
	bfd_set_arch_mach (obfd, bfd_arch_sparc, ibfd_mach);
    }

  if (((elf_elfheader (ibfd)->e_flags & EF_SPARC_LEDATA)
       != previous_ibfd_e_flags)
      && previous_ibfd_e_flags != (unsigned long) -1)
    {
      _bfd_error_handler
	(_("%B: linking little endian files with big endian files"), ibfd);
      error = TRUE;
    }
  previous_ibfd_e_flags = elf_elfheader (ibfd)->e_flags & EF_SPARC_LEDATA;

  if (error)
    {
      bfd_set_error (bfd_error_bad_value);
      return FALSE;
    }

  return _bfd_sparc_elf_merge_private_bfd_data (ibfd, info);
}
/* 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;
}
Beispiel #10
0
static struct bfd_hash_entry *
funcvec_hash_newfunc (struct bfd_hash_entry *entry,
		      struct bfd_hash_table *gen_table,
		      const char *string)
{
  struct funcvec_hash_entry *ret;
  struct funcvec_hash_table *table;

  ret = (struct funcvec_hash_entry *) entry;
  table = (struct funcvec_hash_table *) gen_table;

  /* Allocate the structure if it has not already been allocated by a
     subclass.  */
  if (ret == NULL)
    ret = ((struct funcvec_hash_entry *)
	   bfd_hash_allocate(gen_table,
			     ((unsigned int)
                              sizeof(struct funcvec_hash_entry))));
  if (ret == NULL)
    return NULL;

  /* Call the allocation method of the superclass: */
  ret = ((struct funcvec_hash_entry *)
	 bfd_hash_newfunc((struct bfd_hash_entry *)ret, gen_table,
                          string));

  if (ret == NULL)
    return NULL;

  /* Note where this entry will reside in the function vector table.  */
  ret->offset = table->offset;

  /* Bump the offset at which we store entries in the function
     vector.  We'd like to bump up the size of the vectors section,
     but it's not easily available here.  */
 switch (bfd_get_mach (table->abfd))
   {
   case bfd_mach_h8300:
   case bfd_mach_h8300hn:
   case bfd_mach_h8300sn:
     table->offset += 2;
     break;
   case bfd_mach_h8300h:
   case bfd_mach_h8300s:
     table->offset += 4;
     break;
   default:
     return NULL;
   }

  /* Everything went OK.  */
  return (struct bfd_hash_entry *) ret;
}
Beispiel #11
0
bfd_boolean
bfd_arm_merge_machines (bfd *ibfd, bfd *obfd)
{
  unsigned int in  = bfd_get_mach (ibfd);
  unsigned int out = bfd_get_mach (obfd);

  /* If the output architecture is unknown, we now have a value to set.  */
  if (out == bfd_mach_arm_unknown)
    bfd_set_arch_mach (obfd, bfd_arch_arm, in);

  /* If the input architecture is unknown,
     then so must be the output architecture.  */
  else if (in == bfd_mach_arm_unknown)
    /* FIXME: We ought to have some way to
       override this on the command line.  */
    bfd_set_arch_mach (obfd, bfd_arch_arm, bfd_mach_arm_unknown);

  /* If they are the same then nothing needs to be done.  */
  else if (out == in)
    ;

  /* Otherwise the general principle that a earlier architecture can be
     linked with a later architecture to produce a binary that will execute
     on the later architecture.

     We fail however if we attempt to link a Cirrus EP9312 binary with an
     Intel XScale binary, since these architecture have co-processors which
     will not both be present on the same physical hardware.  */
  else if (in == bfd_mach_arm_ep9312
	   && (out == bfd_mach_arm_XScale
	       || out == bfd_mach_arm_iWMMXt
	       || out == bfd_mach_arm_iWMMXt2))
    {
      _bfd_error_handler (_("\
error: %B is compiled for the EP9312, whereas %B is compiled for XScale"),
			  ibfd, obfd);
      bfd_set_error (bfd_error_wrong_format);
      return FALSE;
    }
Beispiel #12
0
static unsigned long
default_gcore_mach (void)
{
#if 1	/* See if this even matters...  */
  return 0;
#else

  const struct bfd_arch_info *bfdarch = gdbarch_bfd_arch_info (current_gdbarch);

  if (bfdarch != NULL)
    return bfdarch->mach;
  if (exec_bfd == NULL)
    error (_("Can't find default bfd machine type (need execfile)."));

  return bfd_get_mach (exec_bfd);
#endif /* 1 */
}
Beispiel #13
0
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;
}
Beispiel #14
0
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;
}
Beispiel #15
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);
}
Beispiel #16
0
/* Write an object file in LynxOS format.
 * Section contents have already been written.  We write the
 * file header, symbols, and relocation.  */
static bfd_boolean
NAME(aout,sparclynx_write_object_contents)(bfd *abfd)
{
  struct external_exec exec_bytes;
  struct internal_exec *execp = exec_hdr(abfd);

  /* Magic number, maestro, please!  */
  switch (bfd_get_arch(abfd))
    {
    case bfd_arch_m68k:
      switch (bfd_get_mach(abfd))
	{
	case bfd_mach_m68010:
	  N_SET_MACHTYPE (*execp, M_68010);
	  break;
	default:
	case bfd_mach_m68020:
	  N_SET_MACHTYPE (*execp, M_68020);
	  break;
	}
      break;
    case bfd_arch_sparc:
      N_SET_MACHTYPE (*execp, M_SPARC);
      break;
    case bfd_arch_i386:
      N_SET_MACHTYPE (*execp, M_386);
      break;
    case bfd_arch_a29k:
      N_SET_MACHTYPE (*execp, M_29K);
      break;
    default:
      N_SET_MACHTYPE (*execp, M_UNKNOWN);
    }

  choose_reloc_size (abfd);

  N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags);

  WRITE_HEADERS (abfd, execp);

  return TRUE;
}
Beispiel #17
0
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;
}
Beispiel #18
0
// Define BFD-related global variables.
static int define_bfd_vars(void)
{
	bfd * bfd;
	bfd_boolean r;
	int len;
#define MAX_PATHLENGTH 2048
	char mypath[MAX_PATHLENGTH];
     
	len = readlink("/proc/self/exe", mypath, sizeof(mypath));
     
	if (len < 0) {
		fprintf(stderr, "libopagent: readlink /proc/self/exe failed\n");
		return -1;
	}
	if (len >= MAX_PATHLENGTH) {
		fprintf(stderr, "libopagent: readlink /proc/self/exe returned"
			" path length longer than %d.\n", MAX_PATHLENGTH);

		return -1;
	}
	mypath[len] = '\0';

	bfd_init();
	bfd = bfd_openr(mypath, NULL);
	if (bfd == NULL) {
		bfd_perror("bfd_openr error. Cannot get required BFD info");
		return -1;
	}
	r = bfd_check_format(bfd, bfd_object);
	if (!r) {
		bfd_perror("bfd_get_arch error. Cannot get required BFD info");
		return -1;
	}
	_bfd_target_name =  bfd->xvec->name;
	_bfd_arch = bfd_get_arch(bfd);
	_bfd_mach = bfd_get_mach(bfd);

	return 0;
}
Beispiel #19
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;
}
main (int argc, char **argv) {
    bfd *ibfd, *obfd;
    asection *p;
    static asymbol **osympp, **delsympp;
    long symsize, symcount, delsymcount;
    int i;
    int c;
    int idx;
    struct add_reloc_struct *new_reloc;
    struct change_reloc_struct *new_change;
    struct delete_reloc_struct *new_delete;
    struct modify_byte_struct *new_modify;
    struct globalize_sym_struct *new_globalize;

    while ((c = getopt (argc, argv, "a:d:c:m:G:")) != -1) {
	switch (c) {
	    case 'a':
		/* check to see if we have two args: name and loc */
		if ((index(optarg, ',') == NULL) ||
		    (index(optarg, ',') != rindex(optarg, ','))) {
		    fprintf(stderr, "usage: -a argument should be <symbolname>,<location>, not \"%s\"\n", optarg);
		    exit(1);
		}
		/* record the add reloc command in the global array */
		new_reloc = (add_reloc_struct *)malloc(sizeof(add_reloc_struct));
		new_reloc->symbol_name = strndup(optarg, (index(optarg, ',') - optarg));
		new_reloc->loc = strtol(index(optarg, ',') + 1, NULL, 0);
		if (errno == EINVAL) {
		    fprintf(stderr, "the value %s is not a valid location for the add command\n", index(optarg, ',') + 1);
		    exit(1);
		}
		new_reloc->next = additional_relocs;
		additional_relocs = new_reloc;
		break;

	    case 'c':
		/* check to see if we have two args */
		if ((index(optarg, ',') == NULL) ||
		    (index(optarg, ',') != rindex(optarg, ','))) {
		    fprintf(stderr, "usage: -c argument should be <symbolname>,<symbolname>, not \"%s\"\n", optarg);
		    exit(1);
		}
		new_change = (change_reloc_struct *)malloc(sizeof(change_reloc_struct));
		new_change->old_symbol_name = strndup(optarg, strlen(optarg) - strlen(index(optarg, ',')));
		new_change->new_symbol_name = strdup(index(optarg, ',') + 1);
		new_change->next = change_relocs;
		change_relocs = new_change;
		break;

	    case 'd':
		new_delete = (delete_reloc_struct *)malloc(sizeof(delete_reloc_struct));
		new_delete->symbol_name = strdup(optarg);
		new_delete->next = delete_relocs;
		delete_relocs = new_delete;
		break;

	    case 'm':
		if ((index(optarg, '=') == NULL) ||
		    (index(optarg, '=') != rindex(optarg, '='))) {
		    fprintf(stderr, "usage: -m argument should be <location>=<value>, not \"%s\"\n", optarg);
		    exit(1);
		}
		new_modify = (modify_byte_struct *)malloc(sizeof(modify_byte_struct));
		new_modify->location = strtol(optarg, NULL, 0);
		new_modify->value = strtol(index(optarg, '=') + 1, NULL, 0);
		if (new_modify->value > 0xff) {
		    fprintf(stderr, "requested modify value %lx for location %lx exceeds 0xff\n",
			    new_modify->value, new_modify->location);
		    exit(1);
		}
		new_modify->next = modify_bytes;
		modify_bytes = new_modify;
		break;

	    case 'G':
		new_globalize = (globalize_sym_struct *)malloc(sizeof(globalize_sym_struct));
		new_globalize->symbol_name = strdup(optarg);
		new_globalize->next = globalize_syms;
		globalize_syms = new_globalize;
		break;

	    default:
		fprintf(stderr, "unrecognized argument character |%c|\n", c);
	}
    }

    if ((argc - optind) != 2) {
	fprintf(stderr, "usage: fixup_relocs [-a newsymbol,location] [-c oldsymbol,newsymbol] [-d symbol] infile.o outfile.o\n");
	exit(1);
    }

    ibfd = bfd_openr(argv[optind], NULL);
    if (ibfd == NULL) {
	bfd_perror("while opening input object file");
	exit(1);
    }

    /* if I don't do "check_format", there's no data in the bfd object.  wtf? */
    if (!bfd_check_format(ibfd, bfd_object)) {
	fprintf(stderr, "input file %s seems to NOT be an object file! exiting.\n", argv[optind]);
	exit(1);
    }

    obfd = bfd_openw(argv[optind+1], bfd_get_target(ibfd));
    if (obfd == NULL) {
	bfd_perror("while opening output object file");
	exit(1);
    }

    if (!bfd_set_format(obfd, bfd_get_format(ibfd))) {
	bfd_perror("while setting output object file format");
    }

    /* copy a bunch of necessary global stuff */
    bfd_set_start_address(obfd, bfd_get_start_address(ibfd));
    bfd_set_file_flags(obfd, bfd_get_file_flags(ibfd));
    bfd_set_arch_mach(obfd, bfd_get_arch(ibfd), bfd_get_mach(ibfd));
    /* BOZO objcopy sets format again at this point.  why? */

    bfd_map_over_sections (ibfd, setup_section, obfd);

    setup_bfd_headers (ibfd, obfd);

    /* Symbol filtering must happen after the output sections
       have been created, but before their contents are set.  */
    symsize = bfd_get_symtab_upper_bound (ibfd);
    if (symsize < 0) {
	fprintf(stderr, "problem processing %s\n", bfd_get_filename (ibfd));
	return FALSE;
    }

    /* count the added relocations so we can put extra space in the output symbol table for them */
    int reloc_add_cnt, reloc_delete_cnt;
    reloc_add_cnt = 0;
    reloc_delete_cnt = 0;
    for (new_reloc = additional_relocs; new_reloc != NULL; new_reloc = new_reloc->next) {
	reloc_add_cnt++;
    }
    /* the "change" symbols might also not be in the symbol table yet */
    for (new_change = change_relocs; new_change != NULL; new_change = new_change->next) {
	reloc_add_cnt++;
	/* the old symbol may be deleted, also */
	reloc_delete_cnt++;
    }
    for (new_delete = delete_relocs; new_delete != NULL; new_delete = new_delete->next) {
	reloc_delete_cnt++;
    }

    /* filter symbol table in two steps: */
    /* 1) move symbols bound for deletion to the end of the output symbol table array */
    /* 2) truncate the table at the first of those */
    /* this makes it possible to do the reloc processing with the symbol table intact, */
    /* and remove the deleted symbols afterwards, without corrupting the reloc data structures */
    isympp = malloc (symsize);
    osympp = malloc (symsize + reloc_add_cnt * sizeof(asymbol *));
    delsympp = malloc (reloc_delete_cnt * sizeof(asymbol *));
    symcount = bfd_canonicalize_symtab (ibfd, isympp);

    if (symcount < 0) {
	fprintf(stderr, "problem processing %s\n", bfd_get_filename (ibfd));
	return FALSE;
    }

    /* remove any undefined symbols whose relocation entries were deleted or changed */
    int osym_idx, delsym_idx;
    osym_idx = delsym_idx = 0;
    delsymcount = 0;
    for (i = 0; i < symcount; i++) {
	if ((is_delete_reloc(bfd_asymbol_name(isympp[i]), delete_relocs) ||
	     (find_change_reloc(bfd_asymbol_name(isympp[i]), change_relocs) != NULL)) &&
	    (isympp[i]->section != NULL) &&
	    (strcmp(isympp[i]->section->name, BFD_UND_SECTION_NAME) == 0)) {
	    delsympp[delsym_idx++] = isympp[i];
	}
	else {
	    if (is_globalize_sym(bfd_asymbol_name(isympp[i]), globalize_syms)) {
		isympp[i]->flags = BSF_GLOBAL;
	    }
	    osympp[osym_idx++] = isympp[i];
	}
    }
    symcount = osym_idx;
    delsymcount = delsym_idx;
    osympp[symcount] = NULL;

    /* add the symbols for additional relocs to the table */
    int added_symbol_cnt = 0;
    for (new_reloc = additional_relocs; new_reloc != NULL; new_reloc = new_reloc->next) {
	if (find_symbol(osympp, new_reloc->symbol_name) < 0) {
	    /* not yet present, so add it */
	    asymbol *new_sym;
	    new_sym = bfd_make_empty_symbol(obfd);
	    new_sym->name = strdup(new_reloc->symbol_name);
	    new_sym->section = bfd_get_section_by_name (obfd, ".text");
	    new_sym->value = new_reloc->loc;
	    new_sym->flags = BSF_GLOBAL;
	    osympp[symcount + added_symbol_cnt++] = new_sym;
	    osympp[symcount + added_symbol_cnt] = NULL;
	}
    }

    /* do the same for changed relocs */
    for (new_change = change_relocs; new_change != NULL; new_change = new_change->next) {
	if (find_symbol(osympp, new_change->new_symbol_name) < 0) {
	    /* not yet present, so add it */
	    /* since this is a name change, we will reuse the existing address (value field of reloc) */
	    int old_symbol_idx;
	    if ((old_symbol_idx = find_symbol(isympp, new_change->old_symbol_name)) < 0) {
		fprintf(stderr, "change command old symbol name %s not found in symbol table! Exiting.\n", new_change->old_symbol_name);
		exit(1);
	    }
	    asymbol *new_sym;
	    new_sym = bfd_make_empty_symbol(obfd);
	    new_sym->name = strdup(new_change->new_symbol_name);
	    new_sym->section = bfd_und_section_ptr;
	    new_sym->value = isympp[old_symbol_idx]->value;
	    new_sym->flags = BSF_GLOBAL;
	    fprintf(stderr, "adding new symbol %s for change reloc command\n", new_sym->name);
	    osympp[symcount + added_symbol_cnt++] = new_sym;
	    osympp[symcount + added_symbol_cnt] = NULL;
	}
    }

    /* append the soon-to-be deleted symbols to the end of the output symbol table */
    for (i = 0; i < delsymcount; i++) {
	osympp[symcount + added_symbol_cnt + i] = delsympp[i];
    }
    osympp[symcount + added_symbol_cnt + delsymcount] = NULL;

    bfd_set_symtab (obfd, osympp, symcount + added_symbol_cnt + delsymcount);

    /* This has to happen after the symbol table has been set.  */
    bfd_map_over_sections (ibfd, copy_section_relocs_edit, obfd);

    /* now truncate the symbol table to eliminate the deleted symbols */
    osympp[symcount + added_symbol_cnt] = NULL;

    bfd_set_symtab (obfd, osympp, symcount + added_symbol_cnt);
    
    /* now that we've set the relocs and cleaned the symtab, can call this */
    bfd_map_over_sections (ibfd, copy_section_data, obfd);

    bfd_close(obfd);
    bfd_close(ibfd);

    return 0;

}
void
m32c_load (bfd * prog)
{
  asection *s;
  unsigned long mach = bfd_get_mach (prog);
  unsigned long highest_addr_loaded = 0;

  if (mach == 0 && default_machine != 0)
    mach = default_machine;

  m32c_set_mach (mach);

  for (s = prog->sections; s; s = s->next)
    {
#if 0
      /* This was a good idea until we started storing the RAM data in
         ROM, at which point everything was all messed up.  The code
         remains as a reminder.  */
      if ((s->flags & SEC_ALLOC) && !(s->flags & SEC_READONLY))
	{
	  if (strcmp (bfd_get_section_name (prog, s), ".stack"))
	    {
	      int secend =
		bfd_get_section_size (s) + bfd_section_lma (prog, s);
	      if (heaptop < secend && bfd_section_lma (prog, s) < 0x10000)
		{
		  heaptop = heapbottom = secend;
		}
	    }
	}
#endif
      if (s->flags & SEC_LOAD)
	{
	  char *buf;
	  bfd_size_type size;

	  size = bfd_get_section_size (s);
	  if (size <= 0)
	    continue;

	  bfd_vma base = bfd_section_lma (prog, s);
	  if (verbose)
	    fprintf (stderr, "[load a=%08x s=%08x %s]\n",
		     (int) base, (int) size, bfd_get_section_name (prog, s));
	  buf = (char *) malloc (size);
	  bfd_get_section_contents (prog, s, buf, 0, size);
	  mem_put_blk (base, buf, size);
	  free (buf);
	  if (highest_addr_loaded < base + size - 1 && size >= 4)
	    highest_addr_loaded = base + size - 1;
	}
    }

  if (strcmp (bfd_get_target (prog), "srec") == 0)
    {
      heaptop = heapbottom = 0;
      switch (mach)
	{
	case bfd_mach_m16c:
	  if (highest_addr_loaded > 0x10000)
	    regs.r_pc = mem_get_si (0x000ffffc) & membus_mask;
	  else
	    regs.r_pc = mem_get_si (0x000fffc) & membus_mask;
	  break;
	case bfd_mach_m32c:
	  regs.r_pc = mem_get_si (0x00fffffc) & membus_mask;
	  break;
	}
    }
  else
    regs.r_pc = prog->start_address;
  if (verbose)
    fprintf (stderr, "[start pc=%08x]\n", (unsigned int) regs.r_pc);
}
Beispiel #22
0
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
}
Beispiel #23
0
void objdump(const char *path)
{
    bfd_init();

    bfd *abfd = bfd_openr(path, NULL);

    if (abfd == NULL)
        errx(1, bfd_errmsg(bfd_get_error()));

    if (!bfd_check_format(abfd, bfd_object)) {
        bfd_close_all_done(abfd);
        errx(1, "File is not a valid object file.");
    }

    printf("%s:     file format %s\n", path, bfd_get_target(abfd));
    printf("architecture: %s, flags: 0x%08x\n", bfd_printable_arch_mach(bfd_get_arch(abfd), bfd_get_mach(abfd)), abfd->flags);
    printf("start address 0x%016lx", bfd_get_start_address(abfd));
    printf("\n");
    printf("Sections:\n");
    printf("Idx Name          Size      VMA               LMA               File off  Algn\n");
    printf("                  Flags    Content\n");

    object_stats stats = { FALSE, FALSE };
    bfd_map_over_sections(abfd, (void (*)(bfd *, asection *, void *))print_section, &stats);

    if (stats.contains_hello && stats.contains_world)
        printf("\nThis file might be a hello world program!\n");

    bfd_close(abfd);
}
Beispiel #24
0
void init_disassemble(){
	abfd = malloc(sizeof(bfd));
	init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf);
	disasm_info.print_address_func = objdump_print_address;
	disasm_info.symbol_at_address_func = objdump_symbol_at_address;

	/*
	 * choose arch infor since we will select different disassemble function.
	 */
	generic_arch_t* arch_instance = get_arch_instance("");
	machine = arch_instance->arch_name;	
	const bfd_arch_info_type *info = bfd_scan_arch (machine);
	if (info == NULL){
        	//fatal (_("Can't use supplied machine %s"), machine);
		printf("Can't use supplied machine %s\n", machine);
		return;
	}

	abfd->arch_info = info;
	
	/*
	 * endian selection
	 */
	if (endian != BFD_ENDIAN_UNKNOWN)
	{
		struct bfd_target *xvec;

		xvec = xmalloc (sizeof (struct bfd_target));
		//memcpy (xvec, abfd->xvec, sizeof (struct bfd_target));
		xvec->byteorder = endian;
		abfd->xvec = xvec;
	}
	/* Get a disassemble function according to the arch and endian of abfd */
	disassemble_fn = disassembler (abfd);
	if(!disassemble_fn)
	{
      /*
	non_fatal (_("Can't disassemble for architecture %s\n"),
                 bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
	*/
		printf("Can't disassemble for architecture %s\n", bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
		exit_status = 1;
		return;
	}

	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 1
	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;
	else
 /* ??? Aborting here seems too drastic.  We could default to big or little
       instead.  */
	disasm_info.endian = BFD_ENDIAN_UNKNOWN;
#endif
	/* set the default endianess is BFD_ENDIAN_LITTLE */
	disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE;
	disasm_info.symtab = sorted_syms;
	disasm_info.symtab_size = sorted_symcount;
	disasm_info.read_memory_func = disasm_read_memory;
	free (sorted_syms);
}
Beispiel #25
0
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 ();
    }
unsigned int
bfd_octets_per_byte (bfd *abfd)
{
  return bfd_arch_mach_octets_per_byte (bfd_get_arch (abfd),
					bfd_get_mach (abfd));
}
Beispiel #27
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;
}