Example #1
0
static bfd_boolean
mips_ecoff_bad_format_hook (bfd * abfd, void * filehdr)
{
  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;

  switch (internal_f->f_magic)
    {
    case MIPS_MAGIC_1:
      /* I don't know what endianness this implies.  */
      return TRUE;

    case MIPS_MAGIC_BIG:
    case MIPS_MAGIC_BIG2:
    case MIPS_MAGIC_BIG3:
      return bfd_big_endian (abfd);

    case MIPS_MAGIC_LITTLE:
    case MIPS_MAGIC_LITTLE2:
    case MIPS_MAGIC_LITTLE3:
      return bfd_little_endian (abfd);

    default:
      return FALSE;
    }
}
Example #2
0
/* Appends OpenCL programs to the list of `struct so_list' objects.  */
static void
append_ocl_sos (struct so_list **link_ptr)
{
  CORE_ADDR *ocl_program_addr_base;
  struct objfile *objfile;

  ALL_OBJFILES (objfile)
    {
      ocl_program_addr_base
	= (CORE_ADDR *) objfile_data (objfile, ocl_program_data_key);
      if (ocl_program_addr_base != NULL)
        {
	  enum bfd_endian byte_order = bfd_big_endian (objfile->obfd)?
					 BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
	  TRY
	    {
	      CORE_ADDR data =
		read_memory_unsigned_integer (*ocl_program_addr_base,
					      sizeof (CORE_ADDR),
					      byte_order);
	      if (data != 0x0)
		{
		  struct so_list *newobj;

		  /* Allocate so_list structure.  */
		  newobj = XCNEW (struct so_list);

		  /* Encode FD and object ID in path name.  */
		  xsnprintf (newobj->so_name, sizeof newobj->so_name, "@%s <%d>",
			     hex_string (data),
			     SPUADDR_SPU (*ocl_program_addr_base));
		  strcpy (newobj->so_original_name, newobj->so_name);

		  *link_ptr = newobj;
		  link_ptr = &newobj->next;
		}
	    }
	  CATCH (ex, RETURN_MASK_ALL)
	    {
	      /* Ignore memory errors.  */
	      switch (ex.error)
		{
		case MEMORY_ERROR:
		  break;
		default:
		  throw_exception (ex);
		  break;
		}
	    }
	  END_CATCH
	}
    }
}
Example #3
0
void
gdbarch_info_fill (struct gdbarch_info *info)
{
  /* "(gdb) set architecture ...".  */
  if (info->bfd_arch_info == NULL
      && target_architecture_user)
    info->bfd_arch_info = target_architecture_user;
  /* From the file.  */
  if (info->bfd_arch_info == NULL
      && info->abfd != NULL
      && bfd_get_arch (info->abfd) != bfd_arch_unknown
      && bfd_get_arch (info->abfd) != bfd_arch_obscure)
    info->bfd_arch_info = bfd_get_arch_info (info->abfd);
  /* From the target.  */
  if (info->target_desc != NULL)
    info->bfd_arch_info = choose_architecture_for_target
			   (info->target_desc, info->bfd_arch_info);
  /* From the default.  */
  if (info->bfd_arch_info == NULL)
    info->bfd_arch_info = default_bfd_arch;

  /* "(gdb) set byte-order ...".  */
  if (info->byte_order == BFD_ENDIAN_UNKNOWN
      && target_byte_order_user != BFD_ENDIAN_UNKNOWN)
    info->byte_order = target_byte_order_user;
  /* From the INFO struct.  */
  if (info->byte_order == BFD_ENDIAN_UNKNOWN
      && info->abfd != NULL)
    info->byte_order = (bfd_big_endian (info->abfd) ? BFD_ENDIAN_BIG
			: bfd_little_endian (info->abfd) ? BFD_ENDIAN_LITTLE
			: BFD_ENDIAN_UNKNOWN);
  /* From the default.  */
  if (info->byte_order == BFD_ENDIAN_UNKNOWN)
    info->byte_order = default_byte_order;
  info->byte_order_for_code = info->byte_order;

  /* "(gdb) set osabi ...".  Handled by gdbarch_lookup_osabi.  */
  /* From the manual override, or from file.  */
  if (info->osabi == GDB_OSABI_UNINITIALIZED)
    info->osabi = gdbarch_lookup_osabi (info->abfd);
  /* From the target.  */
  if (info->osabi == GDB_OSABI_UNKNOWN && info->target_desc != NULL)
    info->osabi = tdesc_osabi (info->target_desc);
  /* From the configured default.  */
#ifdef GDB_OSABI_DEFAULT
  if (info->osabi == GDB_OSABI_UNKNOWN)
    info->osabi = GDB_OSABI_DEFAULT;
#endif

  /* Must have at least filled in the architecture.  */
  gdb_assert (info->bfd_arch_info != NULL);
}
Example #4
0
int
create_inferior (char *program, char **argv)
{
  bfd *abfd;
  int pid = 0;
  char **new_argv;
  int nargs;

  abfd = bfd_openr (program, 0);
  if (!abfd)
    {
      fprintf (stderr, "gdbserver: cannot open %s: %s\n",
	       program, bfd_errmsg (bfd_get_error ()));
      exit (1);
    }

  if (!bfd_check_format (abfd, bfd_object))
    {
      fprintf (stderr, "gdbserver: unknown load format for %s: %s\n",
	       program, bfd_errmsg (bfd_get_error ()));
      exit (1);
    }

  /* Add "-E big" or "-E little" to the argument list depending on the
     endianness of the program to be loaded.  */
  for (nargs = 0; argv[nargs] != NULL; nargs++)		/* count the args */
    ;
  new_argv = alloca (sizeof (char *) * (nargs + 3));	/* allocate new args */
  for (nargs = 0; argv[nargs] != NULL; nargs++)		/* copy old to new */
    new_argv[nargs] = argv[nargs];
  new_argv[nargs] = "-E";
  new_argv[nargs + 1] = bfd_big_endian (abfd) ? "big" : "little";
  new_argv[nargs + 2] = NULL;
  argv = new_argv;

  /* Create an instance of the simulator.  */
  default_callback.init (&default_callback);
  gdbsim_desc = sim_open (SIM_OPEN_STANDALONE, &default_callback, abfd, argv);
  if (gdbsim_desc == 0)
    exit (1);

  /* Load the program into the simulator.  */
  if (abfd)
    if (sim_load (gdbsim_desc, program, NULL, 0) == SIM_RC_FAIL)
      mygeneric_load (abfd);

  /* Create an inferior process in the simulator.  This initializes SP.  */
  sim_create_inferior (gdbsim_desc, abfd, argv, /* env */ NULL);
  sim_resume (gdbsim_desc, 1, 0);	/* execute one instr */
  return pid;
}
Example #5
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;
}
Example #6
0
static void
set_endian_from_file (bfd *abfd)
{
  int want;
  if (GDB_MULTI_ARCH)
    internal_error (__FILE__, __LINE__,
		    "set_endian_from_file: not for multi-arch");
  if (bfd_big_endian (abfd))
    want = BFD_ENDIAN_BIG;
  else
    want = BFD_ENDIAN_LITTLE;
  if (TARGET_BYTE_ORDER_AUTO)
    target_byte_order = want;
  else if (TARGET_BYTE_ORDER != want)
    warning ("%s endian file does not match %s endian target.",
	     want == BFD_ENDIAN_BIG ? "big" : "little",
	     TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "big" : "little");
}
Example #7
0
static void
add_to_spuid_list (bfd *abfd, asection *asect, void *list_p)
{
  struct spuid_list *list = list_p;
  enum bfd_endian byte_order
    = bfd_big_endian (abfd) ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
  int fd, pos = 0;

  sscanf (bfd_section_name (abfd, asect), "SPU/%d/regs%n", &fd, &pos);
  if (pos == 0)
    return;

  if (list->pos >= list->offset && list->pos + 4 <= list->offset + list->len)
    {
      store_unsigned_integer (list->buf + list->pos - list->offset,
			      4, byte_order, fd);
      list->written += 4;
    }
  list->pos += 4;
}
Example #8
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;
}
Example #9
0
static bfd_boolean
sh64_address_in_cranges (asection *cranges, bfd_vma addr,
			 sh64_elf_crange *rangep)
{
  bfd_byte *cranges_contents;
  bfd_byte *found_rangep;
  bfd_size_type cranges_size = cranges->size;

  /* If the size is not a multiple of the cranges entry size, then
     something is badly wrong.  */
  if ((cranges_size % SH64_CRANGE_SIZE) != 0)
    return FALSE;

  /* If this section has relocations, then we can't do anything sane.  */
  if (bfd_get_section_flags (cranges->owner, cranges) & SEC_RELOC)
    return FALSE;

  /* Has some kind soul (or previous call) left processed, sorted contents
     for us?  */
  if ((bfd_get_section_flags (cranges->owner, cranges) & SEC_IN_MEMORY)
      && elf_section_data (cranges)->this_hdr.sh_type == SHT_SH5_CR_SORTED)
    cranges_contents = cranges->contents;
  else
    {
      if (!bfd_malloc_and_get_section (cranges->owner, cranges,
				       &cranges_contents))
	goto error_return;

      /* Is it sorted?  */
      if (elf_section_data (cranges)->this_hdr.sh_type
	  != SHT_SH5_CR_SORTED)
	/* Nope.  Lets sort it.  */
	qsort (cranges_contents, cranges_size / SH64_CRANGE_SIZE,
	       SH64_CRANGE_SIZE,
	       bfd_big_endian (cranges->owner)
	       ? _bfd_sh64_crange_qsort_cmpb : _bfd_sh64_crange_qsort_cmpl);

      /* Let's keep it around.  */
      cranges->contents = cranges_contents;
      bfd_set_section_flags (cranges->owner, cranges,
			     bfd_get_section_flags (cranges->owner, cranges)
			     | SEC_IN_MEMORY);

      /* It's sorted now.  */
      elf_section_data (cranges)->this_hdr.sh_type = SHT_SH5_CR_SORTED;
    }

  /* Try and find a matching range.  */
  found_rangep
    = bsearch (&addr, cranges_contents, cranges_size / SH64_CRANGE_SIZE,
	       SH64_CRANGE_SIZE,
	       bfd_big_endian (cranges->owner)
	       ? _bfd_sh64_crange_bsearch_cmpb
	       : _bfd_sh64_crange_bsearch_cmpl);

  /* Fill in a few return values if we found a matching range.  */
  if (found_rangep)
    {
      enum sh64_elf_cr_type cr_type
	= bfd_get_16 (cranges->owner,
		      SH64_CRANGE_CR_TYPE_OFFSET + found_rangep);
      bfd_vma cr_addr
	= bfd_get_32 (cranges->owner,
		      SH64_CRANGE_CR_ADDR_OFFSET
		      + (char *) found_rangep);
      bfd_size_type cr_size
	= bfd_get_32 (cranges->owner,
		      SH64_CRANGE_CR_SIZE_OFFSET
		      + (char *) found_rangep);

      rangep->cr_addr = cr_addr;
      rangep->cr_size = cr_size;
      rangep->cr_type = cr_type;

      return TRUE;
    }

  /* There is a .cranges section, but it does not have a descriptor
     matching this address.  */
  return FALSE;

error_return:
  if (cranges_contents != NULL)
    free (cranges_contents);
  return FALSE;
}
Example #10
0
static void
build_link_order (lang_statement_union_type *statement)
{
  switch (statement->header.type)
    {
    case lang_data_statement_enum:
      {
	asection *output_section;
	struct bfd_link_order *link_order;
	bfd_vma value;
	bfd_boolean big_endian = FALSE;

	output_section = statement->data_statement.output_section;
	ASSERT (output_section->owner == link_info.output_bfd);

	if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
	      || ((output_section->flags & SEC_LOAD) != 0
		  && (output_section->flags & SEC_THREAD_LOCAL))))
	  break;

	link_order = bfd_new_link_order (link_info.output_bfd, output_section);
	if (link_order == NULL)
	  einfo (_("%F%P: bfd_new_link_order failed\n"));

	link_order->type = bfd_data_link_order;
	link_order->offset = statement->data_statement.output_offset;
	link_order->u.data.contents = (bfd_byte *) xmalloc (QUAD_SIZE);

	value = statement->data_statement.value;

	/* If the endianness of the output BFD is not known, then we
	   base the endianness of the data on the first input file.
	   By convention, the bfd_put routines for an unknown
	   endianness are big endian, so we must swap here if the
	   input file is little endian.  */
	if (bfd_big_endian (link_info.output_bfd))
	  big_endian = TRUE;
	else if (bfd_little_endian (link_info.output_bfd))
	  big_endian = FALSE;
	else
	  {
	    bfd_boolean swap;

	    swap = FALSE;
	    if (command_line.endian == ENDIAN_BIG)
	      big_endian = TRUE;
	    else if (command_line.endian == ENDIAN_LITTLE)
	      {
		big_endian = FALSE;
		swap = TRUE;
	      }
	    else if (command_line.endian == ENDIAN_UNSET)
	      {
		big_endian = TRUE;
		{
		  LANG_FOR_EACH_INPUT_STATEMENT (s)
		  {
		    if (s->the_bfd != NULL)
		      {
			if (bfd_little_endian (s->the_bfd))
			  {
			    big_endian = FALSE;
			    swap = TRUE;
			  }
			break;
		      }
		  }
		}
	      }

	    if (swap)
	      {
		bfd_byte buffer[8];

		switch (statement->data_statement.type)
		  {
		  case QUAD:
		  case SQUAD:
		    if (sizeof (bfd_vma) >= QUAD_SIZE)
		      {
			bfd_putl64 (value, buffer);
			value = bfd_getb64 (buffer);
			break;
		      }
		    /* Fall through.  */
		  case LONG:
		    bfd_putl32 (value, buffer);
		    value = bfd_getb32 (buffer);
		    break;
		  case SHORT:
		    bfd_putl16 (value, buffer);
		    value = bfd_getb16 (buffer);
		    break;
		  case BYTE:
		    break;
		  default:
		    abort ();
		  }
	      }
	  }

	ASSERT (output_section->owner == link_info.output_bfd);
	switch (statement->data_statement.type)
	  {
	  case QUAD:
	  case SQUAD:
	    if (sizeof (bfd_vma) >= QUAD_SIZE)
	      bfd_put_64 (link_info.output_bfd, value,
			  link_order->u.data.contents);
	    else
	      {
		bfd_vma high;

		if (statement->data_statement.type == QUAD)
		  high = 0;
		else if ((value & 0x80000000) == 0)
		  high = 0;
		else
		  high = (bfd_vma) -1;
		bfd_put_32 (link_info.output_bfd, high,
			    (link_order->u.data.contents
			     + (big_endian ? 0 : 4)));
		bfd_put_32 (link_info.output_bfd, value,
			    (link_order->u.data.contents
			     + (big_endian ? 4 : 0)));
	      }
	    link_order->size = QUAD_SIZE;
	    break;
	  case LONG:
	    bfd_put_32 (link_info.output_bfd, value,
			link_order->u.data.contents);
	    link_order->size = LONG_SIZE;
	    break;
	  case SHORT:
	    bfd_put_16 (link_info.output_bfd, value,
			link_order->u.data.contents);
	    link_order->size = SHORT_SIZE;
	    break;
	  case BYTE:
	    bfd_put_8 (link_info.output_bfd, value,
		       link_order->u.data.contents);
	    link_order->size = BYTE_SIZE;
	    break;
	  default:
	    abort ();
	  }
	link_order->u.data.size = link_order->size;
      }
      break;

    case lang_reloc_statement_enum:
      {
	lang_reloc_statement_type *rs;
	asection *output_section;
	struct bfd_link_order *link_order;

	rs = &statement->reloc_statement;

	output_section = rs->output_section;
	ASSERT (output_section->owner == link_info.output_bfd);

	if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
	      || ((output_section->flags & SEC_LOAD) != 0
		  && (output_section->flags & SEC_THREAD_LOCAL))))
	  break;

	link_order = bfd_new_link_order (link_info.output_bfd, output_section);
	if (link_order == NULL)
	  einfo (_("%F%P: bfd_new_link_order failed\n"));

	link_order->offset = rs->output_offset;
	link_order->size = bfd_get_reloc_size (rs->howto);

	link_order->u.reloc.p = (struct bfd_link_order_reloc *)
	  xmalloc (sizeof (struct bfd_link_order_reloc));

	link_order->u.reloc.p->reloc = rs->reloc;
	link_order->u.reloc.p->addend = rs->addend_value;

	if (rs->name == NULL)
	  {
	    link_order->type = bfd_section_reloc_link_order;
	    if (rs->section->owner == link_info.output_bfd)
	      link_order->u.reloc.p->u.section = rs->section;
	    else
	      {
		link_order->u.reloc.p->u.section = rs->section->output_section;
		link_order->u.reloc.p->addend += rs->section->output_offset;
	      }
	  }
	else
	  {
	    link_order->type = bfd_symbol_reloc_link_order;
	    link_order->u.reloc.p->u.name = rs->name;
	  }
      }
      break;

    case lang_input_section_enum:
      {
	/* Create a new link_order in the output section with this
	   attached */
	asection *i = statement->input_section.section;

	if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
	    && (i->flags & SEC_EXCLUDE) == 0)
	  {
	    asection *output_section = i->output_section;
	    struct bfd_link_order *link_order;

	    ASSERT (output_section->owner == link_info.output_bfd);

	    if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
		  || ((output_section->flags & SEC_LOAD) != 0
		      && (output_section->flags & SEC_THREAD_LOCAL))))
	      break;

	    link_order = bfd_new_link_order (link_info.output_bfd,
					     output_section);
	    if (link_order == NULL)
	      einfo (_("%F%P: bfd_new_link_order failed\n"));

	    if ((i->flags & SEC_NEVER_LOAD) != 0
		&& (i->flags & SEC_DEBUGGING) == 0)
	      {
		/* We've got a never load section inside one which is
		   going to be output, we'll change it into a fill.  */
		link_order->type = bfd_data_link_order;
		link_order->u.data.contents = (unsigned char *) "";
		link_order->u.data.size = 1;
	      }
	    else
	      {
		link_order->type = bfd_indirect_link_order;
		link_order->u.indirect.section = i;
		ASSERT (i->output_section == output_section);
	      }
	    link_order->size = i->size;
	    link_order->offset = i->output_offset;
	  }
      }
      break;

    case lang_padding_statement_enum:
      /* Make a new link_order with the right filler */
      {
	asection *output_section;
	struct bfd_link_order *link_order;

	output_section = statement->padding_statement.output_section;
	ASSERT (statement->padding_statement.output_section->owner
		== link_info.output_bfd);

	if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
	      || ((output_section->flags & SEC_LOAD) != 0
		  && (output_section->flags & SEC_THREAD_LOCAL))))
	  break;

	link_order = bfd_new_link_order (link_info.output_bfd,
					 output_section);
	if (link_order == NULL)
	  einfo (_("%F%P: bfd_new_link_order failed\n"));
	link_order->type = bfd_data_link_order;
	link_order->size = statement->padding_statement.size;
	link_order->offset = statement->padding_statement.output_offset;
	link_order->u.data.contents = statement->padding_statement.fill->data;
	link_order->u.data.size = statement->padding_statement.fill->size;
      }
      break;

    default:
      /* All the other ones fall through */
      break;
    }
