SIM_RC
sim_create_inferior (SIM_DESC sd,
		     struct bfd *abfd,
		     char **argv,
		     char **envp)
{
  unsigned_word entry_point;
  TRACE(trace_gdb, ("sim_create_inferior(start_address=0x%x, ...)\n",
		    entry_point));

  if (simulator == NULL)
    error ("No program loaded");

  if (abfd != NULL)
    entry_point = bfd_get_start_address (abfd);
  else
    entry_point = 0xfff00000; /* ??? */

  psim_init(simulator);
  psim_stack(simulator, argv, envp);

  ASSERT (psim_write_register(simulator, -1 /* all start at same PC */,
			      &entry_point, "pc", cooked_transfer) > 0);
  return SIM_RC_OK;
}
Пример #2
0
void
print_section_info (struct target_ops *t, bfd *abfd)
{
  struct target_section *p;
  /* FIXME: 16 is not wide enough when gdbarch_addr_bit > 64.  */
  int wid = gdbarch_addr_bit (gdbarch_from_bfd (abfd)) <= 32 ? 8 : 16;

  printf_filtered ("\t`%s', ", bfd_get_filename (abfd));
  wrap_here ("        ");
  printf_filtered (_("file type %s.\n"), bfd_get_target (abfd));
  if (abfd == exec_bfd)
    printf_filtered (_("\tEntry point: %s\n"),
                     paddress (bfd_get_start_address (abfd)));
  for (p = t->to_sections; p < t->to_sections_end; p++)
    {
      printf_filtered ("\t%s", hex_string_custom (p->addr, wid));
      printf_filtered (" - %s", hex_string_custom (p->endaddr, wid));

      /* FIXME: A format of "08l" is not wide enough for file offsets
	 larger than 4GB.  OTOH, making it "016l" isn't desirable either
	 since most output will then be much wider than necessary.  It
	 may make sense to test the size of the file and choose the
	 format string accordingly.  */
      /* FIXME: i18n: Need to rewrite this sentence.  */
      if (info_verbose)
	printf_filtered (" @ %s",
			 hex_string_custom (p->the_bfd_section->filepos, 8));
      printf_filtered (" is %s", bfd_section_name (p->bfd, p->the_bfd_section));
      if (p->bfd != abfd)
	printf_filtered (" in %s", bfd_get_filename (p->bfd));
      printf_filtered ("\n");
    }
}
Пример #3
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);
}
Пример #4
0
static void
e7000_create_inferior (char *execfile, char *args, char **env)
{
  int entry_pt;

  if (args && *args)
    error ("Can't pass arguments to remote E7000DEBUG process");

  if (execfile == 0 || exec_bfd == 0)
    error ("No executable file specified");

  entry_pt = (int) bfd_get_start_address (exec_bfd);

#ifdef CREATE_INFERIOR_HOOK
  CREATE_INFERIOR_HOOK (0);	/* No process-ID */
#endif

  /* The "process" (board) is already stopped awaiting our commands, and
     the program is already downloaded.  We just set its PC and go.  */

  clear_proceed_status ();

  /* Tell wait_for_inferior that we've started a new process.  */
  init_wait_for_inferior ();

  /* Set up the "saved terminal modes" of the inferior
     based on what modes we are starting it with.  */
  target_terminal_init ();

  /* Install inferior's terminal modes.  */
  target_terminal_inferior ();

  /* insert_step_breakpoint ();  FIXME, do we need this?  */
  proceed ((CORE_ADDR) entry_pt, -1, 0);	/* Let 'er rip... */
}
Пример #5
0
static void
darwin_solib_get_all_image_info_addr_at_init (struct darwin_info *info)
{
  char *interp_name;
  CORE_ADDR load_addr = 0;
  bfd *dyld_bfd = NULL;
  struct cleanup *cleanup;

  /* This method doesn't work with an attached process.  */
  if (current_inferior ()->attach_flag)
    return;

  /* Find the program interpreter.  */
  interp_name = find_program_interpreter ();
  if (!interp_name)
    return;

  cleanup = make_cleanup (null_cleanup, NULL);

  /* Create a bfd for the interpreter.  */
  dyld_bfd = gdb_bfd_open (interp_name, gnutarget, -1);
  if (dyld_bfd)
    {
      bfd *sub;

      make_cleanup_bfd_unref (dyld_bfd);
      sub = gdb_bfd_mach_o_fat_extract
	(dyld_bfd, bfd_object, gdbarch_bfd_arch_info (target_gdbarch ()));
      if (sub)
	{
	  dyld_bfd = sub;
	  make_cleanup_bfd_unref (sub);
	}
      else
	dyld_bfd = NULL;
    }
  if (!dyld_bfd)
    {
      do_cleanups (cleanup);
      return;
    }

  /* We find the dynamic linker's base address by examining
     the current pc (which should point at the entry point for the
     dynamic linker) and subtracting the offset of the entry point.  */
  load_addr = (regcache_read_pc (get_current_regcache ())
               - bfd_get_start_address (dyld_bfd));

  /* Now try to set a breakpoint in the dynamic linker.  */
  info->all_image_addr =
    lookup_symbol_from_bfd (dyld_bfd, "_dyld_all_image_infos");

  do_cleanups (cleanup);

  if (info->all_image_addr == 0)
    return;

  info->all_image_addr += load_addr;
}
Пример #6
0
/// Returns the entry point of the loaded program (usually the same as the
/// program start address, but not always).
unsigned trap::ExecLoader::get_program_start() {
  if (this->exec_image == NULL && !this->plain_file) {
    THROW_ERROR("Binary parser was not created correctly.");
  }
  if (this->plain_file)
    return this->data_start;
  else
    return bfd_get_start_address(this->exec_image);
} // ExecLoader::get_program_start()
Пример #7
0
static int
sim_prepare_for_program (SIM_DESC sd, bfd* abfd)
{
  sim_cpu *cpu;
  int elf_flags = 0;

  cpu = STATE_CPU (sd, 0);

  if (abfd != NULL)
    {
      asection *s;

      if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
        elf_flags = elf_elfheader (abfd)->e_flags;

      cpu->cpu_elf_start = bfd_get_start_address (abfd);
      /* See if any section sets the reset address */
      cpu->cpu_use_elf_start = 1;
      for (s = abfd->sections; s && cpu->cpu_use_elf_start; s = s->next) 
        {
          if (s->flags & SEC_LOAD)
            {
              bfd_size_type size;

              size = bfd_get_section_size (s);
              if (size > 0)
                {
                  bfd_vma lma;

                  if (STATE_LOAD_AT_LMA_P (sd))
                    lma = bfd_section_lma (abfd, s);
                  else
                    lma = bfd_section_vma (abfd, s);

                  if (lma <= 0xFFFE && lma+size >= 0x10000)
                    cpu->cpu_use_elf_start = 0;
                }
            }
        }

      if (elf_flags & E_M68HC12_BANKS)
        {
          if (sim_get_bank_parameters (sd, abfd) != 0)
            sim_io_eprintf (sd, "Memory bank parameters are not initialized\n");
        }
    }

  if (!sim_hw_configure (sd))
    return SIM_RC_FAIL;

  /* reset all state information */
  sim_board_reset (sd);

  return SIM_RC_OK;
}
Пример #8
0
void
init_entry_point_info (struct objfile *objfile)
{
  /* Save startup file's range of PC addresses to help blockframe.c
     decide where the bottom of the stack is.  */

  if (bfd_get_file_flags (objfile->obfd) & EXEC_P)
    {
      /* Executable file -- record its entry point so we'll recognize
         the startup file because it contains the entry point.  */
      objfile->ei.entry_point = bfd_get_start_address (objfile->obfd);
    }
  else
    {
      /* Examination of non-executable.o files.  Short-circuit this stuff.  */
      objfile->ei.entry_point = INVALID_ENTRY_POINT;
    }
}
Пример #9
0
SIM_RC
sim_create_inferior (SIM_DESC sd,
		     struct bfd *prog_bfd,
		     char **argv,
		     char **env)
{
  memset (&State, 0, sizeof (State));
  if (prog_bfd != NULL) {
    PC = bfd_get_start_address (prog_bfd);
  } else {
    PC = 0;
  }
  CPU_PC_SET (STATE_CPU (sd, 0), (unsigned64) PC);

  if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_am33_2)
    PSW |= PSW_FE;

  return SIM_RC_OK;
}
Пример #10
0
void showStats()
{   
   (void)printf("Filename: %s\n\n", bfd_get_filename(abfd));
   (void)printf("File's target: %s\n", bfd_get_target(abfd));

   (void)printf("File's endianess: ");

   if (bfd_little_endian(abfd)) (void)printf("little endian\n");
   else (void)printf("big endian\n");
   
   (void)printf("Bits per byte on file's arch: %u bits\n",
                bfd_arch_bits_per_byte(abfd));

   (void)printf("Bits per address on file's arch: %u bits\n\n",
                bfd_arch_bits_per_address(abfd));

   (void)printf("Start address: %p\n", 
                (void *)bfd_get_start_address(abfd));

}
Пример #11
0
/* initialize bincode */
bincode_t *initialize_bincode(const char *file)
{
    bfd *abfd;
    bincode_t *bin;
    //char *target = "x86_64-unknown-linux-gnu";
    char *target = "i686-pc-linux-gnu";

    bfd_init();

    if (!bfd_set_default_target(target)) {
        bs_dbgmsg("  (!) bfd_set_default_target()\n");
        return NULL;
    }

    if ((abfd = bfd_openr(file, target)) == NULL) {
        bs_dbgmsg("  (!) bfd_openr(): %s\n", file);
        return NULL;
    }

    if (!bfd_check_format(abfd, bfd_object)) {
        bs_dbgmsg("  (!) bfd_check_format()\n");
        bfd_close(abfd);
        return NULL;
    }

    if((bin = malloc(sizeof(bincode_t))) == NULL) {
        bs_errmsg("  (!) malloc(): bin\n");
        exit(EXIT_FAILURE);
    }

    bin->filename = strdup(abfd->filename);
    bin->abfd = abfd;
    bin->filesize = bfd_get_size(abfd);
    bin->start_addr = bfd_get_start_address(abfd);
    init_disasm_info(bin->abfd, &bin->disasm_info);
    bin->disasm_info.application_data = bin;
    initialize_section(bin);

    return bin;
}
Пример #12
0
SIM_RC
sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
		     char **argv, char **env)
{
  SIM_CPU *cpu = STATE_CPU (sd, 0);
  SIM_ADDR addr;

  /* Set the PC.  */
  if (abfd != NULL)
    addr = bfd_get_start_address (abfd);
  else
    addr = 0;
  sim_pc_set (cpu, addr);

  /* Standalone mode (i.e. `bfin-...-run`) will take care of the argv
     for us in sim_open() -> sim_parse_args().  But in debug mode (i.e.
     'target sim' with `bfin-...-gdb`), we need to handle it.  */
  if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
    {
      freeargv (STATE_PROG_ARGV (sd));
      STATE_PROG_ARGV (sd) = dupargv (argv);
    }

  switch (STATE_ENVIRONMENT (sd))
    {
    case USER_ENVIRONMENT:
      bfin_user_init (sd, cpu, abfd, (void *)argv, (void *)env);
      break;
    case OPERATING_ENVIRONMENT:
      bfin_os_init (sd, cpu, (void *)argv);
      break;
    default:
      bfin_virtual_init (sd, cpu);
      break;
    }

  return SIM_RC_OK;
}
Пример #13
0
void
print_section_info (struct target_ops *t, bfd *abfd)
{
  struct section_table *p;
  /* FIXME: "016l" is not wide enough when TARGET_ADDR_BIT > 64.  */
  char *fmt = TARGET_ADDR_BIT <= 32 ? "08l" : "016l";

  printf_filtered ("\t`%s', ", bfd_get_filename (abfd));
  wrap_here ("        ");
  printf_filtered ("file type %s.\n", bfd_get_target (abfd));
  if (abfd == exec_bfd)
    {
      printf_filtered ("\tEntry point: ");
      print_address_numeric (bfd_get_start_address (abfd), 1, gdb_stdout);
      printf_filtered ("\n");
    }
  for (p = t->to_sections; p < t->to_sections_end; p++)
    {
      printf_filtered ("\t%s", local_hex_string_custom (p->addr, fmt));
      printf_filtered (" - %s", local_hex_string_custom (p->endaddr, fmt));

      /* FIXME: A format of "08l" is not wide enough for file offsets
	 larger than 4GB.  OTOH, making it "016l" isn't desirable either
	 since most output will then be much wider than necessary.  It
	 may make sense to test the size of the file and choose the
	 format string accordingly.  */
      if (info_verbose)
	printf_filtered (" @ %s",
			 local_hex_string_custom (p->the_bfd_section->filepos, "08l"));
      printf_filtered (" is %s", bfd_section_name (p->bfd, p->the_bfd_section));
      if (p->bfd != abfd)
	{
	  printf_filtered (" in %s", bfd_get_filename (p->bfd));
	}
      printf_filtered ("\n");
    }
}
Пример #14
0
static os_emul_data *
emul_netbsd_create(device *root,
		   bfd *image,
		   const char *name)
{
  unsigned_word top_of_stack;
  unsigned stack_size;
  int elf_binary;
  os_emul_data *bsd_data;
  device *vm;
  char *filename;

  /* check that this emulation is really for us */
  if (name != NULL && strcmp(name, "netbsd") != 0)
    return NULL;
  if (image == NULL)
    return NULL;


  /* merge any emulation specific entries into the device tree */

  /* establish a few defaults */
  if (image->xvec->flavour == bfd_target_elf_flavour) {
    elf_binary = 1;
    top_of_stack = 0xe0000000;
    stack_size =   0x00100000;
  }
  else {
    elf_binary = 0;
    top_of_stack = 0x20000000;
    stack_size =   0x00100000;
  }

  /* options */
  emul_add_tree_options(root, image, "netbsd",
			(WITH_ENVIRONMENT == USER_ENVIRONMENT
			 ? "user" : "virtual"),
			0 /*oea-interrupt-prefix*/);

  /* virtual memory - handles growth of stack/heap */
  vm = tree_parse(root, "/openprom/vm");
  tree_parse(vm, "./stack-base 0x%lx",
	     (unsigned long)(top_of_stack - stack_size));
  tree_parse(vm, "./nr-bytes 0x%x", stack_size);

  filename = tree_quote_property (bfd_get_filename(image));
  tree_parse(root, "/openprom/vm/map-binary/file-name %s",
	     filename);
  free (filename);

  /* finish the init */
  tree_parse(root, "/openprom/init/register/pc 0x%lx",
	     (unsigned long)bfd_get_start_address(image));
  tree_parse(root, "/openprom/init/register/sp 0x%lx",
	     (unsigned long)top_of_stack);
  tree_parse(root, "/openprom/init/register/msr 0x%x",
	     ((tree_find_boolean_property(root, "/options/little-endian?")
	       ? msr_little_endian_mode
	       : 0)
	      | (tree_find_boolean_property(root, "/openprom/options/floating-point?")
		 ? (msr_floating_point_available
		    | msr_floating_point_exception_mode_0
		    | msr_floating_point_exception_mode_1)
		 : 0)));
  tree_parse(root, "/openprom/init/stack/stack-type %s",
	     (elf_binary ? "ppc-elf" : "ppc-xcoff"));

  /* finally our emulation data */
  bsd_data = ZALLOC(os_emul_data);
  bsd_data->vm = vm;
  bsd_data->syscalls = &emul_netbsd_syscalls;
  return bsd_data;
}
Пример #15
0
static void
bfin_user_init (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd,
		const char * const *argv, const char * const *env)
{
  /* XXX: Missing host -> target endian ...  */
  /* Linux starts the user app with the stack:
       argc
       argv[0]          -- pointers to the actual strings
       argv[1..N]
       NULL
       env[0]
       env[1..N]
       NULL
       auxvt[0].type    -- ELF Auxiliary Vector Table
       auxvt[0].value
       auxvt[1..N]
       AT_NULL
       0
       argv[0..N][0..M] -- actual argv/env strings
       env[0..N][0..M]
       FDPIC loadmaps   -- for FDPIC apps
     So set things up the same way.  */
  int i, argc, envc;
  bu32 argv_flat, env_flat;

  bu32 sp, sp_flat;

  /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic  */
  bu32 elf_addrs[6];
  bu32 auxvt;
  bu32 exec_loadmap, ldso_loadmap;
  char *ldso_path;

  unsigned char null[4] = { 0, 0, 0, 0 };

  host_callback *cb = STATE_CALLBACK (sd);

  elf_addrs[0] = elf_addrs[4] = bfd_get_start_address (abfd);
  elf_addrs[1] = elf_addrs[2] = elf_addrs[3] = elf_addrs[5] = 0;

  /* Keep the load addresses consistent between runs.  Also make sure we make
     space for the fixed code region (part of the Blackfin Linux ABI).  */
  fdpic_load_offset = 0x1000;

  /* First try to load this as an FDPIC executable.  */
  sp = SPREG;
  if (!bfin_fdpic_load (sd, cpu, STATE_PROG_BFD (sd), &sp, elf_addrs, &ldso_path))
    goto skip_fdpic_init;
  exec_loadmap = sp;

  /* If that worked, then load the fixed code region.  We only do this for
     FDPIC ELFs atm because they are PIEs and let us relocate them without
     manual fixups.  FLAT files however require location processing which
     we do not do ourselves, and they link with a VMA of 0.  */
  sim_write (sd, 0x400, bfin_linux_fixed_code, sizeof (bfin_linux_fixed_code));

  /* If the FDPIC needs an interpreter, then load it up too.  */
  if (ldso_path)
    {
      const char *ldso_full_path = concat (simulator_sysroot, ldso_path, NULL);
      struct bfd *ldso_bfd;

      ldso_bfd = bfd_openr (ldso_full_path, STATE_TARGET (sd));
      if (!ldso_bfd)
	{
	  sim_io_eprintf (sd, "bfin-sim: bfd open failed: %s\n", ldso_full_path);
	  goto static_fdpic;
	}
      if (!bfd_check_format (ldso_bfd, bfd_object))
	sim_io_eprintf (sd, "bfin-sim: bfd format not valid: %s\n", ldso_full_path);
      bfd_set_arch_info (ldso_bfd, STATE_ARCHITECTURE (sd));

      if (!bfin_fdpic_load (sd, cpu, ldso_bfd, &sp, elf_addrs, &ldso_path))
	sim_io_eprintf (sd, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path);
      if (ldso_path)
	sim_io_eprintf (sd, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
			ldso_full_path, ldso_path);

      ldso_loadmap = sp;
    }
  else
 static_fdpic:
    ldso_loadmap = 0;

  /* Finally setup the registers required by the FDPIC ABI.  */
  SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up.  */
  SET_PREG (0, exec_loadmap); /* Exec loadmap addr.  */
  SET_PREG (1, ldso_loadmap); /* Interp loadmap addr.  */
  SET_PREG (2, elf_addrs[5]); /* PT_DYNAMIC map addr.  */

  auxvt = 1;
  SET_SPREG (sp);
 skip_fdpic_init:
  sim_pc_set (cpu, elf_addrs[0]);

  /* Figure out how much storage the argv/env strings need.  */
  argc = count_argc (argv);
  if (argc == -1)
    argc = 0;
  argv_flat = argc; /* NUL bytes  */
  for (i = 0; i < argc; ++i)
    argv_flat += strlen (argv[i]);

  if (!env)
    env = simple_env;
  envc = count_argc (env);
  env_flat = envc; /* NUL bytes  */
  for (i = 0; i < envc; ++i)
    env_flat += strlen (env[i]);

  /* Push the Auxiliary Vector Table between argv/env and actual strings.  */
  sp_flat = sp = ALIGN (SPREG - argv_flat - env_flat - 4, 4);
  if (auxvt)
    {
# define AT_PUSH(at, val) \
  auxvt_size += 8; \
  sp -= 4; \
  auxvt = (val); \
  sim_write (sd, sp, (void *)&auxvt, 4); \
  sp -= 4; \
  auxvt = (at); \
  sim_write (sd, sp, (void *)&auxvt, 4)
      unsigned int egid = getegid (), gid = getgid ();
      unsigned int euid = geteuid (), uid = getuid ();
      bu32 auxvt_size = 0;
      AT_PUSH (AT_NULL, 0);
      AT_PUSH (AT_SECURE, egid != gid || euid != uid);
      AT_PUSH (AT_EGID, egid);
      AT_PUSH (AT_GID, gid);
      AT_PUSH (AT_EUID, euid);
      AT_PUSH (AT_UID, uid);
      AT_PUSH (AT_ENTRY, elf_addrs[4]);
      AT_PUSH (AT_FLAGS, 0);
      AT_PUSH (AT_BASE, elf_addrs[3]);
      AT_PUSH (AT_PHNUM, elf_addrs[2]);
      AT_PUSH (AT_PHENT, sizeof (Elf32_External_Phdr));
      AT_PUSH (AT_PHDR, elf_addrs[1]);
      AT_PUSH (AT_CLKTCK, 100); /* XXX: This ever not 100 ?  */
      AT_PUSH (AT_PAGESZ, 4096);
      AT_PUSH (AT_HWCAP, 0);
#undef AT_PUSH
    }
  SET_SPREG (sp);

  /* Push the argc/argv/env after the auxvt.  */
  sp -= ((1 + argc + 1 + envc + 1) * 4);
  SET_SPREG (sp);

  /* First push the argc value.  */
  sim_write (sd, sp, (void *)&argc, 4);
  sp += 4;

  /* Then the actual argv strings so we know where to point argv[].  */
  for (i = 0; i < argc; ++i)
    {
      unsigned len = strlen (argv[i]) + 1;
      sim_write (sd, sp_flat, (void *)argv[i], len);
      sim_write (sd, sp, (void *)&sp_flat, 4);
      sp_flat += len;
      sp += 4;
    }
  sim_write (sd, sp, null, 4);
  sp += 4;

  /* Then the actual env strings so we know where to point env[].  */
  for (i = 0; i < envc; ++i)
    {
      unsigned len = strlen (env[i]) + 1;
      sim_write (sd, sp_flat, (void *)env[i], len);
      sim_write (sd, sp, (void *)&sp_flat, 4);
      sp_flat += len;
      sp += 4;
    }

  /* Set some callbacks.  */
  cb->syscall_map = cb_linux_syscall_map;
  cb->errno_map = cb_linux_errno_map;
  cb->open_map = cb_linux_open_map;
  cb->signal_map = cb_linux_signal_map;
  cb->stat_map = stat_map_32 = cb_linux_stat_map_32;
  stat_map_64 = cb_linux_stat_map_64;
}
Пример #16
0
static bool
bfin_fdpic_load (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd, bu32 *sp,
		 bu32 *elf_addrs, char **ldso_path)
{
  bool ret;
  int i;

  Elf_Internal_Ehdr *iehdr;
  Elf32_External_Ehdr ehdr;
  Elf_Internal_Phdr *phdrs;
  unsigned char *data;
  long phdr_size;
  int phdrc;
  bu32 nsegs;

  bu32 max_load_addr;

  unsigned char null[4] = { 0, 0, 0, 0 };

  ret = false;
  *ldso_path = NULL;

  /* See if this an FDPIC ELF.  */
  phdrs = NULL;
  if (!abfd)
    goto skip_fdpic_init;
  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
    goto skip_fdpic_init;
  if (bfd_bread (&ehdr, sizeof (ehdr), abfd) != sizeof (ehdr))
    goto skip_fdpic_init;
  iehdr = elf_elfheader (abfd);
  if (!(iehdr->e_flags & EF_BFIN_FDPIC))
    goto skip_fdpic_init;

  if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
    sim_io_printf (sd, "Loading FDPIC ELF %s\n Load base: %#x\n ELF entry: %#x\n",
		   bfd_get_filename (abfd), fdpic_load_offset, elf_addrs[0]);

  /* Grab the Program Headers to set up the loadsegs on the stack.  */
  phdr_size = bfd_get_elf_phdr_upper_bound (abfd);
  if (phdr_size == -1)
    goto skip_fdpic_init;
  phdrs = xmalloc (phdr_size);
  phdrc = bfd_get_elf_phdrs (abfd, phdrs);
  if (phdrc == -1)
    goto skip_fdpic_init;

  /* Push the Ehdr onto the stack.  */
  *sp -= sizeof (ehdr);
  elf_addrs[3] = *sp;
  sim_write (sd, *sp, (void *)&ehdr, sizeof (ehdr));
  if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
    sim_io_printf (sd, " Elf_Ehdr: %#x\n", *sp);

  /* Since we're relocating things ourselves, we need to relocate
     the start address as well.  */
  elf_addrs[0] = bfd_get_start_address (abfd) + fdpic_load_offset;

  /* And the Exec's Phdrs onto the stack.  */
  if (STATE_PROG_BFD (sd) == abfd)
    {
      elf_addrs[4] = elf_addrs[0];

      phdr_size = iehdr->e_phentsize * iehdr->e_phnum;
      if (bfd_seek (abfd, iehdr->e_phoff, SEEK_SET) != 0)
	goto skip_fdpic_init;
      data = xmalloc (phdr_size);
      if (bfd_bread (data, phdr_size, abfd) != phdr_size)
	goto skip_fdpic_init;
      *sp -= phdr_size;
      elf_addrs[1] = *sp;
      elf_addrs[2] = phdrc;
      sim_write (sd, *sp, data, phdr_size);
      free (data);
      if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
	sim_io_printf (sd, " Elf_Phdrs: %#x\n", *sp);
    }

  /* Now push all the loadsegs.  */
  nsegs = 0;
  max_load_addr = 0;
  for (i = phdrc; i >= 0; --i)
    if (phdrs[i].p_type == PT_LOAD)
      {
	Elf_Internal_Phdr *p = &phdrs[i];
	bu32 paddr, vaddr, memsz, filesz;

	paddr = p->p_paddr + fdpic_load_offset;
	vaddr = p->p_vaddr;
	memsz = p->p_memsz;
	filesz = p->p_filesz;

	if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
	  sim_io_printf (sd, " PHDR %i: vma %#x lma %#x filesz %#x memsz %#x\n",
			 i, vaddr, paddr, filesz, memsz);

	data = xmalloc (memsz);
	if (memsz != filesz)
	  memset (data + filesz, 0, memsz - filesz);

	if (bfd_seek (abfd, p->p_offset, SEEK_SET) == 0
	    && bfd_bread (data, filesz, abfd) == filesz)
	  sim_write (sd, paddr, data, memsz);

	free (data);

	max_load_addr = MAX (paddr + memsz, max_load_addr);

	*sp -= 12;
	sim_write (sd, *sp+0, (void *)&paddr, 4); /* loadseg.addr  */
	sim_write (sd, *sp+4, (void *)&vaddr, 4); /* loadseg.p_vaddr  */
	sim_write (sd, *sp+8, (void *)&memsz, 4); /* loadseg.p_memsz  */
	++nsegs;
      }
    else if (phdrs[i].p_type == PT_DYNAMIC)
      {
	elf_addrs[5] = phdrs[i].p_paddr + fdpic_load_offset;
	if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
	  sim_io_printf (sd, " PT_DYNAMIC: %#x\n", elf_addrs[5]);
      }
    else if (phdrs[i].p_type == PT_INTERP)
      {
	uint32_t off = phdrs[i].p_offset;
	uint32_t len = phdrs[i].p_filesz;

	*ldso_path = xmalloc (len);
	if (bfd_seek (abfd, off, SEEK_SET) != 0
	    || bfd_bread (*ldso_path, len, abfd) != len)
	  {
	    free (*ldso_path);
	    *ldso_path = NULL;
	  }
	else if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
	  sim_io_printf (sd, " PT_INTERP: %s\n", *ldso_path);
      }

  /* Update the load offset with a few extra pages.  */
  fdpic_load_offset = ALIGN (MAX (max_load_addr, fdpic_load_offset), 0x10000);
  fdpic_load_offset += 0x10000;

  /* Push the summary loadmap info onto the stack last.  */
  *sp -= 4;
  sim_write (sd, *sp+0, null, 2); /* loadmap.version  */
  sim_write (sd, *sp+2, (void *)&nsegs, 2); /* loadmap.nsegs  */

  ret = true;
 skip_fdpic_init:
  free (phdrs);

  return ret;
}
Пример #17
0
static bfd_boolean
MY (write_object_contents) (bfd * abfd)
{
  struct external_exec exec_bytes;
  struct internal_exec *execp = exec_hdr (abfd);
  bfd_size_type text_size;	/* dummy vars */
  file_ptr text_end;

  memset (&exec_bytes, 0, sizeof (exec_bytes));

  obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;

  if (adata (abfd).magic == undecided_magic)
    NAME (aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end);
  execp->a_syms = 0;

  execp->a_entry = bfd_get_start_address (abfd);

  execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *
		     obj_reloc_entry_size (abfd));
  execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *
		     obj_reloc_entry_size (abfd));

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

  NAME (aout,swap_exec_header_out) (abfd, execp, &exec_bytes);

  /* update fields not covered by default swap_exec_header_out */

  /* this is really the sym table size but we store it in drelocs */
  H_PUT_32 (abfd, (bfd_get_symcount (abfd) * 12), exec_bytes.e_drelocs);

  if (bfd_seek (abfd, (file_ptr) 0, FALSE) != 0
      || (bfd_bwrite (&exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, abfd)
	  != EXEC_BYTES_SIZE))
    return FALSE;

  /* Write out the symbols, and then the relocs.  We must write out
       the symbols first so that we know the symbol indices.  */

  if (bfd_get_symcount (abfd) != 0)
    {
      /* Skip the relocs to where we want to put the symbols.  */
      if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*execp) + execp->a_drsize),
		    SEEK_SET) != 0)
	return FALSE;
    }

  if (!MY (write_syms) (abfd))
    return FALSE;

  if (bfd_get_symcount (abfd) != 0)
    {
      if (bfd_seek (abfd, (file_ptr) N_TRELOFF (*execp), SEEK_CUR) != 0)
	return FALSE;
      if (!NAME (aout,squirt_out_relocs) (abfd, obj_textsec (abfd)))
	return FALSE;
      if (bfd_seek (abfd, (file_ptr) N_DRELOFF (*execp), SEEK_CUR) != 0)
	return FALSE;
      if (!NAME (aout,squirt_out_relocs) (abfd, obj_datasec (abfd)))
	return FALSE;
    }

  return TRUE;
}
Пример #18
0
/* load program text and initialized data into simulated virtual memory
   space and initialize program segment range variables */
