/* Work with executable files, for GDB. 

   Copyright (C) 1988-2019 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "frame.h"
#include "inferior.h"
#include "target.h"
#include "gdbcmd.h"
#include "language.h"
#include "filenames.h"
#include "symfile.h"
#include "objfiles.h"
#include "completer.h"
#include "value.h"
#include "exec.h"
#include "observable.h"
#include "arch-utils.h"
#include "gdbthread.h"
#include "progspace.h"
#include "gdb_bfd.h"
#include "gcore.h"
#include "source.h"

#include <fcntl.h>
#include "readline/readline.h"
#include "gdbcore.h"

#include <ctype.h>
#include <sys/stat.h>
#include "solist.h"
#include <algorithm>
#include "gdbsupport/pathstuff.h"

void (*deprecated_file_changed_hook) (const char *);

static const target_info exec_target_info = {
  "exec",
  N_("Local exec file"),
  N_("Use an executable file as a target.\n\
Specify the filename of the executable file.")
};

/* The target vector for executable files.  */

struct exec_target final : public target_ops
{
  const target_info &info () const override
  { return exec_target_info; }

  strata stratum () const override { return file_stratum; }

  void close () override;
  enum target_xfer_status xfer_partial (enum target_object object,
					const char *annex,
					gdb_byte *readbuf,
					const gdb_byte *writebuf,
					ULONGEST offset, ULONGEST len,
					ULONGEST *xfered_len) override;
  struct target_section_table *get_section_table () override;
  void files_info () override;

  bool has_memory () override;
  char *make_corefile_notes (bfd *, int *) override;
  int find_memory_regions (find_memory_region_ftype func, void *data) override;
};

static exec_target exec_ops;

/* Whether to open exec and core files read-only or read-write.  */

bool write_files = false;
static void
show_write_files (struct ui_file *file, int from_tty,
		  struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("Writing into executable and core files is %s.\n"),
		    value);
}


static void
exec_target_open (const char *args, int from_tty)
{
  target_preopen (from_tty);
  exec_file_attach (args, from_tty);
}

/* Close and clear exec_bfd.  If we end up with no target sections to
   read memory from, this unpushes the exec_ops target.  */

void
exec_close (void)
{
  if (exec_bfd)
    {
      bfd *abfd = exec_bfd;

      gdb_bfd_unref (abfd);

      /* Removing target sections may close the exec_ops target.
	 Clear exec_bfd before doing so to prevent recursion.  */
      exec_bfd = NULL;
      exec_bfd_mtime = 0;

      remove_target_sections (&exec_bfd);

      xfree (exec_filename);
      exec_filename = NULL;
    }
}

/* This is the target_close implementation.  Clears all target
   sections and closes all executable bfds from all program spaces.  */

void
exec_target::close ()
{
  struct program_space *ss;
  scoped_restore_current_program_space restore_pspace;

  ALL_PSPACES (ss)
    {
      set_current_program_space (ss);
      clear_section_table (current_target_sections);
      exec_close ();
    }
}

/* See gdbcore.h.  */

void
try_open_exec_file (const char *exec_file_host, struct inferior *inf,
		    symfile_add_flags add_flags)
{
  struct gdb_exception prev_err;

  /* exec_file_attach and symbol_file_add_main may throw an error if the file
     cannot be opened either locally or remotely.

     This happens for example, when the file is first found in the local
     sysroot (above), and then disappears (a TOCTOU race), or when it doesn't
     exist in the target filesystem, or when the file does exist, but
     is not readable.

     Even without a symbol file, the remote-based debugging session should
     continue normally instead of ending abruptly.  Hence we catch thrown
     errors/exceptions in the following code.  */
  try
    {
      /* We must do this step even if exec_file_host is NULL, so that
	 exec_file_attach will clear state.  */
      exec_file_attach (exec_file_host, add_flags & SYMFILE_VERBOSE);
    }
  catch (gdb_exception_error &err)
    {
      if (err.message != NULL)
	warning ("%s", err.what ());

      prev_err = std::move (err);
    }

  if (exec_file_host != NULL)
    {
      try
	{
	  symbol_file_add_main (exec_file_host, add_flags);
	}
      catch (const gdb_exception_error &err)
	{
	  if (!exception_print_same (prev_err, err))
	    warning ("%s", err.what ());
	}
    }
}

