From 806f810b6981720941243c3a62be2e83c7112322 Mon Sep 17 00:00:00 2001 From: Stan Shebs Date: Thu, 13 Oct 1994 01:16:19 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 14 + gdb/TODO | 7 +- gdb/config/rs6000/rs6000.mt | 4 + gdb/config/rs6000/rs6000lynx.mt | 4 + gdb/exec.c | 205 +++++++++-- gdb/xcoffexec.c | 600 -------------------------------- 6 files changed, 191 insertions(+), 643 deletions(-) create mode 100644 gdb/config/rs6000/rs6000.mt create mode 100644 gdb/config/rs6000/rs6000lynx.mt diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b76f4a0559c..71d0bc9f23d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,17 @@ +Wed Oct 12 18:02:17 1994 Stan Shebs (shebs@andros.cygnus.com) + + * 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. + Wed Oct 12 10:08:19 1994 Jeff Law (law@snake.cs.utah.edu) * partial-stab.h (N_TEXT): Delete GDB_TARGET_IS_HPPA kludge; they diff --git a/gdb/TODO b/gdb/TODO index a1ca339b173..6d55d5fd367 100644 --- a/gdb/TODO +++ b/gdb/TODO @@ -274,9 +274,6 @@ Possible feature: A version of the "disassemble" command which shows both source and assembly code ("set symbol-filename on" is a partial solution). -xcoffexec.c should be eliminated, contents going into either exec.c -or rs6000-nat.c. - investigate "x/s 0" (right now stops early) (I think maybe GDB is using a 0 address for bad purposes internally). @@ -320,9 +317,7 @@ Put dirname in psymtabs and change lookup*symtab to use dirname (so /foo/bar.c works whether compiled by cc /foo/bar.c, or cd /foo; cc bar.c). -merge xcoffexec.c and exec.c (might need a simple hook or two in -exec.c, but that's no excuse to duplicate the whole thing). Merge -xcoffread.c and coffread.c. Use breakpoint_re_set instead of +Merge xcoffread.c and coffread.c. Use breakpoint_re_set instead of fixup_breakpoints. Fix byte order and int size sins in tm-a29k.h diff --git a/gdb/config/rs6000/rs6000.mt b/gdb/config/rs6000/rs6000.mt new file mode 100644 index 00000000000..17f7ac8b846 --- /dev/null +++ b/gdb/config/rs6000/rs6000.mt @@ -0,0 +1,4 @@ +# Target: IBM RS/6000 running AIX + +TM_FILE= tm-rs6000.h +TDEPFILES= rs6000-pinsn.o rs6000-tdep.o xcoffsolib.o exec.o diff --git a/gdb/config/rs6000/rs6000lynx.mt b/gdb/config/rs6000/rs6000lynx.mt new file mode 100644 index 00000000000..b1423b79f94 --- /dev/null +++ b/gdb/config/rs6000/rs6000lynx.mt @@ -0,0 +1,4 @@ +# Target: RS6000 running LynxOS + +TM_FILE= tm-rs6000ly.h +TDEPFILES= coff-solib.o rs6000-pinsn.o rs6000-tdep.o exec.o diff --git a/gdb/exec.c b/gdb/exec.c index 445077173a1..b0565bc5b5c 100644 --- a/gdb/exec.c +++ b/gdb/exec.c @@ -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 @@ -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 diff --git a/gdb/xcoffexec.c b/gdb/xcoffexec.c index 35c8902fd7b..e69de29bb2d 100644 --- a/gdb/xcoffexec.c +++ b/gdb/xcoffexec.c @@ -1,600 +0,0 @@ -/* Execute AIXcoff files, for GDB. - Copyright 1988, 1989, 1991, 1992, 1994 Free Software Foundation, Inc. - Derived from exec.c. Modified by IBM Corporation. - Donated by IBM Corporation and Cygnus Support. - -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 2 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, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* xcoff-exec - deal with executing XCOFF files. */ - -#include "defs.h" - -#include -#include -#include -#include -#include -#include - -#include "frame.h" -#include "inferior.h" -#include "target.h" -#include "gdbcmd.h" -#include "gdbcore.h" -#include "language.h" -#include "symfile.h" -#include "objfiles.h" - -#include "bfd.h" -#include "xcoffsolib.h" - -/* Prototypes for local functions */ - -static void -file_command PARAMS ((char *, int)); - -static void -exec_close PARAMS ((int)); - -struct vmap * -map_vmap PARAMS ((bfd *, bfd *)); - -struct section_table *exec_sections, *exec_sections_end; - -/* Whether to open exec and core files read-only or read-write. */ - -int write_files = 0; - -extern int info_verbose; - -bfd *exec_bfd; /* needed by core.c */ - -extern char *getenv(); -extern void add_syms_addr_command (); -extern void symbol_file_command (); -static void exec_files_info(); - -struct vmap *vmap; /* current vmap */ - -extern struct target_ops exec_ops; - -/* exec_close - done with exec file, clean up all resources. */ - -static void -exec_close (quitting) - int quitting; -{ - register struct vmap *vp, *nxt; - int need_symtab_cleanup = 0; - - for (nxt = vmap; nxt; ) - { - 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 - 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 = 0; - - /* exec_bfd was already closed (the exec file has a vmap entry). */ - exec_bfd = NULL; - - if (exec_ops.to_sections) - { - /* Reflect to_sections freeing in current_target if it is - the exec target. Otherwise target_xfer_memory (eventually - called from clear_symtab_users) might access the freed - exec_ops.to_sections via the copy in current_target. */ - if (current_target.to_sections == exec_ops.to_sections) - { - current_target.to_sections = NULL; - current_target.to_sections_end = NULL; - } - - free (exec_ops.to_sections); - exec_ops.to_sections = NULL; - exec_ops.to_sections_end = NULL; - } - - /* If we are quitting, we don't want to call breakpoint_re_set which may - output messages which would just be confusing in this context. */ - if (!quitting && need_symtab_cleanup) - clear_symtab_users (); -} - -/* 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. */ - -void -exec_file_command (filename, from_tty) - char *filename; - int from_tty; -{ - target_preopen (from_tty); - - /* Remove any previous exec file. */ - unpush_target (&exec_ops); - - /* Now open and digest the file the user requested, if any. */ - - if (filename) - { - char *scratch_pathname; - int scratch_chan; - - filename = tilde_expand (filename); - make_cleanup (free, filename); - - scratch_chan = openp (getenv ("PATH"), 1, filename, - write_files? O_RDWR: O_RDONLY, 0, - &scratch_pathname); - if (scratch_chan < 0) - perror_with_name (filename); - - exec_bfd = bfd_fdopenr (scratch_pathname, gnutarget, scratch_chan); - if (!exec_bfd) - error ("Could not open `%s' as an executable file: %s", - scratch_pathname, bfd_errmsg(bfd_get_error ())); - - /* make sure we have an object file */ - - if (!bfd_check_format (exec_bfd, bfd_object)) - error ("\"%s\": not in executable format: %s.", scratch_pathname, - bfd_errmsg (bfd_get_error ())); - - /* setup initial vmap */ - - map_vmap (exec_bfd, 0); - if (!vmap) - error ("Can't find the file sections in `%s': %s", exec_bfd->filename, - bfd_errmsg(bfd_get_error ())); - - if (build_section_table (exec_bfd, &exec_ops.to_sections, - &exec_ops.to_sections_end)) - error ("Can't find the file sections in `%s': %s", exec_bfd->filename, - bfd_errmsg (bfd_get_error ())); - - /* make sure core, if present, matches */ - validate_files (); - - push_target(&exec_ops); - - /* Tell display code (if any) about the changed file name. */ - if (exec_file_display_hook) - (*exec_file_display_hook) (filename); - } - else - { - exec_close (0); /* just in case */ - if (from_tty) - printf_unfiltered ("No exec file now.\n"); - } -} - -/* 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 (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. - 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 (abfd, asect, table_pp_char) - bfd *abfd; - sec_ptr asect; - char *table_pp_char; -{ - struct section_table **table_pp = (struct section_table **)table_pp_char; - flagword aflag; - - aflag = bfd_get_section_flags (abfd, asect); - /* FIXME, we need to handle BSS segment here...it alloc's but doesn't load */ - if (!(aflag & SEC_LOAD)) - return; - if (0 == bfd_section_size (abfd, asect)) - return; - (*table_pp)->bfd = abfd; - (*table_pp)->the_bfd_section = asect; - (*table_pp)->addr = bfd_section_vma (abfd, asect); - (*table_pp)->endaddr = (*table_pp)->addr + bfd_section_size (abfd, asect); - (*table_pp)++; -} - -int -build_section_table (some_bfd, start, end) - bfd *some_bfd; - struct section_table **start, **end; -{ - unsigned count; - - count = bfd_count_sections (some_bfd); - if (count == 0) - fatal ("aborting"); /* return 1? */ - if (*start) - free (*start); - *start = (struct section_table *) xmalloc (count * sizeof (**start)); - *end = *start; - bfd_map_over_sections (some_bfd, add_to_section_table, (char *) end); - if (*end > *start + count) - fatal ("aborting"); - /* We could realloc the table, but it probably loses for most files. */ - return 0; -} - -static void -bfdsec_to_vmap(bf, sect, arg3) - bfd *bf; - sec_ptr sect; - PTR arg3; -{ - struct vmap_and_bfd *vmap_bfd = (struct vmap_and_bfd *) arg3; - register struct vmap *vp; - vp = vmap_bfd->pvmap; - - if ((bfd_get_section_flags (bf, sect) & SEC_LOAD) == 0) - return; - - if (STREQ(bfd_section_name (bf, sect), ".text")) - { - vp->tstart = 0; - vp->tend = vp->tstart + bfd_section_size (bf, 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 (bf, sect); - } - else if (STREQ(bfd_section_name (bf, sect), ".data")) - { - vp->dstart = 0; - vp->dend = vp->dstart + bfd_section_size (bf, sect); - } - 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"); -} - -/* Make a vmap for the BFD "bf", which might be a member of the archive - BFD "arch". Return the new vmap. */ - -struct vmap * -map_vmap (bf, arch) - bfd *bf; - bfd *arch; -{ - struct vmap_and_bfd vmap_bfd; - struct vmap *vp, **vpp; - - vp = (PTR) xmalloc (sizeof (*vp)); - memset (vp, '\0', sizeof (*vp)); - vp->nxt = 0; - vp->bfd = bf; - vp->name = bfd_get_filename (arch ? arch : bf); - vp->member = arch ? bfd_get_filename (bf) : ""; - - vmap_bfd.pbfd = arch; - vmap_bfd.pvmap = vp; - bfd_map_over_sections (bf, 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 exec file, address within gdb address-space, - length, and a flag indicating whether to read or write. - - Result is a length: - - 0: We cannot handle this address and length. - > 0: We have handled N bytes starting at this address. - (If N == length, we did it all.) We might be able - to handle more bytes beyond this length, but no - promises. - < 0: We cannot handle this address, but if somebody - else handles (-N) bytes, we can start from there. - - The same routine is used to handle both core and exec files; - we just tail-call it with more arguments to select between them. */ - -int -xfer_memory (memaddr, myaddr, len, write, target) - CORE_ADDR memaddr; - char *myaddr; - int len; - int write; - struct target_ops *target; -{ - boolean res; - struct section_table *p; - CORE_ADDR nextsectaddr, memend; - boolean (*xfer_fn) PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type)); - - if (len <= 0) - fatal ("aborting"); - - memend = memaddr + len; - xfer_fn = write? bfd_set_section_contents: bfd_get_section_contents; - nextsectaddr = memend; - - for (p = target->to_sections; p < target->to_sections_end; p++) - { - if (p->addr <= memaddr) - if (p->endaddr >= memend) - { - /* Entire transfer is within this section. */ - res = xfer_fn (p->bfd, p->the_bfd_section, myaddr, memaddr - p->addr, len); - return (res != 0) ? len : 0; - } - else if (p->endaddr <= memaddr) - { - /* This section ends before the transfer starts. */ - continue; - } - else - { - /* 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); - return (res != 0) ? len : 0; - } - else if (p->addr < nextsectaddr) - nextsectaddr = p->addr; - } - - if (nextsectaddr >= memend) - return 0; /* We can't help */ - else - return - (nextsectaddr - memaddr); /* Next boundary where we can help */ -} - -void -print_section_info (t, abfd) - struct target_ops *t; - bfd *abfd; -{ - struct section_table *p; - - /* FIXME-32x64: Need a version of print_address_numeric with field width. */ - printf_filtered ("\t`%s', ", bfd_get_filename(abfd)); - wrap_here (" "); - printf_filtered ("file type %s.\n", bfd_get_target(abfd)); - - for (p = t->to_sections; p < t->to_sections_end; p++) { - printf_filtered ("\t%s", - local_hex_string_custom ((unsigned long) p->addr, "08l")); - printf_filtered (" - %s", - local_hex_string_custom ((unsigned long) p->endaddr, "08l")); - if (info_verbose) - printf_filtered (" @ %s", - local_hex_string_custom ((unsigned long) p->the_bfd_section->filepos, "08l")); - printf_filtered (" is %s", bfd_section_name (p->bfd, p->the_bfd_section)); - if (p->bfd != abfd) { - printf_filtered (" in %s", bfd_get_filename (p->bfd)); - } - printf_filtered ("\n"); - } -} - - -static void -exec_files_info (t) - struct target_ops *t; -{ - register struct vmap *vp = vmap; - - print_section_info (t, exec_bfd); - - if (!vp) - return; - - 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", - "tstart", "tend", "dstart", "dend", "section", "file(member)"); - - for (; 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 ? ")" : ""); -} - -#ifdef DAMON -/* Damon's implementation of set_section_command! It is based on the sex member - (which is a section pointer from vmap) of vmap. - We will not have multiple vmap entries (one for each section), rather transmit - text and data base offsets and fix them at the same time. Elimination of sex - entry in vmap make this function obsolute, use the one from exec.c. - Need further testing!! FIXMEmgo. */ - -static void -set_section_command(args, from_tty) -char *args; -{ - register struct vmap *vp = vmap; - char *secname; - unsigned seclen; - unsigned long secaddr; - char secprint[100]; - long offset; - - 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); - - for (vp = vmap; vp; vp = vp->nxt) { - if (!strncmp(secname - , bfd_section_name(vp->bfd, vp->sex), seclen) - && bfd_section_name(vp->bfd, vp->sex)[seclen] == '\0') { - offset = secaddr - vp->tstart; - vp->tstart += offset; - vp->tend += offset; - exec_files_info(); - return; - } - } - - if (seclen >= sizeof(secprint)) - seclen = sizeof(secprint) - 1; - strncpy(secprint, secname, seclen); - secprint[seclen] = '\0'; - error("Section %s not found", secprint); -} -#else -static void -set_section_command (args, from_tty) - char *args; - int from_tty; -{ - struct section_table *p; - char *secname; - unsigned seclen; - unsigned long secaddr; - char secprint[100]; - long offset; - - 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); - - 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) - && bfd_section_name (exec_bfd, p->the_bfd_section)[seclen] == '\0') - { - offset = secaddr - p->addr; - p->addr += offset; - p->endaddr += offset; - if (from_tty) - exec_files_info (&exec_ops); - return; - } - - if (seclen >= sizeof (secprint)) - seclen = sizeof (secprint) - 1; - strncpy (secprint, secname, seclen); - secprint[seclen] = '\0'; - error ("Section %s not found", secprint); -} - -#endif /* !DAMON */ - -struct target_ops exec_ops = { - "exec", "Local exec file", - "Use an executable file as a target.\n\ -Specify the filename of the executable file.", - exec_file_command, exec_close, /* open, close */ - find_default_attach, 0, 0, 0, /* attach, detach, resume, wait, */ - 0, 0, /* fetch_registers, store_registers, */ - 0, /* prepare_to_store */ - xfer_memory, exec_files_info, - 0, 0, /* insert_breakpoint, remove_breakpoint, */ - 0, 0, 0, 0, 0, /* terminal stuff */ - 0, 0, /* kill, load */ - 0, /* lookup sym */ - find_default_create_inferior, - 0, /* mourn_inferior */ - 0, /* can_run */ - 0, /* notice_signals */ - file_stratum, 0, /* next */ - 0, 1, 0, 0, 0, /* all mem, mem, stack, regs, exec */ - 0, 0, /* section pointers */ - OPS_MAGIC, /* Always the last thing */ -}; - -void -_initialize_exec() -{ - - add_com("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."); - - add_com("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."); - - 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_target(&exec_ops); -} -- 2.30.2