119370Spst/* Work with executable files, for GDB.
219370Spst
3130809Smarcel   Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
4130809Smarcel   1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation,
5130809Smarcel   Inc.
6130809Smarcel
798948Sobrien   This file is part of GDB.
819370Spst
998948Sobrien   This program is free software; you can redistribute it and/or modify
1098948Sobrien   it under the terms of the GNU General Public License as published by
1198948Sobrien   the Free Software Foundation; either version 2 of the License, or
1298948Sobrien   (at your option) any later version.
1319370Spst
1498948Sobrien   This program is distributed in the hope that it will be useful,
1598948Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1698948Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1798948Sobrien   GNU General Public License for more details.
1819370Spst
1998948Sobrien   You should have received a copy of the GNU General Public License
2098948Sobrien   along with this program; if not, write to the Free Software
2198948Sobrien   Foundation, Inc., 59 Temple Place - Suite 330,
2298948Sobrien   Boston, MA 02111-1307, USA.  */
2319370Spst
2419370Spst#include "defs.h"
2519370Spst#include "frame.h"
2619370Spst#include "inferior.h"
2719370Spst#include "target.h"
2819370Spst#include "gdbcmd.h"
2919370Spst#include "language.h"
3019370Spst#include "symfile.h"
3119370Spst#include "objfiles.h"
3298948Sobrien#include "completer.h"
3398948Sobrien#include "value.h"
34130809Smarcel#include "exec.h"
3519370Spst
3619370Spst#ifdef USG
3719370Spst#include <sys/types.h>
3819370Spst#endif
3919370Spst
4019370Spst#include <fcntl.h>
41130809Smarcel#include "readline/readline.h"
4219370Spst#include "gdb_string.h"
4319370Spst
4419370Spst#include "gdbcore.h"
4519370Spst
4619370Spst#include <ctype.h>
4719370Spst#include "gdb_stat.h"
4819370Spst#ifndef O_BINARY
4919370Spst#define O_BINARY 0
5019370Spst#endif
5119370Spst
5219370Spst#include "xcoffsolib.h"
5319370Spst
5498948Sobrienstruct vmap *map_vmap (bfd *, bfd *);
5519370Spst
5698948Sobrienvoid (*file_changed_hook) (char *);
5746289Sdfr
5819370Spst/* Prototypes for local functions */
5919370Spst
6098948Sobrienstatic void exec_close (int);
6119370Spst
6298948Sobrienstatic void file_command (char *, int);
6319370Spst
6498948Sobrienstatic void set_section_command (char *, int);
6519370Spst
6698948Sobrienstatic void exec_files_info (struct target_ops *);
6719370Spst
6898948Sobrienstatic int ignore (CORE_ADDR, char *);
6946289Sdfr
7098948Sobrienstatic void init_exec_ops (void);
7146289Sdfr
7298948Sobrienvoid _initialize_exec (void);
7346289Sdfr
7446289Sdfr/* The target vector for executable files.  */
7546289Sdfr
7646289Sdfrstruct target_ops exec_ops;
7746289Sdfr
7819370Spst/* The Binary File Descriptor handle for the executable file.  */
7919370Spst
8019370Spstbfd *exec_bfd = NULL;
8119370Spst
8219370Spst/* Whether to open exec and core files read-only or read-write.  */
8319370Spst
8419370Spstint write_files = 0;
8519370Spst
8619370Spststruct vmap *vmap;
8719370Spst
8898948Sobrienvoid
8998948Sobrienexec_open (char *args, int from_tty)
9098948Sobrien{
9198948Sobrien  target_preopen (from_tty);
9298948Sobrien  exec_file_attach (args, from_tty);
9398948Sobrien}
9498948Sobrien
9519370Spststatic void
9698948Sobrienexec_close (int quitting)
9719370Spst{
9819370Spst  int need_symtab_cleanup = 0;
9919370Spst  struct vmap *vp, *nxt;
10098948Sobrien
10198948Sobrien  for (nxt = vmap; nxt != NULL;)
10219370Spst    {
10319370Spst      vp = nxt;
10419370Spst      nxt = vp->nxt;
10519370Spst
10619370Spst      /* if there is an objfile associated with this bfd,
10798948Sobrien         free_objfile() will do proper cleanup of objfile *and* bfd. */
10898948Sobrien
10919370Spst      if (vp->objfile)
11019370Spst	{
11119370Spst	  free_objfile (vp->objfile);
11219370Spst	  need_symtab_cleanup = 1;
11319370Spst	}
11419370Spst      else if (vp->bfd != exec_bfd)
11519370Spst	/* FIXME-leak: We should be freeing vp->name too, I think.  */
11619370Spst	if (!bfd_close (vp->bfd))
11719370Spst	  warning ("cannot close \"%s\": %s",
11819370Spst		   vp->name, bfd_errmsg (bfd_get_error ()));
11919370Spst
12019370Spst      /* FIXME: This routine is #if 0'd in symfile.c.  What should we
12198948Sobrien         be doing here?  Should we just free everything in
12298948Sobrien         vp->objfile->symtabs?  Should free_objfile do that?
12398948Sobrien         FIXME-as-well: free_objfile already free'd vp->name, so it isn't
12498948Sobrien         valid here.  */
12519370Spst      free_named_symtabs (vp->name);
12698948Sobrien      xfree (vp);
12719370Spst    }
12819370Spst
12919370Spst  vmap = NULL;
13019370Spst
13119370Spst  if (exec_bfd)
13219370Spst    {
13319370Spst      char *name = bfd_get_filename (exec_bfd);
13419370Spst
13519370Spst      if (!bfd_close (exec_bfd))
13619370Spst	warning ("cannot close \"%s\": %s",
13719370Spst		 name, bfd_errmsg (bfd_get_error ()));
13898948Sobrien      xfree (name);
13919370Spst      exec_bfd = NULL;
14019370Spst    }
14119370Spst
14219370Spst  if (exec_ops.to_sections)
14319370Spst    {
14498948Sobrien      xfree (exec_ops.to_sections);
14519370Spst      exec_ops.to_sections = NULL;
14619370Spst      exec_ops.to_sections_end = NULL;
14719370Spst    }
14819370Spst}
14919370Spst
15098948Sobrienvoid
15198948Sobrienexec_file_clear (int from_tty)
15298948Sobrien{
15398948Sobrien  /* Remove exec file.  */
15498948Sobrien  unpush_target (&exec_ops);
15598948Sobrien
15698948Sobrien  if (from_tty)
15798948Sobrien    printf_unfiltered ("No executable file now.\n");
15898948Sobrien}
15998948Sobrien
16019370Spst/*  Process the first arg in ARGS as the new exec file.
16119370Spst
16298948Sobrien   This function is intended to be behave essentially the same
16398948Sobrien   as exec_file_command, except that the latter will detect when
16498948Sobrien   a target is being debugged, and will ask the user whether it
16598948Sobrien   should be shut down first.  (If the answer is "no", then the
16698948Sobrien   new file is ignored.)
16719370Spst
16898948Sobrien   This file is used by exec_file_command, to do the work of opening
16998948Sobrien   and processing the exec file after any prompting has happened.
17046289Sdfr
17198948Sobrien   And, it is used by child_attach, when the attach command was
17298948Sobrien   given a pid but not a exec pathname, and the attach command could
17398948Sobrien   figure out the pathname from the pid.  (In this case, we shouldn't
17498948Sobrien   ask the user whether the current target should be shut down --
17598948Sobrien   we're supplying the exec pathname late for good reason.)
17698948Sobrien
17798948Sobrien   ARGS is assumed to be the filename. */
17846289Sdfr
17919370Spstvoid
18098948Sobrienexec_file_attach (char *filename, int from_tty)
18119370Spst{
18219370Spst  /* Remove any previous exec file.  */
18319370Spst  unpush_target (&exec_ops);
18419370Spst
18519370Spst  /* Now open and digest the file the user requested, if any.  */
18619370Spst
18798948Sobrien  if (!filename)
18819370Spst    {
18998948Sobrien      if (from_tty)
19098948Sobrien        printf_unfiltered ("No executable file now.\n");
19198948Sobrien    }
19298948Sobrien  else
19398948Sobrien    {
19419370Spst      char *scratch_pathname;
19519370Spst      int scratch_chan;
19619370Spst
19798948Sobrien      scratch_chan = openp (getenv ("PATH"), 1, filename,
19898948Sobrien		   write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, 0,
19919370Spst			    &scratch_pathname);
20098948Sobrien#if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__)
20119370Spst      if (scratch_chan < 0)
20298948Sobrien	{
20398948Sobrien	  char *exename = alloca (strlen (filename) + 5);
20498948Sobrien	  strcat (strcpy (exename, filename), ".exe");
20598948Sobrien	  scratch_chan = openp (getenv ("PATH"), 1, exename, write_files ?
20698948Sobrien	     O_RDWR | O_BINARY : O_RDONLY | O_BINARY, 0, &scratch_pathname);
20798948Sobrien	}
20846289Sdfr#endif
20946289Sdfr      if (scratch_chan < 0)
21019370Spst	perror_with_name (filename);
21119370Spst      exec_bfd = bfd_fdopenr (scratch_pathname, gnutarget, scratch_chan);
21219370Spst
21319370Spst      if (!exec_bfd)
21419370Spst	error ("\"%s\": could not open as an executable file: %s",
21519370Spst	       scratch_pathname, bfd_errmsg (bfd_get_error ()));
21619370Spst
21719370Spst      /* At this point, scratch_pathname and exec_bfd->name both point to the
21898948Sobrien         same malloc'd string.  However exec_close() will attempt to free it
21998948Sobrien         via the exec_bfd->name pointer, so we need to make another copy and
22098948Sobrien         leave exec_bfd as the new owner of the original copy. */
22198948Sobrien      scratch_pathname = xstrdup (scratch_pathname);
22298948Sobrien      make_cleanup (xfree, scratch_pathname);
22398948Sobrien
22419370Spst      if (!bfd_check_format (exec_bfd, bfd_object))
22519370Spst	{
22619370Spst	  /* Make sure to close exec_bfd, or else "run" might try to use
22719370Spst	     it.  */
22819370Spst	  exec_close (0);
22919370Spst	  error ("\"%s\": not in executable format: %s",
23019370Spst		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
23119370Spst	}
23219370Spst
23319370Spst      /* FIXME - This should only be run for RS6000, but the ifdef is a poor
23498948Sobrien         way to accomplish.  */
235130809Smarcel#ifdef DEPRECATED_IBM6000_TARGET
23619370Spst      /* Setup initial vmap. */
23719370Spst
23819370Spst      map_vmap (exec_bfd, 0);
23919370Spst      if (vmap == NULL)
24019370Spst	{
24119370Spst	  /* Make sure to close exec_bfd, or else "run" might try to use
24219370Spst	     it.  */
24319370Spst	  exec_close (0);
24419370Spst	  error ("\"%s\": can't find the file sections: %s",
24519370Spst		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
24619370Spst	}
247130809Smarcel#endif /* DEPRECATED_IBM6000_TARGET */
24819370Spst
24919370Spst      if (build_section_table (exec_bfd, &exec_ops.to_sections,
25098948Sobrien			       &exec_ops.to_sections_end))
25119370Spst	{
25219370Spst	  /* Make sure to close exec_bfd, or else "run" might try to use
25319370Spst	     it.  */
25419370Spst	  exec_close (0);
25598948Sobrien	  error ("\"%s\": can't find the file sections: %s",
25619370Spst		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
25719370Spst	}
25819370Spst
259130809Smarcel#ifdef DEPRECATED_HPUX_TEXT_END
260130809Smarcel      DEPRECATED_HPUX_TEXT_END (&exec_ops);
261130809Smarcel#endif
26298948Sobrien
26319370Spst      validate_files ();
26419370Spst
26546289Sdfr      set_gdbarch_from_file (exec_bfd);
26619370Spst
26719370Spst      push_target (&exec_ops);
26819370Spst
26919370Spst      /* Tell display code (if any) about the changed file name.  */
27019370Spst      if (exec_file_display_hook)
27119370Spst	(*exec_file_display_hook) (filename);
27219370Spst    }
27319370Spst}
27419370Spst
27546289Sdfr/*  Process the first arg in ARGS as the new exec file.
27646289Sdfr
27798948Sobrien   Note that we have to explicitly ignore additional args, since we can
27898948Sobrien   be called from file_command(), which also calls symbol_file_command()
27998948Sobrien   which can take multiple args.
28098948Sobrien
28198948Sobrien   If ARGS is NULL, we just want to close the exec file. */
28246289Sdfr
28398948Sobrienstatic void
28498948Sobrienexec_file_command (char *args, int from_tty)
28546289Sdfr{
28646289Sdfr  char **argv;
28746289Sdfr  char *filename;
28898948Sobrien
28946289Sdfr  target_preopen (from_tty);
29046289Sdfr
29198948Sobrien  if (args)
29298948Sobrien    {
29398948Sobrien      /* Scan through the args and pick up the first non option arg
29498948Sobrien         as the filename.  */
29598948Sobrien
29698948Sobrien      argv = buildargv (args);
29798948Sobrien      if (argv == NULL)
29898948Sobrien        nomem (0);
29998948Sobrien
30098948Sobrien      make_cleanup_freeargv (argv);
30198948Sobrien
30298948Sobrien      for (; (*argv != NULL) && (**argv == '-'); argv++)
30398948Sobrien        {;
30498948Sobrien        }
30598948Sobrien      if (*argv == NULL)
30698948Sobrien        error ("No executable file name was specified");
30798948Sobrien
30898948Sobrien      filename = tilde_expand (*argv);
30998948Sobrien      make_cleanup (xfree, filename);
31098948Sobrien      exec_file_attach (filename, from_tty);
31198948Sobrien    }
31298948Sobrien  else
31398948Sobrien    exec_file_attach (NULL, from_tty);
31446289Sdfr}
31546289Sdfr
31619370Spst/* Set both the exec file and the symbol file, in one command.
31719370Spst   What a novelty.  Why did GDB go through four major releases before this
31819370Spst   command was added?  */
31919370Spst
32019370Spststatic void
32198948Sobrienfile_command (char *arg, int from_tty)
32219370Spst{
32319370Spst  /* FIXME, if we lose on reading the symbol file, we should revert
32419370Spst     the exec file, but that's rough.  */
32519370Spst  exec_file_command (arg, from_tty);
32619370Spst  symbol_file_command (arg, from_tty);
32746289Sdfr  if (file_changed_hook)
32846289Sdfr    file_changed_hook (arg);
32919370Spst}
33098948Sobrien
33119370Spst
33219370Spst/* Locate all mappable sections of a BFD file.
33319370Spst   table_pp_char is a char * to get it through bfd_map_over_sections;
33419370Spst   we cast it back to its proper type.  */
33519370Spst
33619370Spststatic void
337130809Smarceladd_to_section_table (bfd *abfd, struct bfd_section *asect,
338130809Smarcel		      void *table_pp_char)
33919370Spst{
34098948Sobrien  struct section_table **table_pp = (struct section_table **) table_pp_char;
34119370Spst  flagword aflag;
34219370Spst
34319370Spst  aflag = bfd_get_section_flags (abfd, asect);
34419370Spst  if (!(aflag & SEC_ALLOC))
34519370Spst    return;
34619370Spst  if (0 == bfd_section_size (abfd, asect))
34719370Spst    return;
34819370Spst  (*table_pp)->bfd = abfd;
34919370Spst  (*table_pp)->the_bfd_section = asect;
35019370Spst  (*table_pp)->addr = bfd_section_vma (abfd, asect);
35119370Spst  (*table_pp)->endaddr = (*table_pp)->addr + bfd_section_size (abfd, asect);
35219370Spst  (*table_pp)++;
35319370Spst}
35419370Spst
35519370Spst/* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR.
35619370Spst   Returns 0 if OK, 1 on error.  */
35719370Spst
35819370Spstint
359130809Smarcelbuild_section_table (struct bfd *some_bfd, struct section_table **start,
36098948Sobrien		     struct section_table **end)
36119370Spst{
36219370Spst  unsigned count;
36319370Spst
36419370Spst  count = bfd_count_sections (some_bfd);
36519370Spst  if (*start)
36698948Sobrien    xfree (* start);
36719370Spst  *start = (struct section_table *) xmalloc (count * sizeof (**start));
36819370Spst  *end = *start;
36998948Sobrien  bfd_map_over_sections (some_bfd, add_to_section_table, (char *) end);
37019370Spst  if (*end > *start + count)
37198948Sobrien    internal_error (__FILE__, __LINE__, "failed internal consistency check");
37219370Spst  /* We could realloc the table, but it probably loses for most files.  */
37319370Spst  return 0;
37419370Spst}
37519370Spst
37619370Spststatic void
377130809Smarcelbfdsec_to_vmap (struct bfd *abfd, struct bfd_section *sect, void *arg3)
37819370Spst{
37919370Spst  struct vmap_and_bfd *vmap_bfd = (struct vmap_and_bfd *) arg3;
38019370Spst  struct vmap *vp;
38119370Spst
38219370Spst  vp = vmap_bfd->pvmap;
38319370Spst
38419370Spst  if ((bfd_get_section_flags (abfd, sect) & SEC_LOAD) == 0)
38519370Spst    return;
38619370Spst
387130809Smarcel  if (DEPRECATED_STREQ (bfd_section_name (abfd, sect), ".text"))
38819370Spst    {
38946289Sdfr      vp->tstart = bfd_section_vma (abfd, sect);
39019370Spst      vp->tend = vp->tstart + bfd_section_size (abfd, sect);
39146289Sdfr      vp->tvma = bfd_section_vma (abfd, sect);
39246289Sdfr      vp->toffs = sect->filepos;
39319370Spst    }
394130809Smarcel  else if (DEPRECATED_STREQ (bfd_section_name (abfd, sect), ".data"))
39519370Spst    {
39646289Sdfr      vp->dstart = bfd_section_vma (abfd, sect);
39719370Spst      vp->dend = vp->dstart + bfd_section_size (abfd, sect);
39846289Sdfr      vp->dvma = bfd_section_vma (abfd, sect);
39919370Spst    }
40019370Spst  /* Silently ignore other types of sections. (FIXME?)  */
40119370Spst}
40219370Spst
40319370Spst/* Make a vmap for ABFD which might be a member of the archive ARCH.
40419370Spst   Return the new vmap.  */
40519370Spst
40619370Spststruct vmap *
40798948Sobrienmap_vmap (bfd *abfd, bfd *arch)
40819370Spst{
40919370Spst  struct vmap_and_bfd vmap_bfd;
41019370Spst  struct vmap *vp, **vpp;
41119370Spst
41219370Spst  vp = (struct vmap *) xmalloc (sizeof (*vp));
41319370Spst  memset ((char *) vp, '\0', sizeof (*vp));
41419370Spst  vp->nxt = 0;
41519370Spst  vp->bfd = abfd;
41619370Spst  vp->name = bfd_get_filename (arch ? arch : abfd);
41719370Spst  vp->member = arch ? bfd_get_filename (abfd) : "";
41898948Sobrien
41919370Spst  vmap_bfd.pbfd = arch;
42019370Spst  vmap_bfd.pvmap = vp;
42119370Spst  bfd_map_over_sections (abfd, bfdsec_to_vmap, &vmap_bfd);
42219370Spst
42319370Spst  /* Find the end of the list and append. */
42419370Spst  for (vpp = &vmap; *vpp; vpp = &(*vpp)->nxt)
42519370Spst    ;
42619370Spst  *vpp = vp;
42719370Spst
42819370Spst  return vp;
42919370Spst}
43019370Spst
43119370Spst/* Read or write the exec file.
43219370Spst
43319370Spst   Args are address within a BFD file, address within gdb address-space,
43419370Spst   length, and a flag indicating whether to read or write.
43519370Spst
43619370Spst   Result is a length:
43719370Spst
43898948Sobrien   0:    We cannot handle this address and length.
43998948Sobrien   > 0:  We have handled N bytes starting at this address.
44098948Sobrien   (If N == length, we did it all.)  We might be able
44198948Sobrien   to handle more bytes beyond this length, but no
44298948Sobrien   promises.
44398948Sobrien   < 0:  We cannot handle this address, but if somebody
44498948Sobrien   else handles (-N) bytes, we can start from there.
44519370Spst
44698948Sobrien   The same routine is used to handle both core and exec files;
44798948Sobrien   we just tail-call it with more arguments to select between them.  */
44819370Spst
44919370Spstint
45098948Sobrienxfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
45198948Sobrien	     struct mem_attrib *attrib,
45298948Sobrien	     struct target_ops *target)
45319370Spst{
454130809Smarcel  int res;
45519370Spst  struct section_table *p;
45619370Spst  CORE_ADDR nextsectaddr, memend;
45798948Sobrien  asection *section = NULL;
45819370Spst
45919370Spst  if (len <= 0)
46098948Sobrien    internal_error (__FILE__, __LINE__, "failed internal consistency check");
46119370Spst
46246289Sdfr  if (overlay_debugging)
46346289Sdfr    {
46446289Sdfr      section = find_pc_overlay (memaddr);
46546289Sdfr      if (pc_in_unmapped_range (memaddr, section))
46646289Sdfr	memaddr = overlay_mapped_address (memaddr, section);
46746289Sdfr    }
46846289Sdfr
46919370Spst  memend = memaddr + len;
47019370Spst  nextsectaddr = memend;
47119370Spst
47219370Spst  for (p = target->to_sections; p < target->to_sections_end; p++)
47319370Spst    {
47446289Sdfr      if (overlay_debugging && section && p->the_bfd_section &&
47546289Sdfr	  strcmp (section->name, p->the_bfd_section->name) != 0)
47698948Sobrien	continue;		/* not the section we need */
47746289Sdfr      if (memaddr >= p->addr)
478130809Smarcel        {
479130809Smarcel	  if (memend <= p->endaddr)
480130809Smarcel	    {
481130809Smarcel	      /* Entire transfer is within this section.  */
482130809Smarcel	      if (write)
483130809Smarcel		res = bfd_set_section_contents (p->bfd, p->the_bfd_section,
484130809Smarcel						myaddr, memaddr - p->addr,
485130809Smarcel						len);
486130809Smarcel	      else
487130809Smarcel		res = bfd_get_section_contents (p->bfd, p->the_bfd_section,
488130809Smarcel						myaddr, memaddr - p->addr,
489130809Smarcel						len);
490130809Smarcel	      return (res != 0) ? len : 0;
491130809Smarcel	    }
492130809Smarcel	  else if (memaddr >= p->endaddr)
493130809Smarcel	    {
494130809Smarcel	      /* This section ends before the transfer starts.  */
495130809Smarcel	      continue;
496130809Smarcel	    }
497130809Smarcel	  else
498130809Smarcel	    {
499130809Smarcel	      /* This section overlaps the transfer.  Just do half.  */
500130809Smarcel	      len = p->endaddr - memaddr;
501130809Smarcel	      if (write)
502130809Smarcel		res = bfd_set_section_contents (p->bfd, p->the_bfd_section,
503130809Smarcel						myaddr, memaddr - p->addr,
504130809Smarcel						len);
505130809Smarcel	      else
506130809Smarcel		res = bfd_get_section_contents (p->bfd, p->the_bfd_section,
507130809Smarcel						myaddr, memaddr - p->addr,
508130809Smarcel						len);
509130809Smarcel	      return (res != 0) ? len : 0;
510130809Smarcel	    }
511130809Smarcel        }
51246289Sdfr      else
51346289Sdfr	nextsectaddr = min (nextsectaddr, p->addr);
51419370Spst    }
51519370Spst
51619370Spst  if (nextsectaddr >= memend)
51798948Sobrien    return 0;			/* We can't help */
51819370Spst  else
51998948Sobrien    return -(nextsectaddr - memaddr);	/* Next boundary where we can help */
52019370Spst}
52198948Sobrien
52219370Spst
52319370Spstvoid
52498948Sobrienprint_section_info (struct target_ops *t, bfd *abfd)
52519370Spst{
52619370Spst  struct section_table *p;
527130809Smarcel  /* FIXME: "016l" is not wide enough when TARGET_ADDR_BIT > 64.  */
528130809Smarcel  char *fmt = TARGET_ADDR_BIT <= 32 ? "08l" : "016l";
52919370Spst
53098948Sobrien  printf_filtered ("\t`%s', ", bfd_get_filename (abfd));
53119370Spst  wrap_here ("        ");
53298948Sobrien  printf_filtered ("file type %s.\n", bfd_get_target (abfd));
53319370Spst  if (abfd == exec_bfd)
53419370Spst    {
53519370Spst      printf_filtered ("\tEntry point: ");
53619370Spst      print_address_numeric (bfd_get_start_address (abfd), 1, gdb_stdout);
53719370Spst      printf_filtered ("\n");
53819370Spst    }
53919370Spst  for (p = t->to_sections; p < t->to_sections_end; p++)
54019370Spst    {
541130809Smarcel      printf_filtered ("\t%s", local_hex_string_custom (p->addr, fmt));
542130809Smarcel      printf_filtered (" - %s", local_hex_string_custom (p->endaddr, fmt));
543130809Smarcel
544130809Smarcel      /* FIXME: A format of "08l" is not wide enough for file offsets
545130809Smarcel	 larger than 4GB.  OTOH, making it "016l" isn't desirable either
546130809Smarcel	 since most output will then be much wider than necessary.  It
547130809Smarcel	 may make sense to test the size of the file and choose the
548130809Smarcel	 format string accordingly.  */
54919370Spst      if (info_verbose)
55019370Spst	printf_filtered (" @ %s",
551130809Smarcel			 local_hex_string_custom (p->the_bfd_section->filepos, "08l"));
55219370Spst      printf_filtered (" is %s", bfd_section_name (p->bfd, p->the_bfd_section));
55319370Spst      if (p->bfd != abfd)
55419370Spst	{
55519370Spst	  printf_filtered (" in %s", bfd_get_filename (p->bfd));
55619370Spst	}
55719370Spst      printf_filtered ("\n");
55819370Spst    }
55919370Spst}
56019370Spst
56119370Spststatic void
56298948Sobrienexec_files_info (struct target_ops *t)
56319370Spst{
56419370Spst  print_section_info (t, exec_bfd);
56519370Spst
56619370Spst  if (vmap)
56719370Spst    {
56819370Spst      struct vmap *vp;
56919370Spst
57019370Spst      printf_unfiltered ("\tMapping info for file `%s'.\n", vmap->name);
57198948Sobrien      printf_unfiltered ("\t  %*s   %*s   %*s   %*s %8.8s %s\n",
57298948Sobrien			 strlen_paddr (), "tstart",
57398948Sobrien			 strlen_paddr (), "tend",
57498948Sobrien			 strlen_paddr (), "dstart",
57598948Sobrien			 strlen_paddr (), "dend",
57698948Sobrien			 "section",
57798948Sobrien			 "file(member)");
57819370Spst
57998948Sobrien      for (vp = vmap; vp; vp = vp->nxt)
58098948Sobrien	printf_unfiltered ("\t0x%s 0x%s 0x%s 0x%s %s%s%s%s\n",
58198948Sobrien			   paddr (vp->tstart),
58298948Sobrien			   paddr (vp->tend),
58398948Sobrien			   paddr (vp->dstart),
58498948Sobrien			   paddr (vp->dend),
58598948Sobrien			   vp->name,
58698948Sobrien			   *vp->member ? "(" : "", vp->member,
58798948Sobrien			   *vp->member ? ")" : "");
58819370Spst    }
58919370Spst}
59019370Spst
59198948Sobrien/* msnyder 5/21/99:
59298948Sobrien   exec_set_section_offsets sets the offsets of all the sections
59398948Sobrien   in the exec objfile.  */
59498948Sobrien
59598948Sobrienvoid
59698948Sobrienexec_set_section_offsets (bfd_signed_vma text_off, bfd_signed_vma data_off,
59798948Sobrien			  bfd_signed_vma bss_off)
59898948Sobrien{
59998948Sobrien  struct section_table *sect;
60098948Sobrien
60198948Sobrien  for (sect = exec_ops.to_sections;
60298948Sobrien       sect < exec_ops.to_sections_end;
60398948Sobrien       sect++)
60498948Sobrien    {
60598948Sobrien      flagword flags;
60698948Sobrien
60798948Sobrien      flags = bfd_get_section_flags (exec_bfd, sect->the_bfd_section);
60898948Sobrien
60998948Sobrien      if (flags & SEC_CODE)
61098948Sobrien	{
61198948Sobrien	  sect->addr += text_off;
61298948Sobrien	  sect->endaddr += text_off;
61398948Sobrien	}
61498948Sobrien      else if (flags & (SEC_DATA | SEC_LOAD))
61598948Sobrien	{
61698948Sobrien	  sect->addr += data_off;
61798948Sobrien	  sect->endaddr += data_off;
61898948Sobrien	}
61998948Sobrien      else if (flags & SEC_ALLOC)
62098948Sobrien	{
62198948Sobrien	  sect->addr += bss_off;
62298948Sobrien	  sect->endaddr += bss_off;
62398948Sobrien	}
62498948Sobrien    }
62598948Sobrien}
62698948Sobrien
62719370Spststatic void
62898948Sobrienset_section_command (char *args, int from_tty)
62919370Spst{
63019370Spst  struct section_table *p;
63119370Spst  char *secname;
63219370Spst  unsigned seclen;
63319370Spst  unsigned long secaddr;
63419370Spst  char secprint[100];
63519370Spst  long offset;
63619370Spst
63719370Spst  if (args == 0)
63819370Spst    error ("Must specify section name and its virtual address");
63919370Spst
64019370Spst  /* Parse out section name */
64198948Sobrien  for (secname = args; !isspace (*args); args++);
64219370Spst  seclen = args - secname;
64319370Spst
64419370Spst  /* Parse out new virtual address */
64519370Spst  secaddr = parse_and_eval_address (args);
64619370Spst
64798948Sobrien  for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++)
64898948Sobrien    {
64998948Sobrien      if (!strncmp (secname, bfd_section_name (exec_bfd, p->the_bfd_section), seclen)
65098948Sobrien	  && bfd_section_name (exec_bfd, p->the_bfd_section)[seclen] == '\0')
65198948Sobrien	{
65298948Sobrien	  offset = secaddr - p->addr;
65398948Sobrien	  p->addr += offset;
65498948Sobrien	  p->endaddr += offset;
65598948Sobrien	  if (from_tty)
65698948Sobrien	    exec_files_info (&exec_ops);
65798948Sobrien	  return;
65898948Sobrien	}
65919370Spst    }
66019370Spst  if (seclen >= sizeof (secprint))
66119370Spst    seclen = sizeof (secprint) - 1;
66219370Spst  strncpy (secprint, secname, seclen);
66319370Spst  secprint[seclen] = '\0';
66419370Spst  error ("Section %s not found", secprint);
66519370Spst}
66619370Spst
66719370Spst/* If mourn is being called in all the right places, this could be say
66846289Sdfr   `gdb internal error' (since generic_mourn calls
66946289Sdfr   breakpoint_init_inferior).  */
67019370Spst
67119370Spststatic int
67298948Sobrienignore (CORE_ADDR addr, char *contents)
67319370Spst{
67419370Spst  return 0;
67519370Spst}
67619370Spst
67798948Sobrien/* Find mapped memory. */
67898948Sobrien
67998948Sobrienextern void
68098948Sobrienexec_set_find_memory_regions (int (*func) (int (*) (CORE_ADDR,
68198948Sobrien						    unsigned long,
68298948Sobrien						    int, int, int,
68398948Sobrien						    void *),
68498948Sobrien					   void *))
68598948Sobrien{
68698948Sobrien  exec_ops.to_find_memory_regions = func;
68798948Sobrien}
68898948Sobrien
68998948Sobrienstatic char *exec_make_note_section (bfd *, int *);
69098948Sobrien
69146289Sdfr/* Fill in the exec file target vector.  Very few entries need to be
69246289Sdfr   defined.  */
69319370Spst
69498948Sobrienstatic void
69598948Sobrieninit_exec_ops (void)
69619370Spst{
69746289Sdfr  exec_ops.to_shortname = "exec";
69846289Sdfr  exec_ops.to_longname = "Local exec file";
69946289Sdfr  exec_ops.to_doc = "Use an executable file as a target.\n\
70046289SdfrSpecify the filename of the executable file.";
70198948Sobrien  exec_ops.to_open = exec_open;
70246289Sdfr  exec_ops.to_close = exec_close;
70346289Sdfr  exec_ops.to_attach = find_default_attach;
70446289Sdfr  exec_ops.to_xfer_memory = xfer_memory;
70546289Sdfr  exec_ops.to_files_info = exec_files_info;
70646289Sdfr  exec_ops.to_insert_breakpoint = ignore;
70746289Sdfr  exec_ops.to_remove_breakpoint = ignore;
70846289Sdfr  exec_ops.to_create_inferior = find_default_create_inferior;
70946289Sdfr  exec_ops.to_stratum = file_stratum;
71046289Sdfr  exec_ops.to_has_memory = 1;
71198948Sobrien  exec_ops.to_make_corefile_notes = exec_make_note_section;
71298948Sobrien  exec_ops.to_magic = OPS_MAGIC;
71346289Sdfr}
71446289Sdfr
71546289Sdfrvoid
71698948Sobrien_initialize_exec (void)
71746289Sdfr{
71819370Spst  struct cmd_list_element *c;
71919370Spst
72046289Sdfr  init_exec_ops ();
72146289Sdfr
72246289Sdfr  if (!dbx_commands)
72346289Sdfr    {
72446289Sdfr      c = add_cmd ("file", class_files, file_command,
72546289Sdfr		   "Use FILE as program to be debugged.\n\
72619370SpstIt is read for its symbols, for getting the contents of pure memory,\n\
72719370Spstand it is the program executed when you use the `run' command.\n\
72819370SpstIf FILE cannot be found as specified, your execution directory path\n\
72919370Spst($PATH) is searched for a command of that name.\n\
73019370SpstNo arg means to have no executable file and no symbols.", &cmdlist);
731130809Smarcel      set_cmd_completer (c, filename_completer);
73246289Sdfr    }
73319370Spst
73419370Spst  c = add_cmd ("exec-file", class_files, exec_file_command,
73598948Sobrien	       "Use FILE as program for getting contents of pure memory.\n\
73619370SpstIf FILE cannot be found as specified, your execution directory path\n\
73719370Spstis searched for a command of that name.\n\
73819370SpstNo arg means have no executable file.", &cmdlist);
739130809Smarcel  set_cmd_completer (c, filename_completer);
74019370Spst
74119370Spst  add_com ("section", class_files, set_section_command,
74298948Sobrien	   "Change the base address of section SECTION of the exec file to ADDR.\n\
74319370SpstThis can be used if the exec file does not contain section addresses,\n\
74419370Spst(such as in the a.out format), or when the addresses specified in the\n\
74519370Spstfile itself are wrong.  Each section must be changed separately.  The\n\
74619370Spst``info files'' command lists all the sections and their addresses.");
74719370Spst
74819370Spst  add_show_from_set
74998948Sobrien    (add_set_cmd ("write", class_support, var_boolean, (char *) &write_files,
75019370Spst		  "Set writing into executable and core files.",
75119370Spst		  &setlist),
75219370Spst     &showlist);
75398948Sobrien
75419370Spst  add_target (&exec_ops);
75519370Spst}
75698948Sobrien
75798948Sobrienstatic char *
75898948Sobrienexec_make_note_section (bfd *obfd, int *note_size)
75998948Sobrien{
76098948Sobrien  error ("Can't create a corefile");
76198948Sobrien}
762