Example #11
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);
}
Example #12
0
SIM_RC
sim_config (SIM_DESC sd)
{
  enum bfd_endian prefered_target_byte_order;
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);

  /* extract all relevant information */
  if (STATE_PROG_BFD (sd) == NULL
      /* If we have a binary input file (presumably with specified
	 "--architecture"), it'll have no endianness.  */
      || (!bfd_little_endian (STATE_PROG_BFD (sd))
	  && !bfd_big_endian (STATE_PROG_BFD (sd))))
    prefered_target_byte_order = BFD_ENDIAN_UNKNOWN;
  else
    prefered_target_byte_order = (bfd_little_endian (STATE_PROG_BFD (sd))
				  ? BFD_ENDIAN_LITTLE
				  : BFD_ENDIAN_BIG);

  /* set the target byte order */
#if (WITH_TREE_PROPERTIES)
  if (current_target_byte_order == BFD_ENDIAN_UNKNOWN)
    current_target_byte_order
      = (tree_find_boolean_property (root, "/options/little-endian?")
	 ? BFD_ENDIAN_LITTLE
	 : BFD_ENDIAN_BIG);
#endif
  if (current_target_byte_order == BFD_ENDIAN_UNKNOWN
      && prefered_target_byte_order != BFD_ENDIAN_UNKNOWN)
    current_target_byte_order = prefered_target_byte_order;
  if (current_target_byte_order == BFD_ENDIAN_UNKNOWN)
    current_target_byte_order = WITH_TARGET_BYTE_ORDER;
  if (current_target_byte_order == BFD_ENDIAN_UNKNOWN)
    current_target_byte_order = WITH_DEFAULT_TARGET_BYTE_ORDER;

  /* verify the target byte order */
  if (CURRENT_TARGET_BYTE_ORDER == BFD_ENDIAN_UNKNOWN)
    {
      sim_io_eprintf (sd, "Target byte order unspecified\n");
      return SIM_RC_FAIL;
    }
  if (CURRENT_TARGET_BYTE_ORDER != current_target_byte_order)
    sim_io_eprintf (sd, "Target (%s) and configured (%s) byte order in conflict\n",
		  config_byte_order_to_a (current_target_byte_order),
		  config_byte_order_to_a (CURRENT_TARGET_BYTE_ORDER));
  if (prefered_target_byte_order != BFD_ENDIAN_UNKNOWN
      && CURRENT_TARGET_BYTE_ORDER != prefered_target_byte_order)
    sim_io_eprintf (sd, "Target (%s) and specified (%s) byte order in conflict\n",
		  config_byte_order_to_a (CURRENT_TARGET_BYTE_ORDER),
		  config_byte_order_to_a (prefered_target_byte_order));


  /* set the stdio */
  if (current_stdio == 0)
    current_stdio = WITH_STDIO;
  if (current_stdio == 0)
    current_stdio = DO_USE_STDIO;

  /* verify the stdio */
  if (CURRENT_STDIO == 0)
    {
      sim_io_eprintf (sd, "Target standard IO unspecified\n");
      return SIM_RC_FAIL;
    }
  if (CURRENT_STDIO != current_stdio)
    {
      sim_io_eprintf (sd, "Target (%s) and configured (%s) standard IO in conflict\n",
		      config_stdio_to_a (CURRENT_STDIO),
		      config_stdio_to_a (current_stdio));
      return SIM_RC_FAIL;
    }


  /* check the value of MSB */
  if (WITH_TARGET_WORD_MSB != 0
      && WITH_TARGET_WORD_MSB != (WITH_TARGET_WORD_BITSIZE - 1))
    {
      sim_io_eprintf (sd, "Target bitsize (%d) contradicts target most significant bit (%d)\n",
		      WITH_TARGET_WORD_BITSIZE, WITH_TARGET_WORD_MSB);
      return SIM_RC_FAIL;
    }


  /* set the environment */