/* See gdbcore.h.  */

void
exec_file_locate_attach (int pid, int defer_bp_reset, int from_tty)
{
  char *exec_file_target;
  symfile_add_flags add_flags = 0;

  /* Do nothing if we already have an executable filename.  */
  if (get_exec_file (0) != NULL)
    return;

  /* Try to determine a filename from the process itself.  */
  exec_file_target = target_pid_to_exec_file (pid);
  if (exec_file_target == NULL)
    {
      warning (_("No executable has been specified and target does not "
		 "support\n"
		 "determining executable automatically.  "
		 "Try using the \"file\" command."));
      return;
    }

  gdb::unique_xmalloc_ptr<char> exec_file_host
    = exec_file_find (exec_file_target, NULL);

  if (defer_bp_reset)
    add_flags |= SYMFILE_DEFER_BP_RESET;

  if (from_tty)
    add_flags |= SYMFILE_VERBOSE;

  /* Attempt to open the exec file.  */
  try_open_exec_file (exec_file_host.get (), current_inferior (), add_flags);
}

/* Set FILENAME as the new exec file.

   This function is intended to be behave essentially the same
   as exec_file_command, except that the latter will detect when
   a target is being debugged, and will ask the user whether it
   should be shut down first.  (If the answer is "no", then the
   new file is ignored.)

   This file is used by exec_file_command, to do the work of opening
   and processing the exec file after any prompting has happened.

   And, it is used by child_attach, when the attach command was
   given a pid but not a exec pathname, and the attach command could
   figure out the pathname from the pid.  (In this case, we shouldn't
   ask the user whether the current target should be shut down --
   we're supplying the exec pathname late for good reason.)  */

void
exec_file_attach (const char *filename, int from_tty)
{
  /* First, acquire a reference to the current exec_bfd.  We release
     this at the end of the function; but acquiring it now lets the
     BFD cache return it if this call refers to the same file.  */
  gdb_bfd_ref_ptr exec_bfd_holder = gdb_bfd_ref_ptr::new_reference (exec_bfd);

  /* Remove any previous exec file.  */
  exec_close ();

  /* Now open and digest the file the user requested, if any.  */

  if (!filename)
    {
      if (from_tty)
        printf_unfiltered (_("No executable file now.\n"));

      set_gdbarch_from_file (NULL);
    }
  else
    {
      int load_via_target = 0;
      const char *scratch_pathname, *canonical_pathname;
      int scratch_chan;
      struct target_section *sections = NULL, *sections_end = NULL;
      char **matching;

      if (is_target_filename (filename))
	{
	  if (target_filesystem_is_local ())
	    filename += strlen (TARGET_SYSROOT_PREFIX);
	  else
	    load_via_target = 1;
	}

      gdb::unique_xmalloc_ptr<char> canonical_storage, scratch_storage;
      if (load_via_target)
	{
	  /* gdb_bfd_fopen does not support "target:" filenames.  */
	  if (write_files)
	    warning (_("writing into executable files is "
		       "not supported for %s sysroots"),
		     TARGET_SYSROOT_PREFIX);

	  scratch_pathname = filename;
	  scratch_chan = -1;
	  canonical_pathname = scratch_pathname;
	}
      else
	{
	  scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST,
				filename, write_files ?
				O_RDWR | O_BINARY : O_RDONLY | O_BINARY,
				&scratch_storage);
#if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__)
	  if (scratch_chan < 0)
	    {
	      char *exename = (char *) alloca (strlen (filename) + 5);

	      strcat (strcpy (exename, filename), ".exe");
	      scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST,
				    exename, write_files ?
				    O_RDWR | O_BINARY
				    : O_RDONLY | O_BINARY,
				    &scratch_storage);
	    }
#endif
	  if (scratch_chan < 0)
	    perror_with_name (filename);

	  scratch_pathname = scratch_storage.get ();

	  /* gdb_bfd_open (and its variants) prefers canonicalized
	     pathname for better BFD caching.  */
	  canonical_storage = gdb_realpath (scratch_pathname);
	  canonical_pathname = canonical_storage.get ();
	}

      gdb_bfd_ref_ptr temp;
      if (write_files && !load_via_target)
	temp = gdb_bfd_fopen (canonical_pathname, gnutarget,
			      FOPEN_RUB, scratch_chan);
      else
	temp = gdb_bfd_open (canonical_pathname, gnutarget, scratch_chan);
      exec_bfd = temp.release ();

      if (!exec_bfd)
	{
	  error (_("\"%s\": could not open as an executable file: %s."),
		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
	}

      /* gdb_realpath_keepfile resolves symlinks on the local
	 filesystem and so cannot be used for "target:" files.  */
      gdb_assert (exec_filename == NULL);
      if (load_via_target)
	exec_filename = xstrdup (bfd_get_filename (exec_bfd));
      else
	exec_filename = gdb_realpath_keepfile (scratch_pathname).release ();

      if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching))
	{
	  /* Make sure to close exec_bfd, or else "run" might try to use
	     it.  */
	  exec_close ();
	  error (_("\"%s\": not in executable format: %s"),
		 scratch_pathname,
		 gdb_bfd_errmsg (bfd_get_error (), matching).c_str ());
	}

      if (build_section_table (exec_bfd, &sections, &sections_end))
	{
	  /* Make sure to close exec_bfd, or else "run" might try to use
	     it.  */
	  exec_close ();
	  error (_("\"%s\": can't find the file sections: %s"),
		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
	}

      exec_bfd_mtime = bfd_get_mtime (exec_bfd);

      validate_files ();

      set_gdbarch_from_file (exec_bfd);

      /* Add the executable's sections to the current address spaces'
	 list of sections.  This possibly pushes the exec_ops
	 target.  */
      add_target_sections (&exec_bfd, sections, sections_end);
      xfree (sections);

      /* Tell display code (if any) about the changed file name.  */
      if (deprecated_exec_file_display_hook)
	(*deprecated_exec_file_display_hook) (filename);
    }

  bfd_cache_close_all ();
  gdb::observers::executable_changed.notify ();
}