void
ld_load_prog(char *fname,		/* program to load */
	     int argc, char **argv,	/* simulated program cmd line args */
	     char **envp,		/* simulated program environment */
	     struct regs_t *regs,	/* registers to initialize for load */
	     struct mem_t *mem,		/* memory space to load prog into */
	     int zero_bss_segs)		/* zero uninit data segment? */
{
  int i;
  qword_t temp;
  md_addr_t sp, data_break = 0, null_ptr = 0, argv_addr, envp_addr;

  if (eio_valid(fname))
    {
      if (argc != 1)
	{
	  fprintf(stderr, "error: EIO file has arguments\n");
	  exit(1);
	}

      fprintf(stderr, "sim: loading EIO file: %s\n", fname);

      sim_eio_fname = mystrdup(fname);

      /* open the EIO file stream */
      sim_eio_fd = eio_open(fname);

      /* load initial state checkpoint */
      if (eio_read_chkpt(regs, mem, sim_eio_fd) != -1)
	fatal("bad initial checkpoint in EIO file");

      /* load checkpoint? */
      if (sim_chkpt_fname != NULL)
	{
	  counter_t restore_icnt;

	  FILE *chkpt_fd;

	  fprintf(stderr, "sim: loading checkpoint file: %s\n",
		  sim_chkpt_fname);

	  if (!eio_valid(sim_chkpt_fname))
	    fatal("file `%s' does not appear to be a checkpoint file",
		  sim_chkpt_fname);

	  /* open the checkpoint file */
	  chkpt_fd = eio_open(sim_chkpt_fname);

	  /* load the state image */
	  restore_icnt = eio_read_chkpt(regs, mem, chkpt_fd);

	  /* fast forward the baseline EIO trace to checkpoint location */
	  myfprintf(stderr, "sim: fast forwarding to instruction %n\n",
		    restore_icnt);
	  eio_fast_forward(sim_eio_fd, restore_icnt);
	}

      /* computed state... */
      ld_environ_base = regs->regs_R[MD_REG_SP];
      ld_prog_entry = regs->regs_PC;

      /* fini... */
      return;
    }
#ifdef MD_CROSS_ENDIAN
  else
    {
      warn("endian of `%s' does not match host", fname);
      warn("running with experimental cross-endian execution support");
      warn("****************************************");
      warn("**>> please check results carefully <<**");
      warn("****************************************");
#if 0
      fatal("SimpleScalar/Alpha only supports binary execution on\n"
	    "       little-endian hosts, use EIO files on big-endian hosts");
#endif
    }
#endif /* MD_CROSS_ENDIAN */

  if (sim_chkpt_fname != NULL)
    fatal("checkpoints only supported while EIO tracing");

#ifdef BFD_LOADER

  {
    bfd *abfd;
    asection *sect;

    /* set up a local stack pointer, this is where the argv and envp
       data is written into program memory */
    ld_stack_base = MD_STACK_BASE;
    sp = ROUND_DOWN(MD_STACK_BASE - MD_MAX_ENVIRON, sizeof(MD_DOUBLE_TYPE));
    ld_stack_size = ld_stack_base - sp;
    printf("Thread 0 stack size (3)%d\n",  current->ld_stack_size);

    /* initial stack pointer value */
    ld_environ_base = sp;

    /* load the program into memory, try both endians */
    if (!(abfd = bfd_openr(argv[0], "ss-coff-big")))
      if (!(abfd = bfd_openr(argv[0], "ss-coff-little")))
	fatal("cannot open executable `%s'", argv[0]);

    /* this call is mainly for its side effect of reading in the sections.
       we follow the traditional behavior of `strings' in that we don't
       complain if we don't recognize a file to be an object file.  */
    if (!bfd_check_format(abfd, bfd_object))
      {
	bfd_close(abfd);
	fatal("cannot open executable `%s'", argv[0]);
      }

    /* record profile file name */
    ld_prog_fname = argv[0];

    /* record endian of target */
    ld_target_big_endian = abfd->xvec->byteorder_big_p;

    debug("processing %d sections in `%s'...",
	  bfd_count_sections(abfd), argv[0]);

    /* read all sections in file */
    for (sect=abfd->sections; sect; sect=sect->next)
      {
	char *p;

	debug("processing section `%s', %d bytes @ 0x%08x...",
	      bfd_section_name(abfd, sect), bfd_section_size(abfd, sect),
	      bfd_section_vma(abfd, sect));

	/* read the section data, if allocated and loadable and non-NULL */
	if ((bfd_get_section_flags(abfd, sect) & SEC_ALLOC)
	    && (bfd_get_section_flags(abfd, sect) & SEC_LOAD)
	    && bfd_section_vma(abfd, sect)
	    && bfd_section_size(abfd, sect))
	  {
	    /* allocate a section buffer */
	    p = calloc(bfd_section_size(abfd, sect), sizeof(char));
	    if (!p)
	      fatal("cannot allocate %d bytes for section `%s'",
		    bfd_section_size(abfd, sect),
		    bfd_section_name(abfd, sect));

	    if (!bfd_get_section_contents(abfd, sect, p, (file_ptr)0,
					  bfd_section_size(abfd, sect)))
	      fatal("could not read entire `%s' section from executable",
		    bfd_section_name(abfd, sect));

	    /* copy program section it into simulator target memory */
	    mem_bcopy(mem_fn, Write, bfd_section_vma(abfd, sect),
		      p, bfd_section_size(abfd, sect));

	    /* release the section buffer */
	    free(p);
	  }
	/* zero out the section if it is loadable but not allocated in exec */
	else if (zero_bss_segs
		 && (bfd_get_section_flags(abfd, sect) & SEC_LOAD)
		 && bfd_section_vma(abfd, sect)
		 && bfd_section_size(abfd, sect))
	  {
	    /* zero out the section region */
	    mem_bzero(mem_fn,
		      bfd_section_vma(abfd, sect),
		      bfd_section_size(abfd, sect));
	  }
	else
	  {
	    /* else do nothing with this section, it's probably debug data */
	    debug("ignoring section `%s' during load...",
		  bfd_section_name(abfd, sect));
	  }

	/* expected text section */
	if (!strcmp(bfd_section_name(abfd, sect), ".text"))
	  {
	    /* .text section processing */
	    ld_text_size =
	      ((bfd_section_vma(abfd, sect) + bfd_section_size(abfd, sect))
	       - MD_TEXT_BASE)
		+ /* for speculative fetches/decodes */TEXT_TAIL_PADDING;

	    /* create tail padding and copy into simulator target memory */
#if 0
	    mem_bzero(mem_fn,
		      bfd_section_vma(abfd, sect)
		      + bfd_section_size(abfd, sect),
		      TEXT_TAIL_PADDING);
#endif
	  }
	/* expected data sections */
	else if (!strcmp(bfd_section_name(abfd, sect), ".rdata")
		 || !strcmp(bfd_section_name(abfd, sect), ".data")
		 || !strcmp(bfd_section_name(abfd, sect), ".sdata")
		 || !strcmp(bfd_section_name(abfd, sect), ".bss")
		 || !strcmp(bfd_section_name(abfd, sect), ".sbss"))
	  {
	    /* data section processing */
	    if (bfd_section_vma(abfd, sect) + bfd_section_size(abfd, sect) >
		data_break)
	      data_break = (bfd_section_vma(abfd, sect) +
			    bfd_section_size(abfd, sect));
	  }
	else
	  {
	    /* what is this section??? */
	    fatal("encountered unknown section `%s', %d bytes @ 0x%08x",
		  bfd_section_name(abfd, sect), bfd_section_size(abfd, sect),
		  bfd_section_vma(abfd, sect));
	  }
      }

    /* compute data segment size from data break point */
    ld_text_base = MD_TEXT_BASE;
    ld_data_base = MD_DATA_BASE;
    ld_prog_entry = bfd_get_start_address(abfd);
    ld_data_size = data_break - ld_data_base;

    /* done with the executable, close it */
    if (!bfd_close(abfd))
      fatal("could not close executable `%s'", argv[0]);
  }

#else /* !BFD_LOADER, i.e., standalone loader */

  {
    FILE *fobj;
    long floc;
    struct ecoff_filehdr fhdr;
    struct ecoff_aouthdr ahdr;
    struct ecoff_scnhdr shdr;

    /* record profile file name */
    ld_prog_fname = argv[0];

    /* load the program into memory, try both endians */
#if defined(__CYGWIN32__) || defined(_MSC_VER)
    fobj = fopen(argv[0], "rb");
#else
    fobj = fopen(argv[0], "r");
#endif
    if (!fobj)
      fatal("cannot open executable `%s'", argv[0]);

    if (fread(&fhdr, sizeof(struct ecoff_filehdr), 1, fobj) < 1)
      fatal("cannot read header from executable `%s'", argv[0]);

    /* record endian of target */
    if (fhdr.f_magic == MD_SWAPH(ECOFF_ALPHAMAGIC))
      ld_target_big_endian = FALSE;
    else if (fhdr.f_magic == MD_SWAPH(ECOFF_EB_MAGIC)
	     || fhdr.f_magic == MD_SWAPH(ECOFF_EL_MAGIC)
	     || fhdr.f_magic == MD_SWAPH(ECOFF_EB_OTHER)
	     || fhdr.f_magic == MD_SWAPH(ECOFF_EL_OTHER))
      fatal("Alpha simulator cannot run PISA binary `%s'", argv[0]);
    else
      fatal("bad magic number in executable `%s' (not an executable)",
	    argv[0]);

    if (fread(&ahdr, sizeof(struct ecoff_aouthdr), 1, fobj) < 1)
      fatal("cannot read AOUT header from executable `%s'", argv[0]);

    ld_text_base = MD_SWAPQ(ahdr.text_start);
    ld_text_size = MD_SWAPQ(ahdr.tsize);
    ld_prog_entry = MD_SWAPQ(ahdr.entry);
    ld_data_base = MD_SWAPQ(ahdr.data_start);
    ld_data_size = MD_SWAPQ(ahdr.dsize) + MD_SWAPQ(ahdr.bsize);
    regs->regs_R[MD_REG_GP] = MD_SWAPQ(ahdr.gp_value);

    /* compute data segment size from data break point */
    data_break = ld_data_base + ld_data_size;

    /* seek to the beginning of the first section header, the file header comes
       first, followed by the optional header (this is the aouthdr), the size
       of the aouthdr is given in Fdhr.f_opthdr */
    fseek(fobj, sizeof(struct ecoff_filehdr) + MD_SWAPH(fhdr.f_opthdr), 0);

    debug("processing %d sections in `%s'...",
	  MD_SWAPH(fhdr.f_nscns), argv[0]);

    /* loop through the section headers */
    floc = ftell(fobj);
    for (i = 0; i < MD_SWAPH(fhdr.f_nscns); i++)
      {
	char *p;

	if (fseek(fobj, floc, 0) == -1)
	  fatal("could not reset location in executable");
	if (fread(&shdr, sizeof(struct ecoff_scnhdr), 1, fobj) < 1)
	  fatal("could not read section %d from executable", i);
	floc = ftell(fobj);

	switch (MD_SWAPW(shdr.s_flags))
	  {
	  case ECOFF_STYP_TEXT:
	    p = calloc(MD_SWAPQ(shdr.s_size), sizeof(char));
	    if (!p)
	      fatal("out of virtual memory");

	    if (fseek(fobj, MD_SWAPQ(shdr.s_scnptr), 0) == -1)
	      fatal("could not read `.text' from executable", i);
	    if (fread(p, MD_SWAPQ(shdr.s_size), 1, fobj) < 1)
	      fatal("could not read text section from executable");

	    /* copy program section into simulator target memory */
	    mem_bcopy(mem_access, mem, Write,
		      MD_SWAPQ(shdr.s_vaddr), p, MD_SWAPQ(shdr.s_size));

#if 0
	    /* create tail padding and copy into simulator target memory */
	    mem_bzero(mem_access, mem,
		      MD_SWAPQ(shdr.s_vaddr) + MD_SWAPQ(shdr.s_size),
		      TEXT_TAIL_PADDING);
#endif

	    /* release the section buffer */
	    free(p);

#if 0
	    Text_seek = MD_SWAPQ(shdr.s_scnptr);
	    Text_start = MD_SWAPQ(shdr.s_vaddr);
	    Text_size = MD_SWAPQ(shdr.s_size) / 4;
	    /* there is a null routine after the supposed end of text */
	    Text_size += 10;
	    Text_end = Text_start + Text_size * 4;
	    /* create_text_reloc(shdr.s_relptr, shdr.s_nreloc); */
#endif
	    break;

	  case ECOFF_STYP_INIT:
	  case ECOFF_STYP_FINI:
	    if (MD_SWAPQ(shdr.s_size) > 0)
	      {
		p = calloc(MD_SWAPQ(shdr.s_size), sizeof(char));
		if (!p)
		  fatal("out of virtual memory");

		if (fseek(fobj, MD_SWAPQ(shdr.s_scnptr), 0) == -1)
		  fatal("could not read `.text' from executable", i);
		if (fread(p, MD_SWAPQ(shdr.s_size), 1, fobj) < 1)
		  fatal("could not read text section from executable");
		
		/* copy program section into simulator target memory */
		mem_bcopy(mem_access, mem,
			  Write, MD_SWAPQ(shdr.s_vaddr),
			  p, MD_SWAPQ(shdr.s_size));

		/* release the section buffer */
		free(p);
	      }
	    else
	      warn("section `%s' is empty...", shdr.s_name);
	    break;

	  case ECOFF_STYP_LITA:
	  case ECOFF_STYP_LIT8:
	  case ECOFF_STYP_LIT4:
	  case ECOFF_STYP_XDATA:
	  case ECOFF_STYP_PDATA:
	  case ECOFF_STYP_RCONST:
	    /* fall through */

	  case ECOFF_STYP_RDATA:
	    /* The .rdata section is sometimes placed before the text
	     * section instead of being contiguous with the .data section.
	     */
#if 0
	    Rdata_start = MD_SWAPQ(shdr.s_vaddr);
	    Rdata_size = MD_SWAPQ(shdr.s_size);
	    Rdata_seek = MD_SWAPQ(shdr.s_scnptr);
#endif
	    /* fall through */
	  case ECOFF_STYP_DATA:
#if 0
	    Data_seek = MD_SWAPQ(shdr.s_scnptr);
#endif
	    /* fall through */
	  case ECOFF_STYP_SDATA:
#if 0
	    Sdata_seek = MD_SWAPQ(shdr.s_scnptr);
#endif
	    if (MD_SWAPQ(shdr.s_size) > 0)
	      {
		p = calloc(MD_SWAPQ(shdr.s_size), sizeof(char));
		if (!p)
		  fatal("out of virtual memory");

		if (fseek(fobj, MD_SWAPQ(shdr.s_scnptr), 0) == -1)
		  fatal("could not read `.text' from executable", i);
		if (fread(p, MD_SWAPQ(shdr.s_size), 1, fobj) < 1)
		  fatal("could not read text section from executable");

		/* copy program section it into simulator target memory */
		mem_bcopy(mem_access, mem,
			  Write, MD_SWAPQ(shdr.s_vaddr),
			  p, MD_SWAPQ(shdr.s_size));

		/* release the section buffer */
		free(p);
	      }
	    else
	      warn("section `%s' is empty...", shdr.s_name);
	  break;

	  case ECOFF_STYP_BSS:
	  case ECOFF_STYP_SBSS:
	    /* no data to read... */
	    break;

	  default:
	    warn("section `%s' ignored...", shdr.s_name);
	  }
      }

    /* done with the executable, close it */
    if (fclose(fobj))
      fatal("could not close executable `%s'", argv[0]);
  }

#endif /* BFD_LOADER */

  /* perform sanity checks on segment ranges */
  if (!ld_text_base || !ld_text_size)
    fatal("executable is missing a `.text' section");
  if (!ld_data_base || !ld_data_size)
    fatal("executable is missing a `.data' section");
  if (!ld_prog_entry)
    fatal("program entry point not specified");

  /* determine byte/words swapping required to execute on this host */
  sim_swap_bytes = (endian_host_byte_order() != endian_target_byte_order());
  if (sim_swap_bytes)
    {
#if 0 /* FIXME: disabled until further notice... */
      /* cross-endian is never reliable, why this is so is beyond the scope
	 of this comment, e-mail me for details... */
      fprintf(stderr, "sim: *WARNING*: swapping bytes to match host...\n");
      fprintf(stderr, "sim: *WARNING*: swapping may break your program!\n");
      /* #else */
      fatal("binary endian does not match host endian");
#endif
    }
  sim_swap_words = (endian_host_word_order() != endian_target_word_order());
  if (sim_swap_words)
    {
#if 0 /* FIXME: disabled until further notice... */
      /* cross-endian is never reliable, why this is so is beyond the scope
	 of this comment, e-mail me for details... */
      fprintf(stderr, "sim: *WARNING*: swapping words to match host...\n");
      fprintf(stderr, "sim: *WARNING*: swapping may break your program!\n");
      /* #else */
      fatal("binary endian does not match host endian");
#endif
    }

  /* set up a local stack pointer, this is where the argv and envp
     data is written into program memory */
  ld_stack_base = ld_text_base - (409600+4096);
#if 0
  sp = ROUND_DOWN(ld_stack_base - MD_MAX_ENVIRON, sizeof(MD_DOUBLE_TYPE));
#endif
  sp = ld_stack_base - MD_MAX_ENVIRON;
  ld_stack_size = ld_stack_base - sp;
    printf("Thread 0 stack size (4)%d\n",  current->ld_stack_size);

  /* initial stack pointer value */
  ld_environ_base = sp;

  /* write [argc] to stack */
  temp = MD_SWAPQ(argc);
  mem_access(mem, Write, sp, &temp, sizeof(qword_t));
  regs->regs_R[MD_REG_A0] = temp;
  sp += sizeof(qword_t);

  /* skip past argv array and NULL */
  argv_addr = sp;
  regs->regs_R[MD_REG_A1] = argv_addr;
  sp = sp + (argc + 1) * sizeof(md_addr_t);

  /* save space for envp array and NULL */
  envp_addr = sp;
  for (i=0; envp[i]; i++)
    sp += sizeof(md_addr_t);
  sp += sizeof(md_addr_t);

  /* fill in the argv pointer array and data */
  for (i=0; i<argc; i++)
    {
      /* write the argv pointer array entry */
      temp = MD_SWAPQ(sp);
      mem_access(mem, Write, argv_addr + i*sizeof(md_addr_t),
		 &temp, sizeof(md_addr_t));
      /* and the data */
      mem_strcpy(mem_access, mem, Write, sp, argv[i]);
      sp += strlen(argv[i])+1;
    }
  /* terminate argv array with a NULL */
  mem_access(mem, Write, argv_addr + i*sizeof(md_addr_t),
	     &null_ptr, sizeof(md_addr_t));

  /* write envp pointer array and data to stack */
  for (i = 0; envp[i]; i++)
    {
      /* write the envp pointer array entry */
      temp = MD_SWAPQ(sp);
      mem_access(mem, Write, envp_addr + i*sizeof(md_addr_t),
		 &temp, sizeof(md_addr_t));
      /* and the data */
      mem_strcpy(mem_access, mem, Write, sp, envp[i]);
      sp += strlen(envp[i]) + 1;
    }
  /* terminate the envp array with a NULL */
  mem_access(mem, Write, envp_addr + i*sizeof(md_addr_t),
	     &null_ptr, sizeof(md_addr_t));

  /* did we tromp off the stop of the stack? */
  if (sp > ld_stack_base)
    {
      /* we did, indicate to the user that MD_MAX_ENVIRON must be increased,
	 alternatively, you can use a smaller environment, or fewer
	 command line arguments */
      fatal("environment overflow, increase MD_MAX_ENVIRON in alpha.h");
    }

  /* initialize the bottom of heap to top of data segment */
  ld_brk_point = ROUND_UP(ld_data_base + ld_data_size, MD_PAGE_SIZE);

  /* set initial minimum stack pointer value to initial stack value */
  ld_stack_min = regs->regs_R[MD_REG_SP];

  regs->regs_R[MD_REG_SP] = ld_environ_base;
  regs->regs_PC = ld_prog_entry;

  printf("ld_text_base: 0x%08x  ld_text_size: 0x%08x",
	ld_text_base, ld_text_size);
  printf("ld_data_base: 0x%08x  ld_data_size: 0x%08x",
	ld_data_base, ld_data_size);
  printf("ld_stack_base: 0x%08x  ld_stack_size: 0x%08x",
	ld_stack_base, ld_stack_size);
  printf("ld_prog_entry: 0x%08x", ld_prog_entry);

  debug("ld_text_base: 0x%08x  ld_text_size: 0x%08x",
	ld_text_base, ld_text_size);
  debug("ld_data_base: 0x%08x  ld_data_size: 0x%08x",
	ld_data_base, ld_data_size);
  debug("ld_stack_base: 0x%08x  ld_stack_size: 0x%08x",
	ld_stack_base, ld_stack_size);
  debug("ld_prog_entry: 0x%08x", ld_prog_entry);
}
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;

}
static os_emul_data *
emul_bugapi_create(device *root,
		   bfd *image,
		   const char *name)
{
  device *node;
  os_emul_data *bugapi;
  char *filename;

  /* check it really is for us */
  if (name != NULL
      && strcmp(name, "bugapi") != 0
      && strcmp(name, "bug") != 0)
    return NULL;
  if (image != NULL
      && name == NULL
      && bfd_get_start_address(image) >= BUGAPI_END_ADDRESS)
    return NULL;

  bugapi = ZALLOC(os_emul_data);

  /* options */
  emul_add_tree_options(root, image, "bug", "oea",
			1 /*oea-interrupt-prefix*/);

  /* add some real hardware, include eeprom memory for the eeprom trap
     addresses */
  emul_add_tree_hardware(root);
  node = tree_parse(root, "/openprom/memory@0xfff00000");
  tree_parse(node, "./psim,description \"eeprom trap addresses");
  tree_parse(node, "./reg 0xfff00000 0x3000");

  bugapi->root = root;

  bugapi->memory_size
    = tree_find_integer_property(root, "/openprom/options/oea-memory-size");
  bugapi->interrupt_prefix =
    tree_find_integer_property(root, "/openprom/options/oea-interrupt-prefix");
  bugapi->interrupt_vector_address = (bugapi->interrupt_prefix
				      ? MASK(0, 43)
				      : 0);
  bugapi->system_call_address = (bugapi->interrupt_vector_address + 0x00c00);
  bugapi->stall_cpu_loop_address = (bugapi->system_call_address + 0x000f0);
  bugapi->top_of_stack = bugapi->memory_size - 0x1000;
  bugapi->little_endian
    = tree_find_boolean_property(root, "/options/little-endian?");
  bugapi->floating_point_available
    = tree_find_boolean_property(root, "/openprom/options/floating-point?");
  bugapi->input = NULL;
  bugapi->output = NULL;

  /* initialization */
  if (image != NULL)
    tree_parse(root, "/openprom/init/register/0.pc 0x%lx",
	       (unsigned long)bfd_get_start_address(image));
  tree_parse(root, "/openprom/init/register/pc 0x%lx",
	     (unsigned long)bugapi->stall_cpu_loop_address);
  tree_parse(root, "/openprom/init/register/sp 0x%lx",
	     (unsigned long)(bugapi->top_of_stack - 16));
  tree_parse(root, "/openprom/init/register/msr 0x%x",
	     (msr_recoverable_interrupt
	      | (bugapi->little_endian
		 ? (msr_little_endian_mode
		    | msr_interrupt_little_endian_mode)
		 : 0)
	      | (bugapi->floating_point_available
		 ? msr_floating_point_available
		 : 0)
	      | (bugapi->interrupt_prefix
		 ? msr_interrupt_prefix
		 : 0)
	      ));

  /* patch the system call instruction to call this emulation and then
     do an rfi */
  node = tree_parse(root, "/openprom/init/data@0x%lx",
		    (unsigned long)bugapi->system_call_address);
  tree_parse(node, "./psim,description \"system-call trap instruction");
  tree_parse(node, "./real-address 0x%lx",
	     (unsigned long)bugapi->system_call_address);
  tree_parse(node, "./data 0x%x", emul_call_instruction);
  node = tree_parse(root, "/openprom/init/data@0x%lx",
		    (unsigned long)bugapi->system_call_address + 4);
  tree_parse(node, "./psim,description \"return from interrupt instruction");
  tree_parse(node, "./real-address 0x%lx",
	     (unsigned long)bugapi->system_call_address + 4);
  tree_parse(node, "./data 0x%x",
	     emul_rfi_instruction);

  /* patch the end of the system call instruction so that it contains
     a loop to self instruction and point all the cpu's at this */
  node = tree_parse(root, "/openprom/init/data@0x%lx",
		    (unsigned long)bugapi->stall_cpu_loop_address);
  tree_parse(node, "./psim,description \"cpu-loop instruction");
  tree_parse(node, "./real-address 0x%lx",
	     (unsigned long)bugapi->stall_cpu_loop_address);
  tree_parse(node, "./data 0x%lx",
	     (unsigned long)emul_loop_instruction);

  if (image != NULL)
    tree_parse(root, "/openprom/init/stack/stack-type %s",
	       (image->xvec->flavour == bfd_target_elf_flavour
		? "ppc-elf"
		: "ppc-xcoff"));

  if (image != NULL)
    {
      filename = tree_quote_property (bfd_get_filename(image));
      tree_parse(root, "/openprom/init/load-binary/file-name %s",
		 filename);
      free (filename);
    }

  return bugapi;
}
Пример #21
0
   @return  A return code indicating success.                                */
