Fri Apr 29 15:56:18 1994 Stan Shebs (shebs@andros.cygnus.com)

* xcoffexec.c: Reformat to standards and lint.
	(language.h): Include.
	(exec_close): Declare arg "quitting".
	(file_command): Declare arg "from_tty".
	(map_vmap): Cast xmalloc result to PTR.
	* rs6000-nat.c: Reformat to standards and lint.
	(exec_one_dummy_insn): Use char array for saved instruction.
	(fixup_breakpoints): Declare.
	(vmap_ldinfo): Be more informative in fatal error messages.
	(xcoff_relocate_symtab): Define to return void.
	* xcoffsolib.h: Reformat to standards, improve comments.
	* config/rs6000/nm-rs6000.h (xcoff_relocate_symtab): Declare.
This commit is contained in:
Stan Shebs 1994-04-30 00:04:43 +00:00
parent 526637b56c
commit 0c4b30ea74
4 changed files with 345 additions and 308 deletions

View File

@ -1,3 +1,18 @@
Fri Apr 29 15:56:18 1994 Stan Shebs (shebs@andros.cygnus.com)
* xcoffexec.c: Reformat to standards and lint.
(language.h): Include.
(exec_close): Declare arg "quitting".
(file_command): Declare arg "from_tty".
(map_vmap): Cast xmalloc result to PTR.
* rs6000-nat.c: Reformat to standards and lint.
(exec_one_dummy_insn): Use char array for saved instruction.
(fixup_breakpoints): Declare.
(vmap_ldinfo): Be more informative in fatal error messages.
(xcoff_relocate_symtab): Define to return void.
* xcoffsolib.h: Reformat to standards, improve comments.
* config/rs6000/nm-rs6000.h (xcoff_relocate_symtab): Declare.
Thu Apr 28 08:40:56 1994 Jim Kingdon (kingdon@lioth.cygnus.com) Thu Apr 28 08:40:56 1994 Jim Kingdon (kingdon@lioth.cygnus.com)
* utils.c, defs.h (error_begin): New function. * utils.c, defs.h (error_begin): New function.

View File

