Exemple #1
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;
}
Exemple #2
0
static
struct bfd* new_bfd_internal( const char* filename,
                              int arch, int machine )
{
    char** matching;
    enum bfd_architecture _arch = (enum bfd_architecture) arch;
    struct bfd* p = bfd_openr( filename, DEFAULT_TARGET );
    const bfd_arch_info_type* info;

    if ( !p ) error_exit( "failure: bfd_openr" );

    if ( _arch == bfd_arch_unknown ) {
        if ( bfd_check_format( p, bfd_archive ) ) {
            // TODO: add archive handling code
            bfd_close_all_done( p );
            error_exit( "currently not supported." );
        }
        if ( bfd_check_format_matches( p, bfd_object, &matching ) ) {
            return p;
        }
        if ( bfd_get_error() == bfd_error_file_ambiguously_recognized ) {
            bfd_close_all_done( p );
            error_exit( "file format is ambiguosly matched" );
        }
        if ( bfd_get_error() != bfd_error_file_not_recognized ) {
            bfd_close_all_done( p );
            error_exit( "file is not recognized" );
        }
        if ( bfd_check_format_matches( p, bfd_core, &matching ) ) {
            return p;
        }
        error_exit( "failed to load the given file" );
        return NULL; /* this will never be called */
    } else {
        info = bfd_lookup_arch( _arch, machine );
        if ( !info ) error_exit( "failed to lookup archicture" );
        bfd_set_arch_info( p, info );
        return p;
    }
}
// Define BFD-related global variables.
static int define_bfd_vars(void)
{
	bfd * bfd;
	bfd_boolean r;
	int len;
#define MAX_PATHLENGTH 2048
	char mypath[MAX_PATHLENGTH];
     
	len = readlink("/proc/self/exe", mypath, sizeof(mypath));
     
	if (len < 0) {
		fprintf(stderr, "libopagent: readlink /proc/self/exe failed\n");
		return -1;
	}
	if (len >= MAX_PATHLENGTH) {
		fprintf(stderr, "libopagent: readlink /proc/self/exe returned"
			" path length longer than %d.\n", MAX_PATHLENGTH);

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

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

	return 0;
}
int init_bfd_ctx(bfd_ctx * bc, PCWSTR procname)
{
	LogTrace();
	bc->handle = NULL;
	bc->symbol = NULL;

	LogTrace();
	bfd *b = bfd_openr(Base::w2cp(procname, CP_OEMCP).c_str(), 0);
	if (!b) {
		LogFatal(L"Failed to open bfd from (%s)\n" , procname);
		return 1;
	}

	int r1 = bfd_check_format(b, bfd_object);
	int r2 = bfd_check_format_matches(b, bfd_object, NULL);
	int r3 = bfd_get_file_flags(b) & HAS_SYMS;

	if (!(r1 && r2 && r3)) {
		bfd_close(b);
		LogFatal(L"Failed to init bfd from (%s)\n", procname);
		return 1;
	}

	void * symbol_table;
	unsigned dummy = 0;
	if (bfd_read_minisymbols(b, FALSE, &symbol_table, &dummy) == 0) {
		if (bfd_read_minisymbols(b, TRUE, &symbol_table, &dummy) < 0) {
			free(symbol_table);
			bfd_close(b);
			LogFatal(L"Failed to read symbols from (%s)\n", procname);
			return 1;
		}
	}

	bc->handle = b;
	bc->symbol = (asymbol**)symbol_table;

	return 0;
}
static int
init_bfd_ctx(struct bfd_ctx *bc, const char * procname, struct output_buffer *ob)
{
	bc->handle = NULL;
	bc->symbol = NULL;

	bfd *b = bfd_openr(procname, 0);
	if (!b) {
		output_print(ob,"Failed to open bfd from (%s)\n" , procname);
		return 1;
	}

	int r1 = bfd_check_format(b, bfd_object);
	int r2 = bfd_check_format_matches(b, bfd_object, NULL);
	int r3 = bfd_get_file_flags(b) & HAS_SYMS;

	if (!(r1 && r2 && r3)) {
		bfd_close(b);
		output_print(ob,"Failed to init bfd from (%s)\n", procname);
		return 1;
	}

	void *symbol_table;

	unsigned dummy = 0;
	if (bfd_read_minisymbols(b, FALSE, &symbol_table, &dummy) == 0) {
		if (bfd_read_minisymbols(b, TRUE, &symbol_table, &dummy) < 0) {
			free(symbol_table);
			bfd_close(b);
			output_print(ob,"Failed to read symbols from (%s)\n", procname);
			return 1;
		}
	}

	bc->handle = b;
	bc->symbol = symbol_table;

	return 0;
}
Exemple #6
0
int
main (int argc, char **argv)
{
  bfd *archive;
  bfd *last, *next;

  if (argc != 2)
    die ("bad usage");

  archive = bfd_openr (argv[1], NULL);

  if (!bfd_check_format (archive, bfd_archive))
    {
      bfd_close (archive);
      die ("bfd_check_format");
    }

  for (last = bfd_openr_next_archived_file (archive, NULL);
       last;
       last = next)
    {
      next = bfd_openr_next_archived_file (archive, last);
      bfd_close (last);
    }

  for (last = bfd_openr_next_archived_file (archive, NULL);
       last;
       last = next)
    {
      next = bfd_openr_next_archived_file (archive, last);
      bfd_close (last);
    }

  if (!bfd_close (archive))
    die ("bfd_close");

  return 0;
}
static bfd_cache_ptr get_bfd_cache(const char *filename) {
  bfdMap::const_iterator iter = s_bfds.find(filename);
  if (iter != s_bfds.end()) {
    return iter->second;
  }
  bfd_cache_ptr p(new bfd_cache());
  bfd *abfd = bfd_openr(filename, NULL);
  if (abfd) {
    p->abfd = abfd;
    p->syms = NULL;
    char **match;
    if (bfd_check_format(abfd, bfd_archive) ||
        !bfd_check_format_matches(abfd, bfd_object, &match) ||
        !slurp_symtab(&p->syms, abfd)) {
      bfd_close(abfd);
      p.reset();
    }
  } else {
    p.reset();
  }
  s_bfds[filename] = p;
  return p;
}
Exemple #8
0
bfd *
initialize_bfd(const char *filename)
{
  bfd * abfd;
  char **matching;
  char *target = "i686-pc-linux-gnu";

  bfd_init();

  if(!bfd_set_default_target(target))
    fatal("program::initialize", "couldn't set default bfd target");
  
  abfd = bfd_openr(filename, target);
  if(abfd == NULL)
    fatal("initialize_bfd", "cannot open %s", filename);

  if (bfd_check_format (abfd, bfd_archive))
      fatal("initalize_bfd", "archive files  not supported\n");

  if(!bfd_check_format_matches(abfd, bfd_object, &matching))
    fatal("initialize_bfd", "bfd_check_format_matches failed");
  return abfd;
}
Exemple #9
0
static bfd *
spu_bfd_fopen (char *name, CORE_ADDR addr)
{
  bfd *nbfd;
  CORE_ADDR *open_closure = XNEW (CORE_ADDR);

  *open_closure = addr;

  nbfd = gdb_bfd_openr_iovec (name, "elf32-spu",
			      spu_bfd_iovec_open, open_closure,
			      spu_bfd_iovec_pread, spu_bfd_iovec_close,
			      spu_bfd_iovec_stat);
  if (!nbfd)
    return NULL;

  if (!bfd_check_format (nbfd, bfd_object))
    {
      gdb_bfd_unref (nbfd);
      return NULL;
    }

  return nbfd;
}
Exemple #10
0
bfd *
open_bfd_matching_arch (bfd *archive_bfd, bfd_format expected_format)
{
  enum gdb_osabi osabi;
  bfd *abfd;
  
  osabi = GDB_OSABI_UNINITIALIZED;
  abfd = NULL;

  osabi = gdbarch_osabi (get_current_arch ());
  if ((osabi <= GDB_OSABI_UNKNOWN) || (osabi >= GDB_OSABI_INVALID))
    osabi = gdbarch_lookup_osabi (archive_bfd);
  
  // FIXME: gdbarch_lookup_osabi() doesn't work yet on archive_bfd, hardcode
  if ((osabi <= GDB_OSABI_UNKNOWN) || (osabi >= GDB_OSABI_INVALID))
    osabi = GDB_OSABI_DARWIN;
  
  for (;;)
    {
      abfd = bfd_openr_next_archived_file (archive_bfd, abfd);
      if (abfd == NULL)
        break;
      if (! bfd_check_format (abfd, expected_format))
        continue;
      if (osabi == gdbarch_lookup_osabi_from_bfd (abfd))
        break;
    }
    
  // Copy the filename of the archive to the binary bfd.
  if (abfd)
  {
    xfree(abfd->filename);
    abfd->filename = archive_bfd->filename;
  }
  
  return abfd;
}
Exemple #11
0
traceback::Bfd::Context::Context(const char* image) :
	image(cstr::dup(image)),
	handle(),
	symbol()
{
	LogTraceObj("(%s)", image);

	bfd* b = bfd_openr(image, 0);
	if (!b) {
		LogError("Failed to open bfd from (%s)", image);
		return;
	}

	auto r1 = bfd_check_format(b, bfd_object);
	auto r2 = bfd_check_format_matches(b, bfd_object, NULL);
	auto r3 = bfd_get_file_flags(b) & HAS_SYMS;

	if (!(r1 && r2 && r3)) {
		bfd_close(b);
		LogError("Failed to init bfd from (%d, %d, %d) (%s)", r1, r2, r3, image);
		return;
	}

	void* symbol_table = nullptr;
	unsigned dummy = 0;
	if (bfd_read_minisymbols(b, FALSE, &symbol_table, &dummy) == 0) {
		if (bfd_read_minisymbols(b, TRUE, &symbol_table, &dummy) < 0) {
			free(symbol_table);
			bfd_close(b);
			LogError("Failed to read symbols from (%s)", image);
			return;
		}
	}

	handle = b;
	symbol = (asymbol**)symbol_table;
}
Exemple #12
0
/* Read in the symbol table.  */
static int
_symtab_init (struct symtab *symtab, const char *filename)
{
    char **matching;
    long symcount;
    unsigned int size;

    symtab->bfd = NULL;
    symtab->syms = NULL;

    symtab->bfd = bfd_openr (filename, NULL);
    if (symtab->bfd == NULL)
	goto BAIL;

    if (bfd_check_format (symtab->bfd, bfd_archive))
	goto BAIL;

    if (! bfd_check_format_matches (symtab->bfd, bfd_object, &matching))
	goto BAIL;

    symcount = bfd_read_minisymbols (symtab->bfd, false, (PTR) &symtab->syms, &size);
    if (symcount == 0) {
	symcount = bfd_read_minisymbols (symtab->bfd, true /* dynamic */ ,
		(PTR) &symtab->syms, &size);
    }
    if (symcount < 0)
	goto BAIL;

    if ((bfd_get_file_flags (symtab->bfd) & HAS_SYMS) == 0)
	goto BAIL;

    return 1;

BAIL:
    _symtab_fini (symtab);
    return 0;
}
Exemple #13
0
void Archive::Read(const char* filename, Symbol::SymbolIndex_t& symbolIndex)
{
   char *target = 0;
   bfd *file;

   file = bfd_openr (filename, target);
   if (file == 0)
   {
      //    bfd_nonfatal (filename);
   //   return FALSE;
   }

   if (bfd_check_format (file, bfd_archive))
   {
      //    display_archive (file);
      bfd *arfile = 0;

      std::cout << "file " << bfd_get_filename (file) << std::endl;

      while(arfile = bfd_openr_next_archived_file (file, arfile))
      {
         const char* objectname = bfd_get_filename (arfile);
         ObjectFile* o = new ObjectFile(objectname, symbolIndex);
         o->SetParent(*this);
         o->Read(arfile);
         std::cout << "file " << bfd_get_filename (arfile) << std::endl;
      }

      if (arfile == NULL)
      {
      //if (bfd_get_error () != bfd_error_no_more_archived_files)
      //bfd_fatal (bfd_get_filename (file));
      //break;
      }
   }
}
Exemple #14
0
bool ElfFile::readExports()
{
    long storage_needed;
    asymbol **symbol_table;
    long number_of_symbols;
    long i;

    m_symbols.clear();

    bfd_set_default_target("bfd_target_elf_flavour");
    m_bfd = bfd_openr(m_name.toStdString().c_str(),NULL);

    if(!bfd_check_format(m_bfd,bfd_object))
    {
        return false;
    }

    storage_needed = bfd_get_symtab_upper_bound(m_bfd);
    symbol_table = (asymbol **)malloc(storage_needed);
    number_of_symbols = bfd_canonicalize_symtab(m_bfd, symbol_table);

    qDebug() << "Number of symbols " << number_of_symbols;

    for(i = 0; i < number_of_symbols; i++)
    {
        m_symbols << SymbolDescription(
                         symbol_table[i]->section->name,
                         symbol_table[i]->name,
                         symbol_table[i]->flags,
                         symbol_table[i]->value);
        qDebug() << "found " << symbol_table[i]->name;
    }
    free(symbol_table);
    symbol_table = NULL;
    return true;
}
Exemple #15
0
static bfd *
initialize_bfd(const char *filename)
{
  bfd * abfd;
  char **matching;
  char *target = "i686-pc-linux-gnu";

  bfd_init();

  if(!bfd_set_default_target(target)) {
    fprintf(stderr, "initialize_bfd: couldn't set default bfd target\n");
    return NULL;
  }

  abfd = bfd_openr(filename, target);
  if(abfd == NULL) {
    fprintf(stderr, "initialize_bfd: cannot open %s\n", filename);
    return NULL;
  }

  if (bfd_check_format (abfd, bfd_archive)) {
    fprintf(stderr, "initalize_bfd: archive files  not supported\n");
    bfd_close_all_done(abfd);
    return NULL;
  }

  /* if(!bfd_check_format_matches(abfd, bfd_object, &matching)) { */
  if( (!bfd_check_format_matches(abfd, bfd_object, &matching)) &&
      (!bfd_check_format_matches(abfd, bfd_core, &matching)) ) {

    fprintf(stderr, "initialize_bfd: bfd_check_format_matches failed\n");
    bfd_close_all_done(abfd);
    return NULL;
  }
  return abfd;
}
Exemple #16
0
static void
core_open (char *filename, int from_tty)
{
  const char *p;
  int siggy;
  struct cleanup *old_chain;
  char *temp;
  bfd *temp_bfd;
  int scratch_chan;
  int flags;
  volatile struct gdb_exception except;

  target_preopen (from_tty);
  if (!filename)
    {
      if (core_bfd)
	error (_("No core file specified.  (Use `detach' "
		 "to stop debugging a core file.)"));
      else
	error (_("No core file specified."));
    }

  filename = tilde_expand (filename);
  if (!IS_ABSOLUTE_PATH (filename))
    {
      temp = concat (current_directory, "/",
		     filename, (char *) NULL);
      xfree (filename);
      filename = temp;
    }

  old_chain = make_cleanup (xfree, filename);

  flags = O_BINARY | O_LARGEFILE;
  if (write_files)
    flags |= O_RDWR;
  else
    flags |= O_RDONLY;
  scratch_chan = open (filename, flags, 0);
  if (scratch_chan < 0)
    perror_with_name (filename);

  temp_bfd = bfd_fopen (filename, gnutarget, 
			write_files ? FOPEN_RUB : FOPEN_RB,
			scratch_chan);
  if (temp_bfd == NULL)
    perror_with_name (filename);

  if (!bfd_check_format (temp_bfd, bfd_core)
      && !gdb_check_format (temp_bfd))
    {
      /* Do it after the err msg */
      /* FIXME: should be checking for errors from bfd_close (for one
         thing, on error it does not free all the storage associated
         with the bfd).  */
      make_cleanup_bfd_close (temp_bfd);
      error (_("\"%s\" is not a core dump: %s"),
	     filename, bfd_errmsg (bfd_get_error ()));
    }

  /* Looks semi-reasonable.  Toss the old core file and work on the
     new.  */

  discard_cleanups (old_chain);	/* Don't free filename any more */
  unpush_target (&core_ops);
  core_bfd = temp_bfd;
  old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/);

  /* FIXME: kettenis/20031023: This is very dangerous.  The
     CORE_GDBARCH that results from this call may very well be
     different from CURRENT_GDBARCH.  However, its methods may only
     work if it is selected as the current architecture, because they
     rely on swapped data (see gdbarch.c).  We should get rid of that
     swapped data.  */
  core_gdbarch = gdbarch_from_bfd (core_bfd);

  /* Find a suitable core file handler to munch on core_bfd */
  core_vec = sniff_core_bfd (core_bfd);

  validate_files ();

  core_data = XZALLOC (struct target_section_table);

  /* Find the data section */
  if (build_section_table (core_bfd,
			   &core_data->sections,
			   &core_data->sections_end))
    error (_("\"%s\": Can't find sections: %s"),
	   bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ()));

  /* If we have no exec file, try to set the architecture from the
     core file.  We don't do this unconditionally since an exec file
     typically contains more information that helps us determine the
     architecture than a core file.  */
  if (!exec_bfd)
    set_gdbarch_from_file (core_bfd);

  push_target (&core_ops);
  discard_cleanups (old_chain);

  /* Do this before acknowledging the inferior, so if
     post_create_inferior throws (can happen easilly if you're loading
     a core file with the wrong exec), we aren't left with threads
     from the previous inferior.  */
  init_thread_list ();

  inferior_ptid = null_ptid;

  /* Need to flush the register cache (and the frame cache) from a
     previous debug session.  If inferior_ptid ends up the same as the
     last debug session --- e.g., b foo; run; gcore core1; step; gcore
     core2; core core1; core core2 --- then there's potential for
     get_current_regcache to return the cached regcache of the
     previous session, and the frame cache being stale.  */
  registers_changed ();

  /* Build up thread list from BFD sections, and possibly set the
     current thread to the .reg/NN section matching the .reg
     section.  */
  bfd_map_over_sections (core_bfd, add_to_thread_list,
			 bfd_get_section_by_name (core_bfd, ".reg"));

  if (ptid_equal (inferior_ptid, null_ptid))
    {
      /* Either we found no .reg/NN section, and hence we have a
	 non-threaded core (single-threaded, from gdb's perspective),
	 or for some reason add_to_thread_list couldn't determine
	 which was the "main" thread.  The latter case shouldn't
	 usually happen, but we're dealing with input here, which can
	 always be broken in different ways.  */
      struct thread_info *thread = first_thread_of_process (-1);

      if (thread == NULL)
	{
	  inferior_appeared (current_inferior (), CORELOW_PID);
	  inferior_ptid = pid_to_ptid (CORELOW_PID);
	  add_thread_silent (inferior_ptid);
	}
      else
	switch_to_thread (thread->ptid);
    }

  post_create_inferior (&core_ops, from_tty);

  /* Now go through the target stack looking for threads since there
     may be a thread_stratum target loaded on top of target core by
     now.  The layer above should claim threads found in the BFD
     sections.  */
  TRY_CATCH (except, RETURN_MASK_ERROR)
    {
      target_find_new_threads ();
    }

  if (except.reason < 0)
    exception_print (gdb_stderr, except);

  p = bfd_core_file_failing_command (core_bfd);
  if (p)
    printf_filtered (_("Core was generated by `%s'.\n"), p);

  siggy = bfd_core_file_failing_signal (core_bfd);
  if (siggy > 0)
    {
      /* If we don't have a CORE_GDBARCH to work with, assume a native
	 core (map gdb_signal from host signals).  If we do have
	 CORE_GDBARCH to work with, but no gdb_signal_from_target
	 implementation for that gdbarch, as a fallback measure,
	 assume the host signal mapping.  It'll be correct for native
	 cores, but most likely incorrect for cross-cores.  */
      enum gdb_signal sig = (core_gdbarch != NULL
			     && gdbarch_gdb_signal_from_target_p (core_gdbarch)
			     ? gdbarch_gdb_signal_from_target (core_gdbarch,
							       siggy)
			     : gdb_signal_from_host (siggy));

      printf_filtered (_("Program terminated with signal %d, %s.\n"),
		       siggy, gdb_signal_to_string (sig));
    }

  /* Fetch all registers from core file.  */
  target_fetch_registers (get_current_regcache (), -1);

  /* Now, set up the frame cache, and print the top of stack.  */
  reinit_frame_cache ();
  print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
}
Exemple #17
0
static void
core_open (const char *arg, int from_tty)
{
  const char *p;
  int siggy;
  struct cleanup *old_chain;
  char *temp;
  int scratch_chan;
  int flags;
  char *filename;

  target_preopen (from_tty);
  if (!arg)
    {
      if (core_bfd)
	error (_("No core file specified.  (Use `detach' "
		 "to stop debugging a core file.)"));
      else
	error (_("No core file specified."));
    }

  filename = tilde_expand (arg);
  if (!IS_ABSOLUTE_PATH (filename))
    {
      temp = concat (current_directory, "/",
		     filename, (char *) NULL);
      xfree (filename);
      filename = temp;
    }

  old_chain = make_cleanup (xfree, filename);

  flags = O_BINARY | O_LARGEFILE;
  if (write_files)
    flags |= O_RDWR;
  else
    flags |= O_RDONLY;
  scratch_chan = gdb_open_cloexec (filename, flags, 0);
  if (scratch_chan < 0)
    perror_with_name (filename);

  gdb_bfd_ref_ptr temp_bfd (gdb_bfd_fopen (filename, gnutarget,
					   write_files ? FOPEN_RUB : FOPEN_RB,
					   scratch_chan));
  if (temp_bfd == NULL)
    perror_with_name (filename);

  if (!bfd_check_format (temp_bfd.get (), bfd_core)
      && !gdb_check_format (temp_bfd.get ()))
    {
      /* Do it after the err msg */
      /* FIXME: should be checking for errors from bfd_close (for one
         thing, on error it does not free all the storage associated
         with the bfd).  */
      error (_("\"%s\" is not a core dump: %s"),
	     filename, bfd_errmsg (bfd_get_error ()));
    }

  /* Looks semi-reasonable.  Toss the old core file and work on the
     new.  */

  do_cleanups (old_chain);
  unpush_target (&core_ops);
  core_bfd = temp_bfd.release ();
  old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/);

  core_gdbarch = gdbarch_from_bfd (core_bfd);

  /* Find a suitable core file handler to munch on core_bfd */
  core_vec = sniff_core_bfd (core_bfd);

  validate_files ();

  core_data = XCNEW (struct target_section_table);

  /* Find the data section */
  if (build_section_table (core_bfd,
			   &core_data->sections,
			   &core_data->sections_end))
    error (_("\"%s\": Can't find sections: %s"),
	   bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ()));

  /* If we have no exec file, try to set the architecture from the
     core file.  We don't do this unconditionally since an exec file
     typically contains more information that helps us determine the
     architecture than a core file.  */
  if (!exec_bfd)
    set_gdbarch_from_file (core_bfd);

  push_target (&core_ops);
  discard_cleanups (old_chain);

  /* Do this before acknowledging the inferior, so if
     post_create_inferior throws (can happen easilly if you're loading
     a core file with the wrong exec), we aren't left with threads
     from the previous inferior.  */
  init_thread_list ();

  inferior_ptid = null_ptid;

  /* Need to flush the register cache (and the frame cache) from a
     previous debug session.  If inferior_ptid ends up the same as the
     last debug session --- e.g., b foo; run; gcore core1; step; gcore
     core2; core core1; core core2 --- then there's potential for
     get_current_regcache to return the cached regcache of the
     previous session, and the frame cache being stale.  */
  registers_changed ();

  /* Build up thread list from BFD sections, and possibly set the
     current thread to the .reg/NN section matching the .reg
     section.  */
  bfd_map_over_sections (core_bfd, add_to_thread_list,
			 bfd_get_section_by_name (core_bfd, ".reg"));

  if (ptid_equal (inferior_ptid, null_ptid))
    {
      /* Either we found no .reg/NN section, and hence we have a
	 non-threaded core (single-threaded, from gdb's perspective),
	 or for some reason add_to_thread_list couldn't determine
	 which was the "main" thread.  The latter case shouldn't
	 usually happen, but we're dealing with input here, which can
	 always be broken in different ways.  */
      struct thread_info *thread = first_thread_of_process (-1);

      if (thread == NULL)
	{
	  inferior_appeared (current_inferior (), CORELOW_PID);
	  inferior_ptid = pid_to_ptid (CORELOW_PID);
	  add_thread_silent (inferior_ptid);
	}
      else
	switch_to_thread (thread->ptid);
    }

  post_create_inferior (&core_ops, from_tty);

  /* Now go through the target stack looking for threads since there
     may be a thread_stratum target loaded on top of target core by
     now.  The layer above should claim threads found in the BFD
     sections.  */
  TRY
    {
      target_update_thread_list ();
    }

  CATCH (except, RETURN_MASK_ERROR)
    {
      exception_print (gdb_stderr, except);
    }