/* ------------------------------------------------------------------------- */
SIM_RC
sim_create_inferior (SIM_DESC     sd,
		     struct bfd  *abfd,
		     char       **argv  ATTRIBUTE_UNUSED,
		     char       **env   ATTRIBUTE_UNUSED)
{
#ifdef OR32_SIM_DEBUG
  printf ("sim_create_inferior called\n");
#endif

  or1ksim_set_stall_state (1);
  sd->entry_point = (NULL == abfd) ? OR32_RESET_EXCEPTION :
                                    bfd_get_start_address (abfd);
  sd->resume_npc  = OR32_RESET_EXCEPTION;

  return  SIM_RC_OK;

}	/* sim_create_inferior () */


/* ------------------------------------------------------------------------- */
/*!Fetch bytes from the simulated program's memory.

   @param[in]  sd   Simulation descriptor from sim_open (). We don't use
                    this.
   @param[in]  mem  The address in memory to fetch from.
   @param[out] buf  Where to put the read data
   @param[in]  len  Number of bytes to fetch
Пример #22
0
static const struct bfd_target *
vms_object_p (bfd * abfd)
{
  int err = 0;
  int prev_type;
  const struct bfd_target *target_vector = NULL;
  const bfd_arch_info_type *arch = NULL;
  void * tdata_save = abfd->tdata.any;
  bfd_vma saddr_save = bfd_get_start_address (abfd);

#if defined(VMS_DEBUG) && VMS_DEBUG
  vms_debug(1, "vms_object_p (%p)\n", (void *)abfd);
#endif

  if (!vms_initialize (abfd))
    goto error_ret;

  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET))
    goto err_wrong_format;

  prev_type = -1;

  do
    {
#if defined(VMS_DEBUG) && VMS_DEBUG
      vms_debug(7, "reading at %08lx\n", (unsigned long)bfd_tell(abfd));
#endif
      if (_bfd_vms_next_record (abfd) < 0)
	{
#if defined(VMS_DEBUG) && VMS_DEBUG
	  vms_debug (2, "next_record failed\n");
#endif
	  goto err_wrong_format;
	}

      if ((prev_type == EOBJ_S_C_EGSD)
	   && (PRIV (rec_type) != EOBJ_S_C_EGSD))
	{
	  if (! vms_fixup_sections (abfd))
	    {
#if defined(VMS_DEBUG) && VMS_DEBUG
	      vms_debug (2, "vms_fixup_sections failed\n");
#endif
	      goto err_wrong_format;
	    }
	}

      prev_type = PRIV (rec_type);

      if (target_vector == NULL)
	{
	  if (prev_type <= OBJ_S_C_MAXRECTYP)
	    target_vector = &vms_vax_vec;
	  else
	    target_vector = &vms_alpha_vec;
	}

      switch (prev_type)
	{
	  case OBJ_S_C_HDR:
	  case EOBJ_S_C_EMH:
	    err = _bfd_vms_slurp_hdr (abfd, prev_type);
	    break;
	  case OBJ_S_C_EOM:
	  case OBJ_S_C_EOMW:
	  case EOBJ_S_C_EEOM:
	    err = _bfd_vms_slurp_eom (abfd, prev_type);
	    break;
	  case OBJ_S_C_GSD:
	  case EOBJ_S_C_EGSD:
	    err = _bfd_vms_slurp_gsd (abfd, prev_type);
	    break;
	  case OBJ_S_C_TIR:
	  case EOBJ_S_C_ETIR:
	    err = _bfd_vms_slurp_tir (abfd, prev_type);
	    break;
	  case OBJ_S_C_DBG:
	  case EOBJ_S_C_EDBG:
	    err = _bfd_vms_slurp_dbg (abfd, prev_type);
	    break;
	  case OBJ_S_C_TBT:
	  case EOBJ_S_C_ETBT:
	    err = _bfd_vms_slurp_tbt (abfd, prev_type);
	    break;
	  case OBJ_S_C_LNK:
	    err = _bfd_vms_slurp_lnk (abfd, prev_type);
	    break;
	  default:
	    err = -1;
	}
      if (err != 0)
	{
#if defined(VMS_DEBUG) && VMS_DEBUG
	  vms_debug (2, "slurp type %d failed with %d\n", prev_type, err);
#endif
	  goto err_wrong_format;
	}
    }
  while ((prev_type != EOBJ_S_C_EEOM) && (prev_type != OBJ_S_C_EOM) && (prev_type != OBJ_S_C_EOMW));

  if (target_vector == & vms_vax_vec)
    {
      if (! vms_fixup_sections (abfd))
	{
#if defined(VMS_DEBUG) && VMS_DEBUG
	  vms_debug (2, "vms_fixup_sections failed\n");
#endif
	  goto err_wrong_format;
	}

      /* Set arch_info to vax.  */

      arch = bfd_scan_arch ("vax");
      PRIV (is_vax) = TRUE;