/*  Process the first arg in ARGS as the new exec file.

   Note that we have to explicitly ignore additional args, since we can
   be called from file_command(), which also calls symbol_file_command()
   which can take multiple args.
   
   If ARGS is NULL, we just want to close the exec file.  */

static void
exec_file_command (const char *args, int from_tty)
{
  if (from_tty && target_has_execution
      && !query (_("A program is being debugged already.\n"
		   "Are you sure you want to change the file? ")))
    error (_("File not changed."));

  if (args)
    {
      /* Scan through the args and pick up the first non option arg
         as the filename.  */

      gdb_argv built_argv (args);
      char **argv = built_argv.get ();

      for (; (*argv != NULL) && (**argv == '-'); argv++)
        {;
        }
      if (*argv == NULL)
        error (_("No executable file name was specified"));

      gdb::unique_xmalloc_ptr<char> filename (tilde_expand (*argv));
      exec_file_attach (filename.get (), from_tty);
    }
  else
    exec_file_attach (NULL, from_tty);
}

/* Set both the exec file and the symbol file, in one command.
   What a novelty.  Why did GDB go through four major releases before this
   command was added?  */

static void
file_command (const char *arg, int from_tty)
{
  /* FIXME, if we lose on reading the symbol file, we should revert
     the exec file, but that's rough.  */
  exec_file_command (arg, from_tty);
  symbol_file_command (arg, from_tty);
  if (deprecated_file_changed_hook)
    deprecated_file_changed_hook (arg);
}


/* Locate all mappable sections of a BFD file.
   table_pp_char is a char * to get it through bfd_map_over_sections;
   we cast it back to its proper type.  */

