* exec.c: Merge in RS6000 support from xcoffexec.c.

(symfile.h, objfiles.h, xcoffsolib.h): Include.
	(vmap): New global variable.
	(exec_close): Close and free objects in vmap chain.
	(exec_file_command) [IBM6000_TARGET]: Set up initial vmap.
	(bfdsec_to_vmap, map_vmap): Moved here from xcoffexec.c.
	(exec_files_info): Print vmap information.
	* xcoffexec.c: Remove.
	* config/rs6000/rs6000.mt, config/rs6000/rs6000lynx.mt
	(TDEPFILES): Use exec.o instead of xcoffexec.o.
	* TODO: Remove pertinent items.
This commit is contained in:
Stan Shebs
1994-10-13 01:16:19 +00:00
parent ba49e48d26
commit 806f810b69
6 changed files with 191 additions and 643 deletions

View File

@@ -23,6 +23,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "target.h"
#include "gdbcmd.h"
#include "language.h"
#include "symfile.h"
#include "objfiles.h"
#ifdef USG
#include <sys/types.h>
@@ -40,22 +42,21 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define O_BINARY 0
#endif
#include "xcoffsolib.h"
struct vmap *map_vmap PARAMS ((bfd *, bfd *));
/* Prototypes for local functions */
static void
add_to_section_table PARAMS ((bfd *, sec_ptr, PTR));
static void add_to_section_table PARAMS ((bfd *, sec_ptr, PTR));
static void
exec_close PARAMS ((int));
static void exec_close PARAMS ((int));
static void
file_command PARAMS ((char *, int));
static void file_command PARAMS ((char *, int));
static void
set_section_command PARAMS ((char *, int));
static void set_section_command PARAMS ((char *, int));
static void
exec_files_info PARAMS ((struct target_ops *));
static void exec_files_info PARAMS ((struct target_ops *));
extern int info_verbose;
@@ -74,6 +75,8 @@ CORE_ADDR text_start = 0;
CORE_ADDR text_end = 0;
#endif
struct vmap *vmap;
/* Forward decl */
extern struct target_ops exec_ops;
@@ -83,17 +86,49 @@ static void
exec_close (quitting)
int quitting;
{
if (exec_bfd) {
char *name = bfd_get_filename (exec_bfd);
bfd_close (exec_bfd);
free (name);
exec_bfd = NULL;
}
if (exec_ops.to_sections) {
free ((PTR)exec_ops.to_sections);
exec_ops.to_sections = NULL;
exec_ops.to_sections_end = NULL;
}
int need_symtab_cleanup = 0;
struct vmap *vp, *nxt;
for (nxt = vmap; nxt != NULL; )
{
vp = nxt;
nxt = vp->nxt;
/* if there is an objfile associated with this bfd,
free_objfile() will do proper cleanup of objfile *and* bfd. */
if (vp->objfile)
{
free_objfile (vp->objfile);
need_symtab_cleanup = 1;
}
else if (vp->bfd != exec_bfd)
bfd_close (vp->bfd);
/* FIXME: This routine is #if 0'd in symfile.c. What should we
be doing here? Should we just free everything in
vp->objfile->symtabs? Should free_objfile do that? */
free_named_symtabs (vp->name);
free (vp);
}
vmap = NULL;
if (exec_bfd)
{
char *name = bfd_get_filename (exec_bfd);
bfd_close (exec_bfd);
free (name);
exec_bfd = NULL;
}
if (exec_ops.to_sections)
{
free ((PTR)exec_ops.to_sections);
exec_ops.to_sections = NULL;
exec_ops.to_sections_end = NULL;
}
}
/* Process the first arg in ARGS as the new exec file.
@@ -123,19 +158,17 @@ exec_file_command (args, from_tty)
int scratch_chan;
/* Scan through the args and pick up the first non option arg
as the filename. */
as the filename. */
argv = buildargv (args);
if (argv == NULL)
nomem (0);
if ((argv = buildargv (args)) == NULL)
{
nomem (0);
}
make_cleanup (freeargv, (char *) argv);
for (; (*argv != NULL) && (**argv == '-'); argv++) {;}
if (*argv == NULL)
{
error ("no exec file name was specified");
}
error ("no exec file name was specified");
filename = tilde_expand (*argv);
make_cleanup (free, filename);
@@ -148,25 +181,41 @@ exec_file_command (args, from_tty)
exec_bfd = bfd_fdopenr (scratch_pathname, gnutarget, scratch_chan);
if (!exec_bfd)
error ("Could not open `%s' as an executable file: %s",
error ("\"%s\": could not open as an executable file: %s",
scratch_pathname, bfd_errmsg (bfd_get_error ()));
if (!bfd_check_format (exec_bfd, bfd_object))
{
/* Make sure to close exec_bfd, or else "run" might try to use
it. */
exec_close (0);
error ("\"%s\": not in executable format: %s.",
error ("\"%s\": not in executable format: %s",
scratch_pathname, bfd_errmsg (bfd_get_error ()));
}
/* FIXME - This should only be run for RS6000, but the ifdef is a poor
way to accomplish. */
#ifdef IBM6000_TARGET
/* Setup initial vmap. */
map_vmap (exec_bfd, 0);
if (vmap == NULL)
{
/* Make sure to close exec_bfd, or else "run" might try to use
it. */
exec_close (0);
error ("\"%s\": can't find the file sections: %s",
scratch_pathname, bfd_errmsg (bfd_get_error ()));
}
#endif /* IBM6000_TARGET */
if (build_section_table (exec_bfd, &exec_ops.to_sections,
&exec_ops.to_sections_end))
{
/* Make sure to close exec_bfd, or else "run" might try to use
it. */
exec_close (0);
error ("Can't find the file sections in `%s': %s",
exec_bfd->filename, bfd_errmsg (bfd_get_error ()));
error ("\"%s\": can't find the file sections: %s",
scratch_pathname, bfd_errmsg (bfd_get_error ()));
}
#ifdef NEED_TEXT_START_END
@@ -272,6 +321,70 @@ build_section_table (some_bfd, start, end)
return 0;
}
static void
bfdsec_to_vmap(abfd, sect, arg3)
bfd *abfd;
sec_ptr sect;
PTR arg3;
{
struct vmap_and_bfd *vmap_bfd = (struct vmap_and_bfd *) arg3;
struct vmap *vp;
vp = vmap_bfd->pvmap;
if ((bfd_get_section_flags (abfd, sect) & SEC_LOAD) == 0)
return;
if (STREQ (bfd_section_name (abfd, sect), ".text"))
{
vp->tstart = 0;
vp->tend = vp->tstart + bfd_section_size (abfd, sect);
/* When it comes to this adjustment value, in contrast to our previous
belief shared objects should behave the same as the main load segment.
This is the offset from the beginning of text section to the first
real instruction. */
vp->tadj = sect->filepos - bfd_section_vma (abfd, sect);
}
else if (STREQ (bfd_section_name (abfd, sect), ".data"))
{
vp->dstart = 0;
vp->dend = vp->dstart + bfd_section_size (abfd, sect);
}
/* Silently ignore other types of sections. (FIXME?) */
}
/* Make a vmap for ABFD which might be a member of the archive ARCH.
Return the new vmap. */
struct vmap *
map_vmap (abfd, arch)
bfd *abfd;
bfd *arch;
{
struct vmap_and_bfd vmap_bfd;
struct vmap *vp, **vpp;
vp = (PTR) xmalloc (sizeof (*vp));
memset ((char *) vp, '\0', sizeof (*vp));
vp->nxt = 0;
vp->bfd = abfd;
vp->name = bfd_get_filename (arch ? arch : abfd);
vp->member = arch ? bfd_get_filename (abfd) : "";
vmap_bfd.pbfd = arch;
vmap_bfd.pvmap = vp;
bfd_map_over_sections (abfd, bfdsec_to_vmap, &vmap_bfd);
/* Find the end of the list and append. */
for (vpp = &vmap; *vpp; vpp = &(*vpp)->nxt)
;
*vpp = vp;
return vp;
}
/* Read or write the exec file.
Args are address within a BFD file, address within gdb address-space,
@@ -307,7 +420,7 @@ xfer_memory (memaddr, myaddr, len, write, target)
abort();
memend = memaddr + len;
xfer_fn = write? bfd_set_section_contents: bfd_get_section_contents;
xfer_fn = write ? bfd_set_section_contents : bfd_get_section_contents;
nextsectaddr = memend;
for (p = target->to_sections; p < target->to_sections_end; p++)
@@ -316,7 +429,8 @@ xfer_memory (memaddr, myaddr, len, write, target)
if (p->endaddr >= memend)
{
/* Entire transfer is within this section. */
res = xfer_fn (p->bfd, p->the_bfd_section, myaddr, memaddr - p->addr, len);
res = xfer_fn (p->bfd, p->the_bfd_section, myaddr,
memaddr - p->addr, len);
return (res != 0) ? len : 0;
}
else if (p->endaddr <= memaddr)
@@ -328,7 +442,8 @@ xfer_memory (memaddr, myaddr, len, write, target)
{
/* This section overlaps the transfer. Just do half. */
len = p->endaddr - memaddr;
res = xfer_fn (p->bfd, p->the_bfd_section, myaddr, memaddr - p->addr, len);
res = xfer_fn (p->bfd, p->the_bfd_section, myaddr,
memaddr - p->addr, len);
return (res != 0) ? len : 0;
}
else if (p->addr < nextsectaddr)
@@ -391,9 +506,25 @@ print_section_info (t, abfd)
static void
exec_files_info (t)
struct target_ops *t;
struct target_ops *t;
{
print_section_info (t, exec_bfd);
if (vmap)
{
struct vmap *vp;
printf_unfiltered ("\tMapping info for file `%s'.\n", vmap->name);
printf_unfiltered ("\t %8.8s %8.8s %8.8s %8.8s %8.8s %s\n",
"tstart", "tend", "dstart", "dend", "section",
"file(member)");
for (vp = vmap; vp; vp = vp->nxt)
printf_unfiltered ("\t0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x %s%s%s%s\n",
vp->tstart, vp->tend, vp->dstart, vp->dend, vp->name,
*vp->member ? "(" : "", vp->member,
*vp->member ? ")" : "");
}
}
static void