Exemple #18
0
void
core_init (const char * aout_name)
{
  int core_sym_bytes;
  asymbol *synthsyms;
  long synth_count;

  core_bfd = bfd_openr (aout_name, 0);

  if (!core_bfd)
    {
      perror (aout_name);
      done (1);
    }

  if (!bfd_check_format (core_bfd, bfd_object))
    {
      fprintf (stderr, _("%s: %s: not in executable format\n"), whoami, aout_name);
      done (1);
    }

  /* Get core's text section.  */
  core_text_sect = bfd_get_section_by_name (core_bfd, ".text");
  if (!core_text_sect)
    {
      core_text_sect = bfd_get_section_by_name (core_bfd, "$CODE$");
      if (!core_text_sect)
	{
	  fprintf (stderr, _("%s: can't find .text section in %s\n"),
		   whoami, aout_name);
	  done (1);
	}
    }

  /* Read core's symbol table.  */

  /* This will probably give us more than we need, but that's ok.  */
  core_sym_bytes = bfd_get_symtab_upper_bound (core_bfd);
  if (core_sym_bytes < 0)
    {
      fprintf (stderr, "%s: %s: %s\n", whoami, aout_name,
	       bfd_errmsg (bfd_get_error ()));
      done (1);
    }

  core_syms = (asymbol **) xmalloc (core_sym_bytes);
  core_num_syms = bfd_canonicalize_symtab (core_bfd, core_syms);

  if (core_num_syms < 0)
    {
      fprintf (stderr, "%s: %s: %s\n", whoami, aout_name,
	       bfd_errmsg (bfd_get_error ()));
      done (1);
    }

  synth_count = bfd_get_synthetic_symtab (core_bfd, core_num_syms, core_syms,
					  0, NULL, &synthsyms);
  if (synth_count > 0)
    {
      asymbol **symp;
      long new_size;
      long i;

      new_size = (core_num_syms + synth_count + 1) * sizeof (*core_syms);
      core_syms = (asymbol **) xrealloc (core_syms, new_size);
      symp = core_syms + core_num_syms;
      core_num_syms += synth_count;
      for (i = 0; i < synth_count; i++)
	*symp++ = synthsyms + i;
      *symp = 0;
    }

  min_insn_size = 1;
  offset_to_code = 0;

  switch (bfd_get_arch (core_bfd))
    {
    case bfd_arch_vax:
    case bfd_arch_tahoe:
      offset_to_code = 2;
      break;

    case bfd_arch_alpha:
      min_insn_size = 4;
      break;

    default:
      break;
    }

  if (function_mapping_file)
    read_function_mappings (function_mapping_file);
}
SymbolTable::SymbolTable(string path)
{
    //Open the file as binary file descriptor:
    bfd* descr = bfd_openr(path.c_str(), NULL);

    if (!descr)
    {
        throw runtime_error("Failed to open binary file descriptor.");
    }

    //Check the format of the file:
    if (!bfd_check_format(descr, bfd_object))
    {
        bfd_close(descr);
        throw runtime_error("Failed to verify binary format.");
    }

    //Get the size of the symbol table:
    long symbolTableSize = bfd_get_symtab_upper_bound(descr);

    if (symbolTableSize <= 0)
    {
        bfd_close(descr);

        if (symbolTableSize < 0)
        {
            throw runtime_error("Failed to read the upper bound of the symbol table.");
        }
        else
        {
            return;
        }
    }

    //Alloc space for the table:
    asymbol** symbolTable = (asymbol**)malloc(symbolTableSize);

    if (!symbolTable)
    {
        bfd_close(descr);
        throw runtime_error("Failed to allocate space for the symbol table.");
    }

    //Get the number of symbols by canonicalizing the table:
    long symbolTableCount = bfd_canonicalize_symtab(descr, symbolTable);

    if (symbolTableCount < 0)
    {
        bfd_close(descr);
        free(symbolTable);

        throw runtime_error("Failed to read the number of symbols in the symbol table.");
    }

    //Iterate:
    for (int i = 0; i < symbolTableCount; i++)
    {
        //Is there a name?
        if (!symbolTable[i]->name)
        {
            continue;
        }

        //Get the symbol data:
        Symbol* newSymbol = new Symbol(string(bfd_asymbol_name(symbolTable[i])), (pword)bfd_asymbol_value(symbolTable[i]));

        //Check:
        if (!newSymbol)
        {
            throw runtime_error("Failed to allocate space for a symbol.");
        }

        this->table[newSymbol->getName()] = newSymbol;
    }

    //Close the file descriptor and free the table:
    bfd_close(descr);
    free(symbolTable);
}
Exemple #20
0
static void BFDmanager_loadBFDdata (char *file, bfd **image, asymbol ***symbols,
	unsigned *nDataSymbols, data_symbol_t **DataSymbols)
{
	bfd *bfdImage = NULL;
	asymbol **bfdSymbols = NULL;

	if (nDataSymbols)
		*nDataSymbols = 0;
	if (DataSymbols)
		*DataSymbols = NULL;

	/* Open the binary file in read-only mode */
	bfdImage = bfd_openr (file, NULL);
	if (bfdImage == NULL)
	{
		const char *errmsg = bfd_errmsg (bfd_get_error());
		fprintf (stderr, "mpi2prv: WARNING! Cannot open binary file '%s': %s.\n"
		                "         Addresses will not be translated into source code references\n",
		  file, errmsg);
		return;
	}

	/* Check the binary file format */
	if (!bfd_check_format (bfdImage, bfd_object))
	{
		const char *errmsg = bfd_errmsg( bfd_get_error() );
		fprintf (stderr, "mpi2prv: WARNING! Binary file format does not match for file '%s' : %s\n"
		                "         Addresses will not be translated into source code references\n",
		  file, errmsg);
	}

	/* Load the mini-Symbol Table */
	if (bfd_get_file_flags (bfdImage) & HAS_SYMS)
	{
		long symcount;
		size_t size = bfd_get_symtab_upper_bound (bfdImage);
		if (size > 0)
		{
#if defined(BFD_MANAGER_GENERATE_ADDRESSES)
			long s;
			unsigned nDataSyms = 0;
			data_symbol_t *DataSyms = NULL;
#endif

			bfdSymbols = (asymbol**) malloc (size);
			if (bfdSymbols == NULL)
				FATAL_ERROR ("Cannot allocate memory to translate addresses into source code references\n");

#if 0
			/* HSG This is supposed to be space-efficient, but showed some errors .... :( */
			symcount = bfd_read_minisymbols (bfdImage, FALSE, (PTR) bfdSymbols, &usize);
			if (symcount == 0) 
				symcount = bfd_read_minisymbols (bfdImage, TRUE, (PTR) bfdSymbols, &usize);
#else
			symcount = bfd_canonicalize_symtab (bfdImage, bfdSymbols);

# if defined(BFD_MANAGER_GENERATE_ADDRESSES)
			if (nDataSymbols && DataSymbols)
			{
				for (s = 0; s < symcount; s++)
				{
					symbol_info syminfo;
					bfd_get_symbol_info (bfdImage, bfdSymbols[s], &syminfo);
					if (((bfdSymbols[s]->flags & BSF_DEBUGGING) == 0) &&
					    (syminfo.type == 'R' || syminfo.type == 'r' || /* read-only data */
					    syminfo.type == 'B' || syminfo.type == 'b' || /* uninited data */
					    syminfo.type == 'G' || syminfo.type == 'g' || /* inited data */ 
					    syminfo.type == 'C')) /* common data*/
					{
						unsigned long long sz = 0;
						if (bfd_get_flavour(bfdImage) == bfd_target_elf_flavour)
							sz = ((elf_symbol_type*) bfdSymbols[s])->internal_elf_sym.st_size;

						DataSyms = (data_symbol_t*) realloc (DataSyms, sizeof(data_symbol_t)*(nDataSyms+1));
						if (DataSyms == NULL)
							FATAL_ERROR ("Cannot allocate memory to allocate data symbols\n");
						DataSyms[nDataSyms].name = strdup (syminfo.name);
						DataSyms[nDataSyms].address = (void*) syminfo.value;
						DataSyms[nDataSyms].size = sz;
						nDataSyms++;
					}
				}

				*nDataSymbols = nDataSyms;
				*DataSymbols = DataSyms;
			}
# endif
#endif

			if (symcount < 0) 
			{
				/* There aren't symbols! */
				const char *errmsg = bfd_errmsg( bfd_get_error() );
				fprintf(stderr, "mpi2prv: WARNING! Cannot read symbol table for file '%s' : %s\n"
		                "         Addresses will not be translated into source code references\n",
				  file, errmsg);
			}
		}
	}

	*image = bfdImage;
	*symbols = bfdSymbols;

#if defined(DEBUG)
	printf ("BFD file=%s bfdImage = %p bfdSymbols = %p\n",
	  file, bfdImage, bfdSymbols);
#endif

}
Exemple #21
0
int main(int argc, char *argv[])
{
    bfd *abfd;
    bfd_init();
    abfd = bfd_openr(argv[1], NULL);
    if (abfd == NULL) {
        bfd_perror("bfd_openr");
        exit(1);
    }
    if (! bfd_check_format(abfd, bfd_object)) {
        bfd_perror("bfd_check_format");
    }

    printf("SYMBOL TABLE:\n");
    {
        long storage_needed;
        asymbol **symbol_table;
        long number_of_symbols;
        long i;

        storage_needed = bfd_get_symtab_upper_bound (abfd);

        printf("storage_need=%d\n", storage_needed);

        if (storage_needed < 0) {
            bfd_perror("bfd_get_symtab_upper_bound");
            exit(1);
        }
        if (storage_needed == 0) {
            printf("no symbols\n");
            exit(0);
        }
        symbol_table = (asymbol **)malloc (storage_needed);

        number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
        if (number_of_symbols < 0) {
            bfd_perror("bfd_canonicalize_symtab");
            exit(1);
        }
        for (i = 0; i < number_of_symbols; i++) {
            asymbol *asym = symbol_table[i];
            int symclass = bfd_decode_symclass(asym);
            symbol_info syminfo;
            bfd_symbol_info(asym, &syminfo);
            bfd_print_symbol_vandf(abfd, stdout, asym);
            printf(" 0x%x %s ", symclass,
                   bfd_is_undefined_symclass(symclass) ? "?" : " ");
            printf(" %s ", bfd_asymbol_name(asym));
            printf("%p ", bfd_asymbol_value(asym));

            // printf(" %d ", syminfo.value); /* asymbol_value */
            // printf(" %d ", syminfo.type); /* symclass */
            // printf(" %s ", syminfo.name); /* asymbol_name */
            printf(" %d ", syminfo.stab_type);
            printf(" %d ", syminfo.stab_other);
            printf(" %d ", syminfo.stab_desc);
            // printf(" %s ", syminfo.stab_name);
            printf("\n");
        }
    }
    printf("DYNAMIC SYMBOL TABLE:\n");
    {
        long storage_needed;
        asymbol **symbol_table;
        long number_of_symbols;
        long i;

        storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd);

        printf("storage_need=%d\n", storage_needed);

        if (storage_needed < 0) {
            bfd_perror("bfd_get_symtab_upper_bound");
            exit(1);
        }
        if (storage_needed == 0) {
            printf("no symbols\n");
            exit(0);
        }
        symbol_table = (asymbol **)malloc (storage_needed);

        number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, symbol_table);
        if (number_of_symbols < 0) {
            bfd_perror("bfd_canonicalize_symtab");
            exit(1);
        }
        for (i = 0; i < number_of_symbols; i++) {
            asymbol *asym = symbol_table[i];
            int symclass = bfd_decode_symclass(asym);
            symbol_info syminfo;
            bfd_symbol_info(asym, &syminfo);
            bfd_print_symbol_vandf(abfd, stdout, asym);
            printf(" 0x%x %s ", symclass,
                   bfd_is_undefined_symclass(symclass) ? "?" : " ");
            printf(" %s ", bfd_asymbol_name(asym));
            printf("%p ", bfd_asymbol_value(asym));

            // printf(" %d ", syminfo.value); /* asymbol_value */
            // printf(" %d ", syminfo.type); /* symclass */
            // printf(" %s ", syminfo.name); /* asymbol_name */
            printf(" %d ", syminfo.stab_type);
            printf(" %d ", syminfo.stab_other);
            printf(" %d ", syminfo.stab_desc);
            // printf(" %s ", syminfo.stab_name);
            printf("\n");
        }
    }
    exit(0);
}
Exemple #22
0
static
BOOL StackBackTrace(HANDLE hProcess, HANDLE hThread, PCONTEXT pContext)
{
	STACKFRAME StackFrame;

	HMODULE hModule = NULL;
	TCHAR szModule[MAX_PATH];

#ifdef HAVE_BFD
	bfd *abfd = NULL;
	asymbol **syms = NULL;	// The symbol table.
	long symcount = 0;	// Number of symbols in `syms'.
#endif /* HAVE_BFD */

	assert(!bSymInitialized);

	j_SymSetOptions(/* SYMOPT_UNDNAME | */ SYMOPT_LOAD_LINES);
	if(j_SymInitialize(hProcess, NULL, TRUE))
		bSymInitialized = TRUE;

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

	// Initialize the STACKFRAME structure for the first call.  This is only
	// necessary for Intel CPUs, and isn't mentioned in the documentation.
	StackFrame.AddrPC.Offset = pContext->Eip;
	StackFrame.AddrPC.Mode = AddrModeFlat;
	StackFrame.AddrStack.Offset = pContext->Esp;
	StackFrame.AddrStack.Mode = AddrModeFlat;
	StackFrame.AddrFrame.Offset = pContext->Ebp;
	StackFrame.AddrFrame.Mode = AddrModeFlat;

	rprintf( _T("Call stack:\r\n") );

	if(0)
		rprintf( _T("AddrPC     AddrReturn AddrFrame  AddrStack\r\n") );

	while ( 1 )
	{
		BOOL bSuccess = FALSE;
#ifdef HAVE_BFD
		const HMODULE hPrevModule = hModule;
#endif /* HAVE_BFD */
		TCHAR szSymName[512] = _T("");
		TCHAR szFileName[MAX_PATH] = _T("");
		DWORD LineNumber = 0;

		if(bSymInitialized)
		{
			if(!j_StackWalk(
					IMAGE_FILE_MACHINE_I386,
					hProcess,
					hThread,
					&StackFrame,
					pContext,
					NULL,
					j_SymFunctionTableAccess,
					j_SymGetModuleBase,
					NULL
				)
			)
				break;
		}
		else
		{
			if(!IntelStackWalk(
					IMAGE_FILE_MACHINE_I386,
					hProcess,
					hThread,
					&StackFrame,
					pContext,
					NULL,
					NULL,
					NULL,
					NULL
				)
			)
				break;
		}

		// Basic sanity check to make sure  the frame is OK.  Bail if not.
		if ( 0 == StackFrame.AddrFrame.Offset )
			break;

		if(0)
		{
			rprintf(
				_T("%08lX   %08lX   %08lX   %08lX\r\n"),
				StackFrame.AddrPC.Offset,
				StackFrame.AddrReturn.Offset,
				StackFrame.AddrFrame.Offset,
				StackFrame.AddrStack.Offset
			);
			rprintf(
				_T("%08lX   %08lX   %08lX   %08lX\r\n"),
				StackFrame.Params[0],
				StackFrame.Params[1],
				StackFrame.Params[2],
				StackFrame.Params[3]
			);
		}

		rprintf( _T("%08lX"), StackFrame.AddrPC.Offset);

		if((hModule = (HMODULE) GetModuleBase(StackFrame.AddrPC.Offset)) && GetModuleFileName(hModule, szModule, sizeof(szModule)))
		{
#ifndef HAVE_BFD
			rprintf( _T("  %s:ModulBase %08lX"), szModule, hModule);
#else /* HAVE_BFD */
			rprintf( _T("  %s:%08lX"), szModule, StackFrame.AddrPC.Offset);

			if(hModule != hPrevModule)
			{
				if(syms)
				{
					GlobalFree(syms);
					syms = NULL;
					symcount = 0;
				}

				if(abfd)
					bfd_close(abfd);

				if((abfd = bfd_openr (szModule, NULL)))
					if(bfd_check_format(abfd, bfd_object))
					{
						bfd_vma adjust_section_vma = 0;

						/* If we are adjusting section VMA's, change them all now.  Changing
						the BFD information is a hack.  However, we must do it, or
						bfd_find_nearest_line will not do the right thing.  */
						if ((adjust_section_vma = (bfd_vma) hModule - pe_data(abfd)->pe_opthdr.ImageBase))
						{
							asection *s;

							for (s = abfd->sections; s != NULL; s = s->next)
							{
								s->vma += adjust_section_vma;
								s->lma += adjust_section_vma;
							}
						}

						if(bfd_get_file_flags(abfd) & HAS_SYMS)
							/* Read in the symbol table.  */
							slurp_symtab(abfd, &syms, &symcount);
					}
			}

			if(!bSuccess && abfd && syms && symcount)
				if((bSuccess = BfdGetSymFromAddr(abfd, syms, symcount, StackFrame.AddrPC.Offset, szSymName, 512)))
				{
					/*
					framepointer = StackFrame.AddrFrame.Offset;
					hprocess = hProcess;
					*/

					BfdDemangleSymName(szSymName, szSymName, 512);

					rprintf( _T("  %s"), szSymName);

					if(BfdGetLineFromAddr(abfd, syms, symcount, StackFrame.AddrPC.Offset, szFileName, MAX_PATH, &LineNumber))
						rprintf( _T("  %s:%ld"), szFileName, LineNumber);
				}
#endif /* HAVE_BFD */

			if(!bSuccess && bSymInitialized)
				if((bSuccess = ImagehlpGetSymFromAddr(hProcess, StackFrame.AddrPC.Offset, szSymName, 512)))
				{
					rprintf( _T("  %s"), szSymName);

					ImagehlpDemangleSymName(szSymName, szSymName, 512);

					if(ImagehlpGetLineFromAddr(hProcess, StackFrame.AddrPC.Offset, szFileName, MAX_PATH, &LineNumber))
						rprintf( _T("  %s:%ld"), szFileName, LineNumber);
				}

			if(!bSuccess)
				if((bSuccess = PEGetSymFromAddr(hProcess, StackFrame.AddrPC.Offset, szSymName, 512)))
					rprintf( _T("  %s"), szSymName);
		}

		rprintf(_T("\r\n"));
	}

#ifdef HAVE_BFD
	if(syms)
	{
		GlobalFree(syms);
		syms = NULL;
		symcount = 0;
	}

	if(abfd)
		bfd_close(abfd);
#endif /* HAVE_BFD */

	if(bSymInitialized)
	{
		if(!j_SymCleanup(hProcess))
			assert(0);

		bSymInitialized = FALSE;
	}

	return TRUE;
}
static int
enable_break (void)
{
  int success = 0;

  struct minimal_symbol *msymbol;
  char **bkpt_namep;
  asection *interp_sect;

  /* First, remove all the solib event breakpoints.  Their addresses
     may have changed since the last time we ran the program.  */
  remove_solib_event_breakpoints ();

  interp_text_sect_low = interp_text_sect_high = 0;
  interp_plt_sect_low = interp_plt_sect_high = 0;

  /* Find the .interp section; if not found, warn the user and drop
     into the old breakpoint at symbol code.  */
  interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
  if (interp_sect)
    {
      unsigned int interp_sect_size;
      char *buf;
      CORE_ADDR load_addr;
      bfd *tmp_bfd;
      CORE_ADDR sym_addr = 0;

      /* Read the contents of the .interp section into a local buffer;
         the contents specify the dynamic linker this program uses.  */
      interp_sect_size = bfd_section_size (exec_bfd, interp_sect);
      buf = alloca (interp_sect_size);
      bfd_get_section_contents (exec_bfd, interp_sect,
				buf, 0, interp_sect_size);

      /* Now we need to figure out where the dynamic linker was
         loaded so that we can load its symbols and place a breakpoint
         in the dynamic linker itself.

         This address is stored on the stack.  However, I've been unable
         to find any magic formula to find it for Solaris (appears to
         be trivial on GNU/Linux).  Therefore, we have to try an alternate
         mechanism to find the dynamic linker's base address.  */
      tmp_bfd = bfd_openr (buf, gnutarget);
      if (tmp_bfd == NULL)
	goto bkpt_at_symbol;

      /* Make sure the dynamic linker's really a useful object.  */
      if (!bfd_check_format (tmp_bfd, bfd_object))
	{
	  warning (_("Unable to grok dynamic linker %s as an object file"), buf);
	  bfd_close (tmp_bfd);
	  goto bkpt_at_symbol;
	}

      /* We find the dynamic linker's base address by examining the
         current pc (which point at the entry point for the dynamic
         linker) and subtracting the offset of the entry point.  */
      load_addr = read_pc () - tmp_bfd->start_address;

      /* Record the relocated start and end address of the dynamic linker
         text and plt section for aix5_in_dynsym_resolve_code.  */
      interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
      if (interp_sect)
	{
	  interp_text_sect_low =
	    bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
	  interp_text_sect_high =
	    interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect);
	}
      interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
      if (interp_sect)
	{
	  interp_plt_sect_low =
	    bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
	  interp_plt_sect_high =
	    interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect);
	}

      /* Now try to set a breakpoint in the dynamic linker.  */
      for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++)
	{
	  sym_addr = bfd_lookup_symbol (tmp_bfd, *bkpt_namep);
	  if (sym_addr != 0)
	    break;
	}

      /* We're done with the temporary bfd.  */
      bfd_close (tmp_bfd);

      if (sym_addr != 0)
	{
	  create_solib_event_breakpoint (load_addr + sym_addr);
	  return 1;
	}

      /* For whatever reason we couldn't set a breakpoint in the dynamic
         linker.  Warn and drop into the old code.  */
    bkpt_at_symbol:
      warning (_("Unable to find dynamic linker breakpoint function.\nGDB will be unable to debug shared library initializers\nand track explicitly loaded dynamic code."));
    }

  /* Nothing good happened.  */
  success = 0;

  return (success);
}
Exemple #24
0
int
main (int argc, char **argv)
{
  char *name;
  char **prog_argv = NULL;
  struct bfd *prog_bfd;
  enum sim_stop reason;
  int sigrc = 0;
  int single_step = 0;
  RETSIGTYPE (*prev_sigint) ();

  myname = argv[0] + strlen (argv[0]);
  while (myname > argv[0] && myname[-1] != '/')
    --myname;

  /* INTERNAL: When MYNAME is `step', single step the simulator
     instead of allowing it to run free.  The sole purpose of this
     HACK is to allow the sim_resume interface's step argument to be
     tested without having to build/run gdb. */
  if (strlen (myname) > 4 && strcmp (myname - 4, "step") == 0)
    {
      single_step = 1;
    }

  /* Create an instance of the simulator.  */
  default_callback.init (&default_callback);
  sd = sim_open (SIM_OPEN_STANDALONE, &default_callback, NULL, argv);
  if (sd == 0)
    exit (1);
  if (STATE_MAGIC (sd) != SIM_MAGIC_NUMBER)
    {
      fprintf (stderr, "Internal error - bad magic number in simulator struct\n");
      abort ();
    }

  /* We can't set the endianness in the callback structure until
     sim_config is called, which happens in sim_open.  */
  default_callback.target_endian
    = (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN
       ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE);

  /* Was there a program to run?  */
  prog_argv = STATE_PROG_ARGV (sd);
  prog_bfd = STATE_PROG_BFD (sd);
  if (prog_argv == NULL || *prog_argv == NULL)
    usage ();

  name = *prog_argv;

  /* For simulators that don't open prog during sim_open() */
  if (prog_bfd == NULL)
    {
      prog_bfd = bfd_openr (name, 0);
      if (prog_bfd == NULL)
	{
	  fprintf (stderr, "%s: can't open \"%s\": %s\n",
		   myname, name, bfd_errmsg (bfd_get_error ()));
	  exit (1);
	}
      if (!bfd_check_format (prog_bfd, bfd_object))
	{
	  fprintf (stderr, "%s: \"%s\" is not an object file: %s\n",
		   myname, name, bfd_errmsg (bfd_get_error ()));
	  exit (1);
	}
    }

  if (STATE_VERBOSE_P (sd))
    printf ("%s %s\n", myname, name);

  /* Load the program into the simulator.  */
  if (sim_load (sd, name, prog_bfd, 0) == SIM_RC_FAIL)
    exit (1);

  /* Prepare the program for execution.  */
#ifdef HAVE_ENVIRON
  sim_create_inferior (sd, prog_bfd, prog_argv, environ);
#else
  sim_create_inferior (sd, prog_bfd, prog_argv, NULL);
#endif

  /* To accommodate relative file paths, chdir to sysroot now.  We
     mustn't do this until BFD has opened the program, else we wouldn't
     find the executable if it has a relative file path.  */
  if (simulator_sysroot[0] != '\0' && chdir (simulator_sysroot) < 0)
    {
      fprintf (stderr, "%s: can't change directory to \"%s\"\n",
	       myname, simulator_sysroot);
      exit (1);
    }

  /* Run/Step the program.  */
  if (single_step)
    {
      do
	{
	  prev_sigint = signal (SIGINT, cntrl_c);
	  sim_resume (sd, 1/*step*/, 0);
	  signal (SIGINT, prev_sigint);
	  sim_stop_reason (sd, &reason, &sigrc);

	  if ((reason == sim_stopped) &&
	      (sigrc == sim_signal_to_host (sd, SIM_SIGINT)))
	    break; /* exit on control-C */
	}
      /* remain on breakpoint or signals in oe mode*/
      while (((reason == sim_signalled) &&
	      (sigrc == sim_signal_to_host (sd, SIM_SIGTRAP))) ||
	     ((reason == sim_stopped) &&
	      (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)));
    }
  else
    {
      do
	{
#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
	  struct sigaction sa, osa;
	  sa.sa_handler = cntrl_c;
	  sigemptyset (&sa.sa_mask);
	  sa.sa_flags = 0;
	  sigaction (SIGINT, &sa, &osa);
	  prev_sigint = osa.sa_handler;
#else
	  prev_sigint = signal (SIGINT, cntrl_c);
#endif
	  sim_resume (sd, 0, sigrc);
	  signal (SIGINT, prev_sigint);
	  sim_stop_reason (sd, &reason, &sigrc);

	  if ((reason == sim_stopped) &&
	      (sigrc == sim_signal_to_host (sd, SIM_SIGINT)))
	    break; /* exit on control-C */

	  /* remain on signals in oe mode */
	} while ((reason == sim_stopped) &&
		 (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT));

    }
  /* Print any stats the simulator collected.  */
  if (STATE_VERBOSE_P (sd))
    sim_info (sd, 0);

  /* Shutdown the simulator.  */
  sim_close (sd, 0);

  /* If reason is sim_exited, then sigrc holds the exit code which we want
     to return.  If reason is sim_stopped or sim_signalled, then sigrc holds
     the signal that the simulator received; we want to return that to
     indicate failure.  */

  /* Why did we stop? */
  switch (reason)
    {
    case sim_signalled:
    case sim_stopped:
      if (sigrc != 0)
        fprintf (stderr, "program stopped with signal %d.\n", sigrc);
      break;

    case sim_exited:
      break;

    default:
      fprintf (stderr, "program in undefined state (%d:%d)\n", reason, sigrc);
      break;

    }

  return sigrc;
}
Exemple #25
0
int
main (int argc, char **argv)
{
  int o;
  int save_trace;
  bfd *prog;
#ifdef HAVE_networking
  char *console_port_s = 0;
#endif

  setbuf (stdout, 0);

  in_gdb = 0;

  while ((o = getopt (argc, argv, "tc:vdm:C")) != -1)
    switch (o)
      {
      case 't':
	trace++;
	break;
      case 'c':
#ifdef HAVE_networking
	console_port_s = optarg;
#else
	fprintf (stderr, "Nework console not available in this build.\n");
#endif
	break;
      case 'C':
#ifdef HAVE_TERMIOS_H
	m32c_use_raw_console = 1;
#else
	fprintf (stderr, "Raw console not available in this build.\n");
#endif
	break;
      case 'v':
	verbose++;
	break;
      case 'd':
	m32c_disassemble++;
	break;
      case 'm':
	if (strcmp (optarg, "r8c") == 0 || strcmp (optarg, "m16c") == 0)
	  default_machine = bfd_mach_m16c;
	else if (strcmp (optarg, "m32cm") == 0
		 || strcmp (optarg, "m32c") == 0)
	  default_machine = bfd_mach_m32c;
	else
	  {
	    fprintf (stderr, "Invalid machine: %s\n", optarg);
	    exit (1);
	  }
	break;
      case '?':
	fprintf (stderr,
		 "usage: run [-v] [-C] [-c port] [-t] [-d] [-m r8c|m16c|m32cm|m32c]"
		 " program\n");
	exit (1);
      }

  prog = bfd_openr (argv[optind], 0);
  if (!prog)
    {
      fprintf (stderr, "Can't read %s\n", argv[optind]);
      exit (1);
    }

  if (!bfd_check_format (prog, bfd_object))
    {
      fprintf (stderr, "%s not a m32c program\n", argv[optind]);
      exit (1);
    }

  save_trace = trace;
  trace = 0;
  m32c_load (prog);
  trace = save_trace;

#ifdef HAVE_networking
  if (console_port_s)
    setup_tcp_console (console_port_s);
#endif

  sim_disasm_init (prog);

  while (1)
    {
      int rc;

      if (trace)
	printf ("\n");

      if (m32c_disassemble)
	sim_disasm_one ();

      enable_counting = verbose;
      cycles++;
      rc = decode_opcode ();
      enable_counting = 0;

      if (M32C_HIT_BREAK (rc))
	done (1);
      else if (M32C_EXITED (rc))
	done (M32C_EXIT_STATUS (rc));
      else
	assert (M32C_STEPPED (rc));

      trace_register_changes ();

#ifdef TIMER_A
      update_timer_a ();
#endif
    }
}
Exemple #26
0
/**
* @brief  initialization of a symbol table
*
* @param filename
* @param arch_name
*/
void init_symbol_table(char* filename, char* arch_name)
{
  long i,j, digit;
  ENTRY newentry, *oldentry;
  SYM_FUNC *symp;
  asymbol *symptr;
  int key;
  bfd *abfd;

	if(!filename){
		skyeye_info("Can not get correct kernel filename!Maybe your skyeye.conf have something wrong!\n");
		return;
	}
	abfd = bfd_openr (filename, get_bfd_target(arch_name));

	if (!bfd_check_format(abfd, bfd_object)) {
		bfd_close(abfd);
		skyeye_log(Debug_log, __FUNCTION__, "wrong bfd format\n");
		return;
		//exit(0);
	}

	storage_needed = bfd_get_symtab_upper_bound(abfd);
	if (storage_needed < 0){
		printf("FAIL\n");
		exit(0);
	}

	symbol_table = (asymbol **) skyeye_mm_zero (storage_needed);
	if(symbol_table == NULL){
		fprintf(stderr, "Can not alloc memory for symbol table.\n");
		exit(0);
	}

	number_of_symbols =
		bfd_canonicalize_symtab (abfd, symbol_table);
	kernel_number = number_of_symbols; /* <tktan> BUG200106022219 */

	if (number_of_symbols < 0){
		printf("FAIL\n");
		exit(0);
	}

	if (!hcreate(number_of_symbols << 1)) {
		printf("Not enough memory for hash table\n");
		exit(0);
	}
	for (i = 0; i < number_of_symbols; i++) {
		symptr = symbol_table[i] ;
		key = symptr->value + symptr->section->vma; // adjust for section address

    if (((i<kernel_number) && (symbol_table[i]->flags == 0x01)) || // <tktan> BUG200105172154, BUG200106022219 
	((i<kernel_number) && (symbol_table[i]->flags == 0x02)) || // <tktan> BUG200204051654
	(symbol_table[i]->flags & 0x10)) { // Is a function symbol
      // printf("%x %8x %s\n", symbol_table[i]->flags, key, symbol_table[i]->name);

      // ***********************************************************
      // This is converting the function symbol value to char string
      // and use it as a key in the GNU hash table
      // ********************************************************
      newentry.key = (char *) skyeye_mm_zero(9);
      for (j=0;j<8;j++) {
        newentry.key[j] = itoa_tab[((key) >> (j << 2)) & 0xf] ;
      }
      newentry.key[8] = 0 ;

      // *************************************************
      // This is allocating memory for a struct funcsym
      // *************************************************
      symp = (SYM_FUNC *) skyeye_mm_zero(sizeof(SYM_FUNC));
      newentry.data = (char *) symp; 
      symp->name = (char *) symbol_table[i]->name ;
      symp->total_cycle = 0;
      symp->total_energy = 0;
      symp->instances = 0;

      // ***********************************************
      // Insert into hash table
      // *******************************************
      /* <tktan> BUG200106022219 */
      oldentry = hsearch(newentry, FIND) ;
      if (oldentry) { // was entered
        // printf("Duplicate Symbol: %x %s\n", key, symp->name);
        oldentry->data = (char *) symp ;	
      } else if (!hsearch(newentry, ENTER)) { 
        printf("Insufficient memory\n");
        exit(0) ;
      }
    }
  }
Exemple #27
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;
}
Exemple #28
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);
}
Exemple #29
0
int
main (int argc, char **argv)
{
  int o;
  int save_trace;
  bfd *prog;
  int rc;

  /* By default, we exit when an execution error occurs.  */
  execution_error_init_standalone ();

  while ((o = getopt_long (argc, argv, "tvdeEwi", sim_options, NULL)) != -1)
    {
      if (o == 'E')
	/* Stop processing the command line. This is so that any remaining
	   words on the command line that look like arguments will be passed
	   on to the program being simulated.  */
	break;

      if (o >= OPT_ACT)
	{
	  int e, a;

	  o -= OPT_ACT;
	  e = o / SIM_ERRACTION_NUM_ACTIONS;
	  a = o % SIM_ERRACTION_NUM_ACTIONS;
	  execution_error_set_action (e, a);
	}
      else switch (o)
	{
	case 't':
	  trace++;
	  break;
	case 'v':
	  verbose++;
	  break;
	case 'd':
	  disassemble++;
	  break;
	case 'e':
	  execution_error_init_standalone ();
	  break;
	case 'w':
	  execution_error_warn_all ();
	  break;
	case 'i':
	  execution_error_ignore_all ();
	  break;
	case '?':
	  {
	    int i;
	    fprintf (stderr,
		     "usage: run [options] program [arguments]\n");
	    fprintf (stderr,
		     "\t-v\t- increase verbosity.\n"
		     "\t-t\t- trace.\n"
		     "\t-d\t- disassemble.\n"
		     "\t-E\t- stop processing sim args\n"
		     "\t-e\t- exit on all execution errors.\n"
		     "\t-w\t- warn (do not exit) on all execution errors.\n"
		     "\t-i\t- ignore all execution errors.\n");
	    for (i=0; sim_options[i].name; i++)
	      fprintf (stderr, "\t--%s\n", sim_options[i].name);
	    exit (1);
	  }
	}
    }

  prog = bfd_openr (argv[optind], 0);
  if (!prog)
    {
      fprintf (stderr, "Can't read %s\n", argv[optind]);
      exit (1);
    }

  if (!bfd_check_format (prog, bfd_object))
    {
      fprintf (stderr, "%s not a rx program\n", argv[optind]);
      exit (1);
    }

  init_regs ();

  rx_in_gdb = 0;
  save_trace = trace;
  trace = 0;
  rx_load (prog, NULL);
  trace = save_trace;

  sim_disasm_init (prog);

  enable_counting = verbose;

  rc = setjmp (decode_jmp_buf);

  if (rc == 0)
    {
      if (!trace && !disassemble)
	{
	  /* This will longjmp to the above if an exception
	     happens.  */
	  for (;;)
	    decode_opcode ();
	}
      else
	while (1)
	  {

	    if (trace)
	      printf ("\n");

	    if (disassemble)
	      {
		enable_counting = 0;
		sim_disasm_one ();
		enable_counting = verbose;
	      }

	    rc = decode_opcode ();

	    if (trace)
	      trace_register_changes ();
	  }
    }

  if (RX_HIT_BREAK (rc))
    done (1);
  else if (RX_EXITED (rc))
    done (RX_EXIT_STATUS (rc));
  else if (RX_STOPPED (rc))
    {
      if (verbose)
	printf("Stopped on signal %d\n", RX_STOP_SIG (rc));
      exit(1);
    }
  done (0);
  exit (0);
}
Exemple #30
0
void replace_hello(const char *input_path, const char *output_path)
{
    bfd_init();

    bfd *ibfd = bfd_openr(input_path, NULL);

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

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

    bfd *obfd = bfd_openw(output_path, bfd_get_target(ibfd));

    if (obfd == NULL) {
        bfd_close_all_done(ibfd);
        errx(1, bfd_errmsg(bfd_get_error()));
    }

    if (!bfd_set_format(obfd, bfd_get_format(ibfd))) {
        bfd_close_all_done(ibfd);
        bfd_close_all_done(obfd);
        errx(1, "Setting obfd format failed: %s\n", bfd_errmsg(bfd_get_error()));
    }

    bfd_set_arch_info(obfd, bfd_get_arch_info(ibfd));

    // Create sections for .data
    asection *section = bfd_get_section_by_name(ibfd, ".data");
    while (section != NULL) {
        if (section->flags & SEC_HAS_CONTENTS) {
            char *section_contents = (char *)malloc(section->size);
            bfd_get_section_contents(ibfd, section, section_contents, 0, section->size);

            char *hello_pos = (char *)memmem(section_contents, section->size, "hello", 5);
            if (hello_pos != NULL) {
                if (bfd_make_section_anyway_with_flags(obfd, ".data", section->flags) == NULL) {
                    free(section_contents);
                    bfd_close_all_done(ibfd);
                    bfd_close_all_done(obfd);
                    errx(1, bfd_errmsg(bfd_get_error()));
                }
            }

            free(section_contents);
        }

        section = bfd_get_next_section_by_name(ibfd, section);
    }

    asection *comment_section = bfd_make_section_anyway_with_flags(obfd, ".comment.my_objcopy", SEC_HAS_CONTENTS);
    if (comment_section == NULL) {
        bfd_close_all_done(ibfd);
        bfd_close_all_done(obfd);
        errx(1, bfd_errmsg(bfd_get_error()));
    }

    if (!bfd_set_section_size(obfd, comment_section, 3)) {
        bfd_close_all_done(ibfd);
        bfd_close_all_done(obfd);
        errx(1, bfd_errmsg(bfd_get_error()));
    }

    if (!bfd_set_section_contents(obfd, comment_section, "moo", 0, 3)) {
        bfd_close_all_done(ibfd);
        bfd_close_all_done(obfd);
        errx(1, bfd_errmsg(bfd_get_error()));
    }

    // section = bfd_get_section_by_name(ibfd, ".data");
    // asection *osection = bfd_get_section_by_name(obfd, ".data");
    // if (osection == NULL) {
    // 	bfd_close_all_done(ibfd);
    // 	bfd_close_all_done(obfd);
    // 	errx(1, bfd_errmsg(bfd_get_error()));
    // }
    // while (section != NULL) {
    // 	if (section->flags & SEC_HAS_CONTENTS) {
    // 		char *section_contents = (char *)malloc(section->size);
    // 		bfd_get_section_contents(ibfd, section, section_contents, 0, section->size);
    //
    // 		char *hello_pos = (char *)memmem(section_contents, section->size, "hello", 5);
    // 		if (hello_pos != NULL) {
    // 			hello_pos[1] = 'o';
    // 			hello_pos[4] = 'a';
    // 			if (bfd_set_section_contents(obfd, osection, section_contents, 0, section->size)) {
    // 				free(section_contents);
    // 				bfd_close_all_done(ibfd);
    // 				bfd_close_all_done(obfd);
    // 				errx(1, bfd_errmsg(bfd_get_error()));
    // 			}
    // 		}
    //
    // 		free(section_contents);
    // 		osection = bfd_get_next_section_by_name(obfd, osection);
    // 	}
    //
    // 	section = bfd_get_next_section_by_name(ibfd, section);
    // }

    if (!bfd_close(obfd))
        errx(1, "Closing obfd failed: %s\n", bfd_errmsg(bfd_get_error()));

    if (!bfd_close(ibfd))
        errx(1, "Closing ibfd failed: %s\n", bfd_errmsg(bfd_get_error()));
}