static void
add_to_section_table (bfd *abfd, struct bfd_section *asect,
		      void *table_pp_char)
{
  struct target_section **table_pp = (struct target_section **) table_pp_char;
  flagword aflag;

  gdb_assert (abfd == asect->owner);

  /* Check the section flags, but do not discard zero-length sections, since
     some symbols may still be attached to this section.  For instance, we
     encountered on sparc-solaris 2.10 a shared library with an empty .bss
     section to which a symbol named "_end" was attached.  The address
     of this symbol still needs to be relocated.  */
  aflag = bfd_section_flags (asect);
  if (!(aflag & SEC_ALLOC))
    return;

  (*table_pp)->owner = NULL;
  (*table_pp)->the_bfd_section = asect;
  (*table_pp)->addr = bfd_section_vma (asect);
  (*table_pp)->endaddr = (*table_pp)->addr + bfd_section_size (asect);
  (*table_pp)++;
}

/* See exec.h.  */

void
clear_section_table (struct target_section_table *table)
{
  xfree (table->sections);
  table->sections = table->sections_end = NULL;
}

/* Resize section table TABLE by ADJUSTMENT.
   ADJUSTMENT may be negative, in which case the caller must have already
   removed the sections being deleted.
   Returns the old size.  */

static int
resize_section_table (struct target_section_table *table, int adjustment)
{
  int old_count;
  int new_count;

  old_count = table->sections_end - table->sections;

  new_count = adjustment + old_count;

  if (new_count)
    {
      table->sections = XRESIZEVEC (struct target_section, table->sections,
				    new_count);
      table->sections_end = table->sections + new_count;
    }
  else
    clear_section_table (table);

  return old_count;
}

/* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR.
   Returns 0 if OK, 1 on error.  */

int
build_section_table (struct bfd *some_bfd, struct target_section **start,
		     struct target_section **end)
{
  unsigned count;

  count = bfd_count_sections (some_bfd);
  if (*start)
    xfree (* start);
  *start = XNEWVEC (struct target_section, count);
  *end = *start;
  bfd_map_over_sections (some_bfd, add_to_section_table, (char *) end);
  if (*end > *start + count)
    internal_error (__FILE__, __LINE__,
		    _("failed internal consistency check"));
  /* We could realloc the table, but it probably loses for most files.  */
  return 0;
}

/* Add the sections array defined by [SECTIONS..SECTIONS_END[ to the
   current set of target sections.  */

void
add_target_sections (void *owner,
		     struct target_section *sections,
		     struct target_section *sections_end)
{
  int count;
  struct target_section_table *table = current_target_sections;

  count = sections_end - sections;

  if (count > 0)
    {
      int space = resize_section_table (table, count);
      int i;

      for (i = 0; i < count; ++i)
	{
	  table->sections[space + i] = sections[i];
	  table->sections[space + i].owner = owner;
	}

      /* If these are the first file sections we can provide memory
	 from, push the file_stratum target.  */
      if (!target_is_pushed (&exec_ops))
	push_target (&exec_ops);
    }
}

/* Add the sections of OBJFILE to the current set of target sections.  */

void
add_target_sections_of_objfile (struct objfile *objfile)
{
  struct target_section_table *table = current_target_sections;
  struct obj_section *osect;
  int space;
  unsigned count = 0;
  struct target_section *ts;

  if (objfile == NULL)
    return;

  /* Compute the number of sections to add.  */
  ALL_OBJFILE_OSECTIONS (objfile, osect)
    {
      if (bfd_section_size (osect->the_bfd_section) == 0)
	continue;
      count++;
    }

  if (count == 0)
    return;

  space = resize_section_table (table, count);

  ts = table->sections + space;

  ALL_OBJFILE_OSECTIONS (objfile, osect)
    {
      if (bfd_section_size (osect->the_bfd_section) == 0)
	continue;

      gdb_assert (ts < table->sections + space + count);

      ts->addr = obj_section_addr (osect);
      ts->endaddr = obj_section_endaddr (osect);
      ts->the_bfd_section = osect->the_bfd_section;
      ts->owner = (void *) objfile;

      ts++;
    }
}

/* Remove all target sections owned by OWNER.
   OWNER must be the same value passed to add_target_sections.  */