#if (WITH_TREE_PROPERTIES)
  if (STATE_ENVIRONMENT (sd) == ALL_ENVIRONMENT)
    {
      const char *env =
	tree_find_string_property (root, "/openprom/options/env");
      STATE_ENVIRONMENT (sd) = ((strcmp (env, "user") == 0
				 || strcmp (env, "uea") == 0)
				? USER_ENVIRONMENT
				: (strcmp (env, "virtual") == 0
				   || strcmp (env, "vea") == 0)
				? VIRTUAL_ENVIRONMENT
				: (strcmp (env, "operating") == 0
				   || strcmp (env, "oea") == 0)
				? OPERATING_ENVIRONMENT
				: ALL_ENVIRONMENT);
    }
#endif
  if (STATE_ENVIRONMENT (sd) == ALL_ENVIRONMENT)
    STATE_ENVIRONMENT (sd) = (WITH_ENVIRONMENT != ALL_ENVIRONMENT ?
			      WITH_ENVIRONMENT : USER_ENVIRONMENT);


  /* set the alignment */
#if (WITH_TREE_PROPERTIES)
  if (current_alignment == 0)
    current_alignment =
      (tree_find_boolean_property (root, "/openprom/options/strict-alignment?")
       ? STRICT_ALIGNMENT
       : NONSTRICT_ALIGNMENT);