@ -1,5 +1,5 @@
/* IBM RS/6000 native-dependent code for GDB, the GNU debugger. /* IBM RS/6000 native-dependent code for GDB, the GNU debugger.
Copyright 1986, 1987, 1989, 1991, 1992 Free Software Foundation, Inc. Copyright 1986, 1987, 1989, 1991, 1992, 1994 Free Software Foundation, Inc.
This file is part of GDB. This file is part of GDB.
@ -44,6 +44,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <sys/ldr.h> #include <sys/ldr.h>
extern int errno; extern int errno;
extern struct vmap * map_vmap PARAMS ((bfd *bf, bfd *arch)); extern struct vmap * map_vmap PARAMS ((bfd *bf, bfd *arch));
extern struct target_ops exec_ops; extern struct target_ops exec_ops;
@ -54,6 +55,9 @@ exec_one_dummy_insn PARAMS ((void));
extern void extern void
add_text_to_loadinfo PARAMS ((CORE_ADDR textaddr, CORE_ADDR dataaddr)); add_text_to_loadinfo PARAMS ((CORE_ADDR textaddr, CORE_ADDR dataaddr));
extern void
fixup_breakpoints PARAMS ((CORE_ADDR low, CORE_ADDR high, CORE_ADDR delta));
/* Conversion from gdb-to-system special purpose register numbers.. */ /* Conversion from gdb-to-system special purpose register numbers.. */
static int special_regs[] = { static int special_regs[] = {
@ -132,7 +136,8 @@ store_inferior_registers (regno)
errno = 0; errno = 0;
if (regno == -1) { /* for all registers.. */ if (regno == -1)
{ /* for all registers.. */
int ii; int ii;
/* execute one dummy instruction (which is a breakpoint) in inferior /* execute one dummy instruction (which is a breakpoint) in inferior
@ -143,51 +148,61 @@ store_inferior_registers (regno)
exec_one_dummy_insn (); exec_one_dummy_insn ();
/* write general purpose registers first! */ /* write general purpose registers first! */
for ( ii=GPR0; ii<=GPR31; ++ii) { for ( ii=GPR0; ii<=GPR31; ++ii)
{
ptrace (PT_WRITE_GPR, inferior_pid, (PTRACE_ARG3_TYPE) ii, ptrace (PT_WRITE_GPR, inferior_pid, (PTRACE_ARG3_TYPE) ii,
*(int*)&registers[REGISTER_BYTE (ii)], 0); *(int*)&registers[REGISTER_BYTE (ii)], 0);
if ( errno ) { if (errno)
perror ("ptrace write_gpr"); errno = 0; {
perror ("ptrace write_gpr");
errno = 0;
} }
} }
/* write floating point registers now. */ /* write floating point registers now. */
for ( ii=0; ii < 32; ++ii) { for ( ii=0; ii < 32; ++ii)
{
ptrace (PT_WRITE_FPR, inferior_pid, ptrace (PT_WRITE_FPR, inferior_pid,
(PTRACE_ARG3_TYPE) &registers[REGISTER_BYTE (FP0_REGNUM+ii)], (PTRACE_ARG3_TYPE) &registers[REGISTER_BYTE (FP0_REGNUM+ii)],
FPR0+ii, 0); FPR0+ii, 0);
if ( errno ) { if (errno)
perror ("ptrace write_fpr"); errno = 0; {
perror ("ptrace write_fpr");
errno = 0;
} }
} }
/* write special registers. */ /* write special registers. */
for (ii=0; ii <= LAST_SP_REGNUM-FIRST_SP_REGNUM; ++ii) { for (ii=0; ii <= LAST_SP_REGNUM-FIRST_SP_REGNUM; ++ii)
{
ptrace (PT_WRITE_GPR, inferior_pid, ptrace (PT_WRITE_GPR, inferior_pid,
(PTRACE_ARG3_TYPE) special_regs[ii], (PTRACE_ARG3_TYPE) special_regs[ii],
*(int*)&registers[REGISTER_BYTE (FIRST_SP_REGNUM+ii)], 0); *(int*)&registers[REGISTER_BYTE (FIRST_SP_REGNUM+ii)], 0);
if ( errno ) { if (errno)
perror ("ptrace write_gpr"); errno = 0; {
perror ("ptrace write_gpr");
errno = 0;
} }
} }
} }
/* else, a specific register number is given... */ /* else, a specific register number is given... */
else if (regno < FP0_REGNUM) { /* a GPR */ else if (regno < FP0_REGNUM) /* a GPR */
{
ptrace (PT_WRITE_GPR, inferior_pid, (PTRACE_ARG3_TYPE) regno, ptrace (PT_WRITE_GPR, inferior_pid, (PTRACE_ARG3_TYPE) regno,
*(int*)&registers[REGISTER_BYTE (regno)], 0); *(int*)&registers[REGISTER_BYTE (regno)], 0);
} }
else if (regno <= FPLAST_REGNUM) { /* a FPR */ else if (regno <= FPLAST_REGNUM) /* a FPR */
{
ptrace (PT_WRITE_FPR, inferior_pid, ptrace (PT_WRITE_FPR, inferior_pid,
(PTRACE_ARG3_TYPE) &registers[REGISTER_BYTE (regno)], (PTRACE_ARG3_TYPE) &registers[REGISTER_BYTE (regno)],
regno-FP0_REGNUM+FPR0, 0); regno - FP0_REGNUM + FPR0, 0);
} }
else if (regno <= LAST_SP_REGNUM) { /* a special register */ else if (regno <= LAST_SP_REGNUM) /* a special register */
{
ptrace (PT_WRITE_GPR, inferior_pid, ptrace (PT_WRITE_GPR, inferior_pid,
(PTRACE_ARG3_TYPE) special_regs [regno-FIRST_SP_REGNUM], (PTRACE_ARG3_TYPE) special_regs [regno-FIRST_SP_REGNUM],
*(int*)&registers[REGISTER_BYTE (regno)], 0); *(int*)&registers[REGISTER_BYTE (regno)], 0);
@ -196,26 +211,29 @@ store_inferior_registers (regno)
else else
fprintf_unfiltered (gdb_stderr, "Gdb error: register no %d not implemented.\n", regno); fprintf_unfiltered (gdb_stderr, "Gdb error: register no %d not implemented.\n", regno);
if ( errno ) { if (errno)
perror ("ptrace write"); errno = 0; {
perror ("ptrace write");
errno = 0;
} }
} }
/* Execute one dummy breakpoint instruction. This way we give the kernel /* Execute one dummy breakpoint instruction. This way we give the kernel
a chance to do some housekeeping and update inferior's internal data, a chance to do some housekeeping and update inferior's internal data,
including u_area. */ including u_area. */
static void static void
exec_one_dummy_insn () exec_one_dummy_insn ()
{ {
#define DUMMY_INSN_ADDR (TEXT_SEGMENT_BASE)+0x200 #define DUMMY_INSN_ADDR (TEXT_SEGMENT_BASE)+0x200
unsigned long shadow; char shadow_contents[BREAKPOINT_MAX]; /* Stash old bkpt addr contents */
unsigned int status, pid; unsigned int status, pid;
/* We plant one dummy breakpoint into DUMMY_INSN_ADDR address. We assume that /* We plant one dummy breakpoint into DUMMY_INSN_ADDR address. We assume that
this address will never be executed again by the real code. */ this address will never be executed again by the real code. */
target_insert_breakpoint (DUMMY_INSN_ADDR, &shadow); target_insert_breakpoint (DUMMY_INSN_ADDR, shadow_contents);
errno = 0; errno = 0;
ptrace (PT_CONTINUE, inferior_pid, (PTRACE_ARG3_TYPE) DUMMY_INSN_ADDR, 0, 0); ptrace (PT_CONTINUE, inferior_pid, (PTRACE_ARG3_TYPE) DUMMY_INSN_ADDR, 0, 0);
@ -226,7 +244,7 @@ exec_one_dummy_insn ()
pid = wait (&status); pid = wait (&status);
} while (pid != inferior_pid); } while (pid != inferior_pid);
target_remove_breakpoint (DUMMY_INSN_ADDR, &shadow); target_remove_breakpoint (DUMMY_INSN_ADDR, shadow_contents);
} }
void void
@ -238,8 +256,8 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
{ {
/* fetch GPRs and special registers from the first register section /* fetch GPRs and special registers from the first register section
in core bfd. */ in core bfd. */
if (which == 0) { if (which == 0)
{
/* copy GPRs first. */ /* copy GPRs first. */
memcpy (registers, core_reg_sect, 32 * 4); memcpy (registers, core_reg_sect, 32 * 4);
@ -260,7 +278,7 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
fprintf_unfiltered (gdb_stderr, "Gdb error: unknown parameter to fetch_core_registers().\n"); fprintf_unfiltered (gdb_stderr, "Gdb error: unknown parameter to fetch_core_registers().\n");
} }
/* vmap_symtab - handle symbol translation on vmapping */ /* handle symbol translation on vmapping */
static void static void
vmap_symtab (vp) vmap_symtab (vp)
@ -339,11 +357,13 @@ vmap_symtab (vp)
} }
/* Add symbols for an objfile. */ /* Add symbols for an objfile. */
static int static int
objfile_symbol_add (arg) objfile_symbol_add (arg)
char *arg; char *arg;
{ {
struct objfile *obj = (struct objfile *) arg; struct objfile *obj = (struct objfile *) arg;
syms_from_objfile (obj, 0, 0, 0); syms_from_objfile (obj, 0, 0, 0);
new_symfile_objfile (obj, 0, 0); new_symfile_objfile (obj, 0, 0);
return 1; return 1;
@ -355,8 +375,9 @@ objfile_symbol_add (arg)
core file), the caller should set it to -1, and we will open the file. core file), the caller should set it to -1, and we will open the file.
Return the vmap new entry. */ Return the vmap new entry. */
static struct vmap * static struct vmap *
add_vmap(ldi) add_vmap (ldi)
register struct ld_info *ldi; register struct ld_info *ldi;
{ {
bfd *abfd, *last; bfd *abfd, *last;
@ -368,7 +389,7 @@ add_vmap(ldi)
xcoff_relocate_symtab(). Now we need to have persistent object xcoff_relocate_symtab(). Now we need to have persistent object
and member names, so we should save them. */ and member names, so we should save them. */
mem = ldi->ldinfo_filename + strlen(ldi->ldinfo_filename) + 1; mem = ldi->ldinfo_filename + strlen (ldi->ldinfo_filename) + 1;
mem = savestring (mem, strlen (mem)); mem = savestring (mem, strlen (mem));
objname = savestring (ldi->ldinfo_filename, strlen (ldi->ldinfo_filename)); objname = savestring (ldi->ldinfo_filename, strlen (ldi->ldinfo_filename));
@ -377,45 +398,46 @@ add_vmap(ldi)
enhancement would be to only open it once for every object. */ enhancement would be to only open it once for every object. */
abfd = bfd_openr (objname, gnutarget); abfd = bfd_openr (objname, gnutarget);
else else
abfd = bfd_fdopenr(objname, gnutarget, ldi->ldinfo_fd); abfd = bfd_fdopenr (objname, gnutarget, ldi->ldinfo_fd);
if (!abfd) if (!abfd)
error("Could not open `%s' as an executable file: %s", error ("Could not open `%s' as an executable file: %s",
objname, bfd_errmsg(bfd_get_error ())); objname, bfd_errmsg (bfd_get_error ()));
/* make sure we have an object file */ /* make sure we have an object file */
if (bfd_check_format(abfd, bfd_object)) if (bfd_check_format (abfd, bfd_object))
vp = map_vmap (abfd, 0); vp = map_vmap (abfd, 0);
else if (bfd_check_format(abfd, bfd_archive)) { else if (bfd_check_format (abfd, bfd_archive))
{
last = 0; last = 0;
/* /* FIXME??? am I tossing BFDs? bfd? */
* FIXME??? am I tossing BFDs? bfd? while ((last = bfd_openr_next_archived_file (abfd, last)))
*/ if (STREQ (mem, last->filename))
while (last = bfd_openr_next_archived_file(abfd, last))
if (STREQ(mem, last->filename))
break; break;
if (!last) { if (!last)
bfd_close(abfd); {
bfd_close (abfd);
/* FIXME -- should be error */ /* FIXME -- should be error */
warning("\"%s\": member \"%s\" missing.", abfd->filename, mem); warning ("\"%s\": member \"%s\" missing.", abfd->filename, mem);
return; return;
} }
if (!bfd_check_format(last, bfd_object)) { if (!bfd_check_format(last, bfd_object))
bfd_close(last); /* XXX??? */ {
bfd_close (last); /* XXX??? */
goto obj_err; goto obj_err;
} }
vp = map_vmap (last, abfd); vp = map_vmap (last, abfd);
} }
else { else
{
obj_err: obj_err:
bfd_close(abfd); bfd_close (abfd);
error ("\"%s\": not in executable format: %s.", error ("\"%s\": not in executable format: %s.",
objname, bfd_errmsg(bfd_get_error ())); objname, bfd_errmsg (bfd_get_error ()));
/*NOTREACHED*/ /*NOTREACHED*/
} }
obj = allocate_objfile (vp->bfd, 0); obj = allocate_objfile (vp->bfd, 0);
@ -434,15 +456,11 @@ add_vmap(ldi)
return vp; return vp;
} }
/* /* update VMAP info with ldinfo() information
* vmap_ldinfo - update VMAP info with ldinfo() information Input is ptr to ldinfo() results. */
*
* Input:
* ldi - ^ to ldinfo() results.
*/
static void static void
vmap_ldinfo(ldi) vmap_ldinfo (ldi)
register struct ld_info *ldi; register struct ld_info *ldi;
{ {
struct stat ii, vi; struct stat ii, vi;
@ -450,23 +468,21 @@ vmap_ldinfo(ldi)
register got_one, retried; register got_one, retried;
CORE_ADDR ostart; CORE_ADDR ostart;
/* /* For each *ldi, see if we have a corresponding *vp.
* for each *ldi, see if we have a corresponding *vp If so, update the mapping, and symbol table.
* if so, update the mapping, and symbol table. If not, add an entry and symbol table. */
* if not, add an entry and symbol table.
*/
do { do {
char *name = ldi->ldinfo_filename; char *name = ldi->ldinfo_filename;
char *memb = name + strlen(name) + 1; char *memb = name + strlen(name) + 1;
retried = 0; retried = 0;
if (fstat(ldi->ldinfo_fd, &ii) < 0) if (fstat (ldi->ldinfo_fd, &ii) < 0)
fatal("cannot fstat(%d) on %s" fatal ("cannot fstat(fd=%d) on %s", ldi->ldinfo_fd, name);
, ldi->ldinfo_fd retry:
, name); for (got_one = 0, vp = vmap; vp; vp = vp->nxt)
retry: {
for (got_one = 0, vp = vmap; vp; vp = vp->nxt) {
FILE *io; FILE *io;
/* First try to find a `vp', which is the same as in ldinfo. /* First try to find a `vp', which is the same as in ldinfo.
@ -481,20 +497,20 @@ retry:
|| (memb[0] && !STREQ(memb, vp->member))) || (memb[0] && !STREQ(memb, vp->member)))
continue; continue;
io = bfd_cache_lookup(vp->bfd); /* totally opaque! */ io = bfd_cache_lookup (vp->bfd); /* totally opaque! */
if (!io) if (!io)
fatal("cannot find BFD's iostream for %s", vp->name); fatal ("cannot find BFD's iostream for %s", vp->name);
/* see if we are referring to the same file */ /* See if we are referring to the same file. */
if (fstat (fileno(io), &vi) < 0)
if (fstat(fileno(io), &vi) < 0) fatal ("cannot fstat(fd=%d) the BFD for %s (errno=%d)",
fatal("cannot fstat BFD for %s", vp->name); fileno(io), vp->name, errno);
if (ii.st_dev != vi.st_dev || ii.st_ino != vi.st_ino) if (ii.st_dev != vi.st_dev || ii.st_ino != vi.st_ino)
continue; continue;
if (!retried) if (!retried)
close(ldi->ldinfo_fd); close (ldi->ldinfo_fd);
++got_one; ++got_one;
@ -507,7 +523,8 @@ retry:
vp->dstart = (CORE_ADDR) ldi->ldinfo_dataorg; vp->dstart = (CORE_ADDR) ldi->ldinfo_dataorg;
vp->dend = vp->dstart + ldi->ldinfo_datasize; vp->dend = vp->dstart + ldi->ldinfo_datasize;
if (vp->tadj) { if (vp->tadj)
{
vp->tstart += vp->tadj; vp->tstart += vp->tadj;
vp->tend += vp->tadj; vp->tend += vp->tadj;
} }
@ -519,8 +536,9 @@ retry:
} }
/* if there was no matching *vp, we must perforce create the sucker(s) */ /* if there was no matching *vp, we must perforce create the sucker(s) */
if (!got_one && !retried) { if (!got_one && !retried)
add_vmap(ldi); {
add_vmap (ldi);
++retried; ++retried;
goto retry; goto retry;
} }
@ -571,13 +589,13 @@ vmap_exec ()
/* xcoff_relocate_symtab - hook for symbol table relocation. /* xcoff_relocate_symtab - hook for symbol table relocation.
also reads shared libraries.. */ also reads shared libraries.. */
void
xcoff_relocate_symtab (pid) xcoff_relocate_symtab (pid)
unsigned int pid; unsigned int pid;
{ {
#define MAX_LOAD_SEGS 64 /* maximum number of load segments */ #define MAX_LOAD_SEGS 64 /* maximum number of load segments */
struct ld_info *ldi; struct ld_info *ldi;
int temp;
ldi = (void *) alloca(MAX_LOAD_SEGS * sizeof (*ldi)); ldi = (void *) alloca(MAX_LOAD_SEGS * sizeof (*ldi));
@ -589,14 +607,12 @@ unsigned int pid;
usleep (36000); usleep (36000);
errno = 0; errno = 0;
ptrace(PT_LDINFO, pid, (PTRACE_ARG3_TYPE) ldi, ptrace (PT_LDINFO, pid, (PTRACE_ARG3_TYPE) ldi,
MAX_LOAD_SEGS * sizeof(*ldi), ldi); MAX_LOAD_SEGS * sizeof(*ldi), ldi);
if (errno) { if (errno)
perror_with_name ("ptrace ldinfo"); perror_with_name ("ptrace ldinfo");
return 0;
}
vmap_ldinfo(ldi); vmap_ldinfo (ldi);
do { do {
/* We are allowed to assume CORE_ADDR == pointer. This code is /* We are allowed to assume CORE_ADDR == pointer. This code is
@ -619,6 +635,7 @@ unsigned int pid;
/* Relocate symtabs and read in shared library info, based on symbols /* Relocate symtabs and read in shared library info, based on symbols
from the core file. */ from the core file. */
void void
xcoff_relocate_core () xcoff_relocate_core ()
{ {
@ -649,7 +666,7 @@ xcoff_relocate_core ()
ldinfo_sec = bfd_get_section_by_name (core_bfd, ".ldinfo"); ldinfo_sec = bfd_get_section_by_name (core_bfd, ".ldinfo");
if (ldinfo_sec == NULL) if (ldinfo_sec == NULL)
{ {
bfd_err: bfd_err:
fprintf_filtered (gdb_stderr, "Couldn't get ldinfo from core file: %s\n", fprintf_filtered (gdb_stderr, "Couldn't get ldinfo from core file: %s\n",
bfd_errmsg (bfd_get_error ())); bfd_errmsg (bfd_get_error ()));
do_cleanups (old); do_cleanups (old);
@ -681,7 +698,7 @@ bfd_err:
++names_found; ++names_found;
} while (names_found < 2); } while (names_found < 2);
ldip = (struct ld_info *)buffer; ldip = (struct ld_info *) buffer;
/* Can't use a file descriptor from the core file; need to open it. */ /* Can't use a file descriptor from the core file; need to open it. */
ldip->ldinfo_fd = -1; ldip->ldinfo_fd = -1;

View File

@ -1,5 +1,5 @@
/* Execute AIXcoff files, for GDB. /* Execute AIXcoff files, for GDB.
Copyright 1988, 1989, 1991, 1992 Free Software Foundation, Inc. Copyright 1988, 1989, 1991, 1992, 1994 Free Software Foundation, Inc.
Derived from exec.c. Modified by IBM Corporation. Derived from exec.c. Modified by IBM Corporation.
Donated by IBM Corporation and Cygnus Support. Donated by IBM Corporation and Cygnus Support.
@ -35,6 +35,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "target.h" #include "target.h"
#include "gdbcmd.h" #include "gdbcmd.h"
#include "gdbcore.h" #include "gdbcore.h"
#include "language.h"
#include "symfile.h" #include "symfile.h"
#include "objfiles.h" #include "objfiles.h"
@ -74,14 +75,15 @@ extern struct target_ops exec_ops;
/* exec_close - done with exec file, clean up all resources. */ /* exec_close - done with exec file, clean up all resources. */
static void static void
exec_close(quitting) exec_close (quitting)
int quitting;
{ {
register struct vmap *vp, *nxt; register struct vmap *vp, *nxt;
struct objfile *obj;
int need_symtab_cleanup = 0; int need_symtab_cleanup = 0;
for (nxt = vmap; vp = nxt; ) for (nxt = vmap; nxt; )
{ {
vp = nxt;
nxt = vp->nxt; nxt = vp->nxt;
/* if there is an objfile associated with this bfd, /* if there is an objfile associated with this bfd,
@ -93,13 +95,13 @@ exec_close(quitting)
need_symtab_cleanup = 1; need_symtab_cleanup = 1;
} }
else else
bfd_close(vp->bfd); bfd_close (vp->bfd);
/* FIXME: This routine is #if 0'd in symfile.c. What should we /* FIXME: This routine is #if 0'd in symfile.c. What should we
be doing here? Should we just free everything in be doing here? Should we just free everything in
vp->objfile->symtabs? Should free_objfile do that? */ vp->objfile->symtabs? Should free_objfile do that? */
free_named_symtabs(vp->name); free_named_symtabs (vp->name);
free(vp); free (vp);
} }
vmap = 0; vmap = 0;
@ -107,7 +109,8 @@ exec_close(quitting)
/* exec_bfd was already closed (the exec file has a vmap entry). */ /* exec_bfd was already closed (the exec file has a vmap entry). */
exec_bfd = NULL; exec_bfd = NULL;
if (exec_ops.to_sections) { if (exec_ops.to_sections)
{
free (exec_ops.to_sections); free (exec_ops.to_sections);
exec_ops.to_sections = NULL; exec_ops.to_sections = NULL;
exec_ops.to_sections_end = NULL; exec_ops.to_sections_end = NULL;
@ -117,18 +120,21 @@ exec_close(quitting)
clear_symtab_users (); clear_symtab_users ();
} }
/* /* Process the first arg in ARGS as the new exec file.
* exec_file_command - handle the "exec" command, &c.
*/ 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. */
void void
exec_file_command (filename, from_tty) exec_file_command (filename, from_tty)
char *filename; char *filename;
int from_tty; int from_tty;
{ {
target_preopen(from_tty); target_preopen (from_tty);
/* Remove any previous exec file. */ /* Remove any previous exec file. */
unpush_target(&exec_ops); unpush_target (&exec_ops);
/* Now open and digest the file the user requested, if any. */ /* Now open and digest the file the user requested, if any. */
@ -137,31 +143,31 @@ exec_file_command (filename, from_tty)
char *scratch_pathname; char *scratch_pathname;
int scratch_chan; int scratch_chan;
filename = tilde_expand(filename); filename = tilde_expand (filename);
make_cleanup (free, filename); make_cleanup (free, filename);
scratch_chan = openp(getenv("PATH"), 1, filename, scratch_chan = openp (getenv ("PATH"), 1, filename,
write_files? O_RDWR: O_RDONLY, 0, write_files? O_RDWR: O_RDONLY, 0,
&scratch_pathname); &scratch_pathname);
if (scratch_chan < 0) if (scratch_chan < 0)
perror_with_name(filename); perror_with_name (filename);
exec_bfd = bfd_fdopenr(scratch_pathname, gnutarget, scratch_chan); exec_bfd = bfd_fdopenr (scratch_pathname, gnutarget, scratch_chan);
if (!exec_bfd) if (!exec_bfd)
error("Could not open `%s' as an executable file: %s", error ("Could not open `%s' as an executable file: %s",
scratch_pathname, bfd_errmsg(bfd_get_error ())); scratch_pathname, bfd_errmsg(bfd_get_error ()));
/* make sure we have an object file */ /* make sure we have an object file */
if (!bfd_check_format(exec_bfd, bfd_object)) if (!bfd_check_format (exec_bfd, bfd_object))
error("\"%s\": not in executable format: %s.", scratch_pathname, error ("\"%s\": not in executable format: %s.", scratch_pathname,
bfd_errmsg(bfd_get_error ())); bfd_errmsg (bfd_get_error ()));
/* setup initial vmap */ /* setup initial vmap */
map_vmap (exec_bfd, 0); map_vmap (exec_bfd, 0);
if (!vmap) if (!vmap)
error("Can't find the file sections in `%s': %s", exec_bfd->filename, error ("Can't find the file sections in `%s': %s", exec_bfd->filename,
bfd_errmsg(bfd_get_error ())); bfd_errmsg(bfd_get_error ()));
if (build_section_table (exec_bfd, &exec_ops.to_sections, if (build_section_table (exec_bfd, &exec_ops.to_sections,
@ -170,33 +176,35 @@ exec_file_command (filename, from_tty)
bfd_errmsg (bfd_get_error ())); bfd_errmsg (bfd_get_error ()));
/* make sure core, if present, matches */ /* make sure core, if present, matches */
validate_files(); validate_files ();
push_target(&exec_ops); push_target(&exec_ops);
/* Tell display code(if any) about the changed file name. */ /* Tell display code (if any) about the changed file name. */
if (exec_file_display_hook) if (exec_file_display_hook)
(*exec_file_display_hook)(filename); (*exec_file_display_hook) (filename);
} }
else else
{ {
exec_close(0); /* just in case */ exec_close (0); /* just in case */
if (from_tty) if (from_tty)
printf_unfiltered("No exec file now.\n"); printf_unfiltered ("No exec file now.\n");
} }
} }
/* Set both the exec file and the symbol file, in one command. What a /* 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 novelty. Why did GDB go through four major releases before this
* command was added? command was added? */
*/
static void
file_command(arg, from_tty)
char *arg; {
exec_file_command(arg, from_tty); static void
symbol_file_command(arg, from_tty); file_command (arg, from_tty)
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);
} }
/* Locate all mappable sections of a BFD file. /* Locate all mappable sections of a BFD file.
@ -239,7 +247,7 @@ build_section_table (some_bfd, start, end)
free (*start); free (*start);
*start = (struct section_table *) xmalloc (count * sizeof (**start)); *start = (struct section_table *) xmalloc (count * sizeof (**start));
*end = *start; *end = *start;
bfd_map_over_sections (some_bfd, add_to_section_table, (char *)end); bfd_map_over_sections (some_bfd, add_to_section_table, (char *) end);
if (*end > *start + count) if (*end > *start + count)
fatal ("aborting"); fatal ("aborting");
/* We could realloc the table, but it probably loses for most files. */ /* We could realloc the table, but it probably loses for most files. */
@ -252,31 +260,29 @@ bfdsec_to_vmap(bf, sect, arg3)
sec_ptr sect; sec_ptr sect;
PTR arg3; PTR arg3;
{ {
struct vmap_and_bfd *vmap_bfd = (struct vmap_and_bfd *)arg3; struct vmap_and_bfd *vmap_bfd = (struct vmap_and_bfd *) arg3;
register struct vmap *vp, **vpp; register struct vmap *vp;
register struct symtab *syms;
bfd *arch = vmap_bfd->pbfd;
vp = vmap_bfd->pvmap; vp = vmap_bfd->pvmap;
if ((bfd_get_section_flags(bf, sect) & SEC_LOAD) == 0) if ((bfd_get_section_flags (bf, sect) & SEC_LOAD) == 0)
return; return;
if (STREQ(bfd_section_name(bf, sect), ".text")) if (STREQ(bfd_section_name (bf, sect), ".text"))
{ {
vp->tstart = 0; vp->tstart = 0;
vp->tend = vp->tstart + bfd_section_size(bf, sect); vp->tend = vp->tstart + bfd_section_size (bf, sect);
/* When it comes to this adjustment value, in contrast to our previous /* When it comes to this adjustment value, in contrast to our previous
belief shared objects should behave the same as the main load segment. 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 This is the offset from the beginning of text section to the first
real instruction. */ real instruction. */
vp->tadj = sect->filepos - bfd_section_vma(bf, sect); vp->tadj = sect->filepos - bfd_section_vma (bf, sect);
} }
else if (STREQ(bfd_section_name(bf, sect), ".data")) else if (STREQ(bfd_section_name (bf, sect), ".data"))
{ {
vp->dstart = 0; vp->dstart = 0;
vp->dend = vp->dstart + bfd_section_size(bf, sect); vp->dend = vp->dstart + bfd_section_size (bf, sect);
} }
else if (STREQ(bfd_section_name(bf, sect), ".bss")) /* FIXMEmgo */ else if (STREQ(bfd_section_name(bf, sect), ".bss")) /* FIXMEmgo */
printf_unfiltered ("bss section in exec! Don't know what the heck to do!\n"); printf_unfiltered ("bss section in exec! Don't know what the heck to do!\n");
@ -292,14 +298,13 @@ map_vmap (bf, arch)
{ {
struct vmap_and_bfd vmap_bfd; struct vmap_and_bfd vmap_bfd;
struct vmap *vp, **vpp; struct vmap *vp, **vpp;
struct objfile *obj;
vp = (void*) xmalloc (sizeof (*vp)); vp = (PTR) xmalloc (sizeof (*vp));
memset (vp, '\0', sizeof (*vp)); memset (vp, '\0', sizeof (*vp));
vp->nxt = 0; vp->nxt = 0;
vp->bfd = bf; vp->bfd = bf;
vp->name = bfd_get_filename(arch ? arch : bf); vp->name = bfd_get_filename (arch ? arch : bf);
vp->member = arch ? bfd_get_filename(bf) : ""; vp->member = arch ? bfd_get_filename (bf) : "";
vmap_bfd.pbfd = arch; vmap_bfd.pbfd = arch;
vmap_bfd.pvmap = vp; vmap_bfd.pvmap = vp;
@ -422,13 +427,13 @@ exec_files_info (t)
if (!vp) if (!vp)
return; return;
printf_unfiltered("\tMapping info for file `%s'.\n", vp->name); printf_unfiltered ("\tMapping info for file `%s'.\n", vp->name);
printf_unfiltered("\t %8.8s %8.8s %8.8s %8.8s %8.8s %s\n", printf_unfiltered ("\t %8.8s %8.8s %8.8s %8.8s %8.8s %s\n",
"tstart", "tend", "dstart", "dend", "section", "file(member)"); "tstart", "tend", "dstart", "dend", "section", "file(member)");
for (; vp; vp = vp->nxt) for (; vp; vp = vp->nxt)
printf_unfiltered("\t0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x %s%s%s%s\n", printf_unfiltered ("\t0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x %s%s%s%s\n",
vp->tstart, vp->tstart,
vp->tend, vp->tend,
vp->dstart, vp->dstart,
@ -510,17 +515,18 @@ set_section_command (args, from_tty)
/* Parse out new virtual address */ /* Parse out new virtual address */
secaddr = parse_and_eval_address (args); secaddr = parse_and_eval_address (args);
for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++) { for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++)
if (!strncmp (secname, bfd_section_name (exec_bfd, p->the_bfd_section), seclen) if (!strncmp (secname, bfd_section_name (exec_bfd, p->the_bfd_section), seclen)
&& bfd_section_name (exec_bfd, p->the_bfd_section)[seclen] == '\0') { && bfd_section_name (exec_bfd, p->the_bfd_section)[seclen] == '\0')
{
offset = secaddr - p->addr; offset = secaddr - p->addr;
p->addr += offset; p->addr += offset;
p->endaddr += offset; p->endaddr += offset;
if (from_tty) if (from_tty)
exec_files_info(&exec_ops); exec_files_info (&exec_ops);
return; return;
} }
}
if (seclen >= sizeof (secprint)) if (seclen >= sizeof (secprint))
seclen = sizeof (secprint) - 1; seclen = sizeof (secprint) - 1;
strncpy (secprint, secname, seclen); strncpy (secprint, secname, seclen);

View File

@ -1,5 +1,5 @@
/* Data structures for RS/6000 shared libraries, for GDB. /* Data structures for RS/6000 shared libraries, for GDB.
Copyright 1991, 1992 Free Software Foundation, Inc. Copyright 1991, 1992, 1994 Free Software Foundation, Inc.
This file is part of GDB. This file is part of GDB.
@ -17,8 +17,7 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* /* The vmap struct is used to describe the virtual address space of
the vmap struct is used to describe the virtual address space of
the target we are manipulating. The first entry is always the "exec" the target we are manipulating. The first entry is always the "exec"
file. Subsequent entries correspond to other objects that are file. Subsequent entries correspond to other objects that are
mapped into the address space of a process created from the "exec" file. mapped into the address space of a process created from the "exec" file.
@ -27,10 +26,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
user's issuance of a "load" command. */ user's issuance of a "load" command. */
struct vmap { struct vmap {
struct vmap *nxt; /* ^ to next in chain */ struct vmap *nxt; /* ptr to next in chain */
bfd *bfd; /* BFD for mappable object library */ bfd *bfd; /* BFD for mappable object library */
char *name; /* ^ to object file name */ char *name; /* ptr to object file name */
char *member; /* ^ to member name */ char *member; /* ptr to member name */
CORE_ADDR tstart; /* virtual addr where member is mapped */ CORE_ADDR tstart; /* virtual addr where member is mapped */
CORE_ADDR tend; /* virtual upper bound of member */ CORE_ADDR tend; /* virtual upper bound of member */
CORE_ADDR tadj; /* heuristically derived adjustment */ CORE_ADDR tadj; /* heuristically derived adjustment */