void
remove_target_sections (void *owner)
{
  struct target_section *src, *dest;
  struct target_section_table *table = current_target_sections;

  gdb_assert (owner != NULL);

  dest = table->sections;
  for (src = table->sections; src < table->sections_end; src++)
    if (src->owner != owner)
      {
	/* Keep this section.  */
	if (dest < src)
	  *dest = *src;
	dest++;
      }

  /* If we've dropped any sections, resize the section table.  */
  if (dest < src)
    {
      int old_count;

      old_count = resize_section_table (table, dest - src);

      /* If we don't have any more sections to read memory from,
	 remove the file_stratum target from the stack.  */
      if (old_count + (dest - src) == 0)
	{
	  struct program_space *pspace;

	  ALL_PSPACES (pspace)
	    if (pspace->target_sections.sections
		!= pspace->target_sections.sections_end)
	      return;

	  unpush_target (&exec_ops);
	}
    }
}



enum target_xfer_status
exec_read_partial_read_only (gdb_byte *readbuf, ULONGEST offset,
			     ULONGEST len, ULONGEST *xfered_len)
{
  /* It's unduly pedantic to refuse to look at the executable for
     read-only pieces; so do the equivalent of readonly regions aka
     QTro packet.  */
  if (exec_bfd != NULL)
    {
      asection *s;
      bfd_size_type size;
      bfd_vma vma;

      for (s = exec_bfd->sections; s; s = s->next)
	{
	  if ((s->flags & SEC_LOAD) == 0
	      || (s->flags & SEC_READONLY) == 0)
	    continue;

	  vma = s->vma;
	  size = bfd_section_size (s);
	  if (vma <= offset && offset < (vma + size))
	    {
	      ULONGEST amt;

	      amt = (vma + size) - offset;
	      if (amt > len)
		amt = len;

	      amt = bfd_get_section_contents (exec_bfd, s,
					      readbuf, offset - vma, amt);

	      if (amt == 0)
		return TARGET_XFER_EOF;
	      else
		{
		  *xfered_len = amt;
		  return TARGET_XFER_OK;
		}
	    }
	}
    }

  /* Indicate failure to find the requested memory block.  */
  return TARGET_XFER_E_IO;
}

/* Return all read-only memory ranges found in the target section
   table defined by SECTIONS and SECTIONS_END, starting at (and
   intersected with) MEMADDR for LEN bytes.  */

static std::vector<mem_range>
section_table_available_memory (CORE_ADDR memaddr, ULONGEST len,
				struct target_section *sections,
				struct target_section *sections_end)
{
  std::vector<mem_range> memory;

  for (target_section *p = sections; p < sections_end; p++)
    {
      if ((bfd_section_flags (p->the_bfd_section) & SEC_READONLY) == 0)
	continue;

      /* Copy the meta-data, adjusted.  */
      if (mem_ranges_overlap (p->addr, p->endaddr - p->addr, memaddr, len))
	{
	  ULONGEST lo1, hi1, lo2, hi2;

	  lo1 = memaddr;
	  hi1 = memaddr + len;

	  lo2 = p->addr;
	  hi2 = p->endaddr;

	  CORE_ADDR start = std::max (lo1, lo2);
	  int length = std::min (hi1, hi2) - start;

	  memory.emplace_back (start, length);
	}
    }

  return memory;
}

enum target_xfer_status
section_table_read_available_memory (gdb_byte *readbuf, ULONGEST offset,
				     ULONGEST len, ULONGEST *xfered_len)
{
  target_section_table *table = target_get_section_table (&exec_ops);
  std::vector<mem_range> available_memory
    = section_table_available_memory (offset, len,
				      table->sections, table->sections_end);

  normalize_mem_ranges (&available_memory);

  for (const mem_range &r : available_memory)
    {
      if (mem_ranges_overlap (r.start, r.length, offset, len))
	{
	  CORE_ADDR end;
	  enum target_xfer_status status;

	  /* Get the intersection window.  */
	  end = std::min<CORE_ADDR> (offset + len, r.start + r.length);

	  gdb_assert (end - offset <= len);

	  if (offset >= r.start)
	    status = exec_read_partial_read_only (readbuf, offset,
						  end - offset,
						  xfered_len);
	  else
	    {
	      *xfered_len = r.start - offset;
	      status = TARGET_XFER_UNAVAILABLE;
	    }
	  return status;
	}
    }

  *xfered_len = len;
  return TARGET_XFER_UNAVAILABLE;
}