#endif
  if (current_alignment == 0)
    current_alignment = WITH_ALIGNMENT;
  if (current_alignment == 0)
    current_alignment = WITH_DEFAULT_ALIGNMENT;

  /* verify the alignment */
  if (CURRENT_ALIGNMENT == 0)
    {
      sim_io_eprintf (sd, "Target alignment unspecified\n");
      return SIM_RC_FAIL;
    }
  if (CURRENT_ALIGNMENT != current_alignment)
    {
      sim_io_eprintf (sd, "Target (%s) and configured (%s) alignment in conflict\n",
		      config_alignment_to_a (CURRENT_ALIGNMENT),
		      config_alignment_to_a (current_alignment));
      return SIM_RC_FAIL;
    }

#if defined (WITH_FLOATING_POINT)

  /* set the floating point */
  if (current_floating_point == 0)
    current_floating_point = WITH_FLOATING_POINT;

  /* verify the floating point */
  if (CURRENT_FLOATING_POINT == 0)
    {
      sim_io_eprintf (sd, "Target floating-point unspecified\n");
      return SIM_RC_FAIL;
    }
  if (CURRENT_FLOATING_POINT != current_floating_point)
    {
      sim_io_eprintf (sd, "Target (%s) and configured (%s) floating-point in conflict\n",
		      config_alignment_to_a (CURRENT_FLOATING_POINT),
		      config_alignment_to_a (current_floating_point));
      return SIM_RC_FAIL;
    }