#if defined(VMS_DEBUG) && VMS_DEBUG
      vms_debug (2, "arch is vax\n");
#endif
    }
  else if (target_vector == &vms_alpha_vec)
    {
      /* Set arch_info to alpha: */
      const char *alphastr = "alpha";
      arch = bfd_scan_arch(alphastr);
      PRIV (is_vax) = FALSE;
#if defined(VMS_DEBUG) && VMS_DEBUG
      vms_debug(2, "arch is %s\n", alphastr);
#endif /* VMS_DEBUG */
    }

  if (arch == NULL)
    {
#if defined(VMS_DEBUG) && VMS_DEBUG
      vms_debug (2, "arch not found\n");
#endif
      goto err_wrong_format;
    }
  abfd->arch_info = arch;

  return target_vector;

 err_wrong_format:
  bfd_set_error (bfd_error_wrong_format);
 error_ret:
  if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
    bfd_release (abfd, abfd->tdata.any);
  abfd->tdata.any = tdata_save;
  bfd_set_start_address (abfd, saddr_save);
  return NULL;
}
Пример #23
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;
}
Пример #24
0
static bfd_boolean
aout_adobe_write_object_contents (bfd *abfd)
{
  struct external_exec swapped_hdr;
  static struct external_segdesc sentinel[1];	/* Initialized to zero.  */
  asection *sect;
  bfd_size_type amt;

  exec_hdr (abfd)->a_info = ZMAGIC;

  /* Calculate text size as total of text sections, etc.  */
  exec_hdr (abfd)->a_text = 0;
  exec_hdr (abfd)->a_data = 0;
  exec_hdr (abfd)->a_bss  = 0;
  exec_hdr (abfd)->a_trsize = 0;
  exec_hdr (abfd)->a_drsize = 0;

  for (sect = abfd->sections; sect; sect = sect->next)
    {
      if (sect->flags & SEC_CODE)
	{
	  exec_hdr (abfd)->a_text += sect->size;
	  exec_hdr (abfd)->a_trsize += sect->reloc_count *
	    sizeof (struct reloc_std_external);
	}
      else if (sect->flags & SEC_DATA)
	{
	  exec_hdr (abfd)->a_data += sect->size;
	  exec_hdr (abfd)->a_drsize += sect->reloc_count *
	    sizeof (struct reloc_std_external);
	}
      else if (sect->flags & SEC_ALLOC && !(sect->flags & SEC_LOAD))
	exec_hdr (abfd)->a_bss += sect->size;
    }

  exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd)
    * sizeof (struct external_nlist);
  exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);

  aout_adobe_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);

  amt = EXEC_BYTES_SIZE;
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
      || bfd_bwrite (& swapped_hdr, amt, abfd) != amt)
    return FALSE;

  /* Now write out the section information.  Text first, data next, rest
     afterward.  */
  for (sect = abfd->sections; sect; sect = sect->next)
    if (sect->flags & SEC_CODE)
      aout_adobe_write_section (abfd, sect);

  for (sect = abfd->sections; sect; sect = sect->next)
    if (sect->flags & SEC_DATA)
      aout_adobe_write_section (abfd, sect);

  for (sect = abfd->sections; sect; sect = sect->next)
    if (!(sect->flags & (SEC_CODE | SEC_DATA)))
      aout_adobe_write_section (abfd, sect);

  /* Write final `sentinel` section header (with type of 0).  */
  amt = sizeof (*sentinel);
  if (bfd_bwrite (sentinel, amt, abfd) != amt)
    return FALSE;

  /* Now write out reloc info, followed by syms and strings.  */
  if (bfd_get_symcount (abfd) != 0)
    {
      if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (*exec_hdr (abfd))), SEEK_SET)
	  != 0)
	return FALSE;

      if (! aout_32_write_syms (abfd))
	return FALSE;

      if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (*exec_hdr (abfd))), SEEK_SET)
	  != 0)
	return FALSE;

      for (sect = abfd->sections; sect; sect = sect->next)
	if (sect->flags & SEC_CODE)
	  if (!aout_32_squirt_out_relocs (abfd, sect))
	    return FALSE;

      if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*exec_hdr (abfd))), SEEK_SET)
	  != 0)
	return FALSE;

      for (sect = abfd->sections; sect; sect = sect->next)
	if (sect->flags & SEC_DATA)
	  if (!aout_32_squirt_out_relocs (abfd, sect))
	    return FALSE;
    }

  return TRUE;
}
Пример #25
0
static void
download (char *target_name, char *args, int from_tty,
	  void (*write_routine) (bfd *from_bfd, asection *from_sec,
				 file_ptr from_addr, bfd_vma to_addr, int len),
	  void (*start_routine) (bfd_vma entry))
{
  struct cleanup *old_chain;
  asection *section;
  bfd *pbfd;
  bfd_vma entry;
  int i;
#define WRITESIZE 1024
  char *filename;
  int quiet;
  int nostart;

  quiet = 0;
  nostart = 0;
  filename = NULL;

  while (*args != '\000')
    {
      char *arg;

      while (isspace (*args))
	args++;

      arg = args;

      while ((*args != '\000') && !isspace (*args))
	args++;

      if (*args != '\000')
	*args++ = '\000';

      if (*arg != '-')
	filename = arg;
      else if (strncmp (arg, "-quiet", strlen (arg)) == 0)
	quiet = 1;
      else if (strncmp (arg, "-nostart", strlen (arg)) == 0)
	nostart = 1;
      else
	error ("unknown option `%s'", arg);
    }

  if (!filename)
    filename = get_exec_file (1);

  pbfd = bfd_openr (filename, gnutarget);
  if (pbfd == NULL)
    {
      perror_with_name (filename);
      return;
    }
  old_chain = make_cleanup_bfd_close (pbfd);

  if (!bfd_check_format (pbfd, bfd_object))
    error ("\"%s\" is not an object file: %s", filename,
	   bfd_errmsg (bfd_get_error ()));

  for (section = pbfd->sections; section; section = section->next)
    {
      if (bfd_get_section_flags (pbfd, section) & SEC_LOAD)
	{
	  bfd_vma section_address;
	  bfd_size_type section_size;
	  file_ptr fptr;
	  const char *section_name;

	  section_name = bfd_get_section_name (pbfd, section);

	  section_address = bfd_get_section_vma (pbfd, section);

	  /* Adjust sections from a.out files, since they don't
	     carry their addresses with.  */
	  if (bfd_get_flavour (pbfd) == bfd_target_aout_flavour)
	    {
	      if (strcmp (section_name, ".text") == 0)
		section_address = bfd_get_start_address (pbfd);
	      else if (strcmp (section_name, ".data") == 0)
		{
		  /* Read the first 8 bytes of the data section.
		     There should be the string 'DaTa' followed by
		     a word containing the actual section address. */
		  struct data_marker
		    {
		      char signature[4];	/* 'DaTa' */
		      unsigned char sdata[4];	/* &sdata */
		    }
		  marker;
		  bfd_get_section_contents (pbfd, section, &marker, 0,
					    sizeof (marker));
		  if (strncmp (marker.signature, "DaTa", 4) == 0)
		    {
		      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
			section_address = bfd_getb32 (marker.sdata);
		      else
			section_address = bfd_getl32 (marker.sdata);
		    }
		}
	    }

	  section_size = bfd_get_section_size_before_reloc (section);

	  if (!quiet)
	    printf_filtered ("[Loading section %s at 0x%x (%d bytes)]\n",
			     bfd_get_section_name (pbfd, section),
			     section_address,
			     section_size);

	  fptr = 0;
	  while (section_size > 0)
	    {
	      int count;
	      static char inds[] = "|/-\\";
	      static int k = 0;

	      QUIT;

	      count = min (section_size, WRITESIZE);

	      write_routine (pbfd, section, fptr, section_address, count);

	      if (!quiet)
		{
		  printf_unfiltered ("\r%c", inds[k++ % 4]);
		  gdb_flush (gdb_stdout);
		}

	      section_address += count;
	      fptr += count;
	      section_size -= count;
	    }
	}
    }

  if (!nostart)
    {
      entry = bfd_get_start_address (pbfd);

      if (!quiet)
	printf_unfiltered ("[Starting %s at 0x%x]\n", filename, entry);

      start_routine (entry);
    }

  do_cleanups (old_chain);
}