enum target_xfer_status
section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
				   ULONGEST offset, ULONGEST len,
				   ULONGEST *xfered_len,
				   struct target_section *sections,
				   struct target_section *sections_end,
				   const char *section_name)
{
  int res;
  struct target_section *p;
  ULONGEST memaddr = offset;
  ULONGEST memend = memaddr + len;

  if (len == 0)
    internal_error (__FILE__, __LINE__,
		    _("failed internal consistency check"));

  for (p = sections; p < sections_end; p++)
    {
      struct bfd_section *asect = p->the_bfd_section;
      bfd *abfd = asect->owner;

      if (section_name && strcmp (section_name, asect->name) != 0)
	continue;		/* not the section we need.  */
      if (memaddr >= p->addr)
        {
	  if (memend <= p->endaddr)
	    {
	      /* Entire transfer is within this section.  */
	      if (writebuf)
		res = bfd_set_section_contents (abfd, asect,
						writebuf, memaddr - p->addr,
						len);
	      else
		res = bfd_get_section_contents (abfd, asect,
						readbuf, memaddr - p->addr,
						len);

	      if (res != 0)
		{
		  *xfered_len = len;
		  return TARGET_XFER_OK;
		}
	      else
		return TARGET_XFER_EOF;
	    }
	  else if (memaddr >= p->endaddr)
	    {
	      /* This section ends before the transfer starts.  */
	      continue;
	    }
	  else
	    {
	      /* This section overlaps the transfer.  Just do half.  */
	      len = p->endaddr - memaddr;
	      if (writebuf)
		res = bfd_set_section_contents (abfd, asect,
						writebuf, memaddr - p->addr,
						len);
	      else
		res = bfd_get_section_contents (abfd, asect,
						readbuf, memaddr - p->addr,
						len);
	      if (res != 0)
		{
		  *xfered_len = len;
		  return TARGET_XFER_OK;
		}
	      else
		return TARGET_XFER_EOF;
	    }
        }
    }

  return TARGET_XFER_EOF;		/* We can't help.  */
}

struct target_section_table *
exec_target::get_section_table ()
{
  return current_target_sections;
}

enum target_xfer_status
exec_target::xfer_partial (enum target_object object,
			   const char *annex, gdb_byte *readbuf,
			   const gdb_byte *writebuf,
			   ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
{
  struct target_section_table *table = get_section_table ();

  if (object == TARGET_OBJECT_MEMORY)
    return section_table_xfer_memory_partial (readbuf, writebuf,
					      offset, len, xfered_len,
					      table->sections,
					      table->sections_end,
					      NULL);
  else
    return TARGET_XFER_E_IO;
}


void
print_section_info (struct target_section_table *t, bfd *abfd)
{
  struct gdbarch *gdbarch = gdbarch_from_bfd (abfd);
  struct target_section *p;
  /* FIXME: 16 is not wide enough when gdbarch_addr_bit > 64.  */
  int wid = gdbarch_addr_bit (gdbarch) <= 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)
    {
      /* gcc-3.4 does not like the initialization in
	 <p == t->sections_end>.  */
      bfd_vma displacement = 0;
      bfd_vma entry_point;

      for (p = t->sections; p < t->sections_end; p++)
	{
	  struct bfd_section *psect = p->the_bfd_section;

	  if ((bfd_section_flags (psect) & (SEC_ALLOC | SEC_LOAD))
	      != (SEC_ALLOC | SEC_LOAD))
	    continue;

	  if (bfd_section_vma (psect) <= abfd->start_address
	      && abfd->start_address < (bfd_section_vma (psect)
					+ bfd_section_size (psect)))
	    {
	      displacement = p->addr - bfd_section_vma (psect);
	      break;
	    }
	}
      if (p == t->sections_end)
	warning (_("Cannot find section for the entry point of %s."),
		 bfd_get_filename (abfd));

      entry_point = gdbarch_addr_bits_remove (gdbarch, 
					      bfd_get_start_address (abfd) 
						+ displacement);
      printf_filtered (_("\tEntry point: %s\n"),
		       paddress (gdbarch, entry_point));
    }
  for (p = t->sections; p < t->sections_end; p++)
    {
      struct bfd_section *psect = p->the_bfd_section;
      bfd *pbfd = psect->owner;

      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 (psect->filepos, 8));
      printf_filtered (" is %s", bfd_section_name (psect));
      if (pbfd != abfd)
	printf_filtered (" in %s", bfd_get_filename (pbfd));
      printf_filtered ("\n");
    }
}