#endif
  return SIM_RC_OK;
}
void
rx_load (bfd *prog)
{
  unsigned long highest_addr_loaded = 0;
  Elf_Internal_Phdr * phdrs;
  long sizeof_phdrs;
  int num_headers;
  int i;

  rx_big_endian = bfd_big_endian (prog);

  /* Note we load by ELF program header not by BFD sections.
     This is because BFD sections get their information from
     the ELF section structure, which only includes a VMA value
     and not an LMA value.  */
  sizeof_phdrs = bfd_get_elf_phdr_upper_bound (prog);
  if (sizeof_phdrs == 0)
    {
      fprintf (stderr, "Failed to get size of program headers\n");
      return;
    }
  phdrs = malloc (sizeof_phdrs);
  if (phdrs == NULL)
    {
      fprintf (stderr, "Failed allocate memory to hold program headers\n");
      return;
    }
  num_headers = bfd_get_elf_phdrs (prog, phdrs);
  if (num_headers < 1)
    {
      fprintf (stderr, "Failed to read program headers\n");
      return;
    }
  
  for (i = 0; i < num_headers; i++)
    {
      Elf_Internal_Phdr * p = phdrs + i;
      char *buf;
      bfd_vma size;
      bfd_vma base;
      file_ptr offset;

      size = p->p_filesz;
      if (size <= 0)
	continue;

      base = p->p_paddr;
      if (verbose > 1)
	fprintf (stderr, "[load segment: lma=%08x vma=%08x size=%08x]\n",
		 (int) base, (int) p->p_vaddr, (int) size);

      buf = malloc (size);
      if (buf == NULL)
	{
	  fprintf (stderr, "Failed to allocate buffer to hold program segment\n");
	  continue;
	}
      
      offset = p->p_offset;
      if (prog->iovec->bseek (prog, offset, SEEK_SET) != 0)
	{
	  fprintf (stderr, "Failed to seek to offset %lx\n", (long) offset);
	  continue;
	}
      if (prog->iovec->bread (prog, buf, size) != size)
	{
	  fprintf (stderr, "Failed to read %lx bytes\n", size);
	  continue;
	}

      mem_put_blk (base, buf, size);
      free (buf);
      if (highest_addr_loaded < base + size - 1 && size >= 4)
	highest_addr_loaded = base + size - 1;
    }

  free (phdrs);

  regs.r_pc = prog->start_address;

  if (strcmp (bfd_get_target (prog), "srec") == 0
      || regs.r_pc == 0)
    {
      regs.r_pc = mem_get_si (0xfffffffc);
      heaptop = heapbottom = 0;
    }

  if (verbose > 1)
    fprintf (stderr, "[start pc=%08x %s]\n",
	     (unsigned int) regs.r_pc,
	     rx_big_endian ? "BE" : "LE");
}
Example #14
0
/**
 * 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
}