void
exec_target::files_info ()
{
  if (exec_bfd)
    print_section_info (current_target_sections, exec_bfd);
  else
    puts_filtered (_("\t<no file loaded>\n"));
}

static void
set_section_command (const char *args, int from_tty)
{
  struct target_section *p;
  const char *secname;
  unsigned seclen;
  unsigned long secaddr;
  char secprint[100];
  long offset;
  struct target_section_table *table;

  if (args == 0)
    error (_("Must specify section name and its virtual address"));

  /* Parse out section name.  */
  for (secname = args; !isspace (*args); args++);
  seclen = args - secname;

  /* Parse out new virtual address.  */
  secaddr = parse_and_eval_address (args);

  table = current_target_sections;
  for (p = table->sections; p < table->sections_end; p++)
    {
      if (!strncmp (secname, bfd_section_name (p->the_bfd_section), seclen)
	  && bfd_section_name (p->the_bfd_section)[seclen] == '\0')
	{
	  offset = secaddr - p->addr;
	  p->addr += offset;
	  p->endaddr += offset;
	  if (from_tty)
	    exec_ops.files_info ();
	  return;
	}
    }
  if (seclen >= sizeof (secprint))
    seclen = sizeof (secprint) - 1;
  strncpy (secprint, secname, seclen);
  secprint[seclen] = '\0';
  error (_("Section %s not found"), secprint);
}

/* If we can find a section in FILENAME with BFD index INDEX, adjust
   it to ADDRESS.  */

void
exec_set_section_address (const char *filename, int index, CORE_ADDR address)
{
  struct target_section *p;
  struct target_section_table *table;

  table = current_target_sections;
  for (p = table->sections; p < table->sections_end; p++)
    {
      if (filename_cmp (filename, p->the_bfd_section->owner->filename) == 0
	  && index == p->the_bfd_section->index)
	{
	  p->endaddr += address - p->addr;
	  p->addr = address;
	}
    }
}

bool
exec_target::has_memory ()
{
  /* We can provide memory if we have any file/target sections to read
     from.  */
  return (current_target_sections->sections
	  != current_target_sections->sections_end);
}

char *
exec_target::make_corefile_notes (bfd *obfd, int *note_size)
{
  error (_("Can't create a corefile"));
}

int
exec_target::find_memory_regions (find_memory_region_ftype func, void *data)
{
  return objfile_find_memory_regions (this, func, data);
}

void
_initialize_exec (void)
{
  struct cmd_list_element *c;

  if (!dbx_commands)
    {
      c = add_cmd ("file", class_files, file_command, _("\
Use FILE as program to be debugged.\n\
It is read for its symbols, for getting the contents of pure memory,\n\
and it is the program executed when you use the `run' command.\n\
If FILE cannot be found as specified, your execution directory path\n\
($PATH) is searched for a command of that name.\n\
No arg means to have no executable file and no symbols."), &cmdlist);
      set_cmd_completer (c, filename_completer);
    }

  c = add_cmd ("exec-file", class_files, exec_file_command, _("\
Use FILE as program for getting contents of pure memory.\n\
If FILE cannot be found as specified, your execution directory path\n\
is searched for a command of that name.\n\
No arg means have no executable file."), &cmdlist);
  set_cmd_completer (c, filename_completer);

  add_com ("section", class_files, set_section_command, _("\
Change the base address of section SECTION of the exec file to ADDR.\n\
This can be used if the exec file does not contain section addresses,\n\
(such as in the a.out format), or when the addresses specified in the\n\
file itself are wrong.  Each section must be changed separately.  The\n\
``info files'' command lists all the sections and their addresses."));

  add_setshow_boolean_cmd ("write", class_support, &write_files, _("\
Set writing into executable and core files."), _("\
Show writing into executable and core files."), NULL,
			   NULL,
			   show_write_files,
			   &setlist, &showlist);

  add_target (exec_target_info, exec_target_open, filename_completer);
}
