Make writing to files work properly. (Fixes to BFD are also needed.)
authorJohn Gilmore <gnu@cygnus>
Wed, 4 Sep 1991 07:43:50 +0000 (07:43 +0000)
committerJohn Gilmore <gnu@cygnus>
Wed, 4 Sep 1991 07:43:50 +0000 (07:43 +0000)
* core.c (core_open):  Open file ourselves, read or r/w, depending on
write_files.  Use bfd_fdopenr.
* gdbcore.h (write_files):  New variable.
* exec.c (write_files):  Define variable, add set&show for it.
(exec_file_command):  Use write_files to open for read or r/write.

Make shared library reading happen automatically.  These changes
are mostly from Peter Schauer <pes@regent.e-technik.tu-muenchen.de>.

* inferior.h (stop_soon_quietly):  Add to exported variables.
* infrun.c (child_create_inferior):  call solib hook, if defined.
(child_attach):  call solib hook, if defined.
* solib.c:  Include inferior.h.  Add from_tty to so_list as kludge.
(find_solib):  Use lookup_misc_func rather than hand-rolled.
(symbol_add_stub):  New stub for catch_errors.
(solib_add):  Avoid output if !from_tty.  Catch errors rather
than just calling symbol_file_add and bombing.
(solib_create_inferior_hook):  Interface with the target process
to let it read and alloc shared libs, then figure out what it did.

* core.c (validate_files):  Fix typo, soften warning.
(Fix from Hiroto Kagotani <kagotani@cs.titech.ac.jp>.)

* utils.c (fputs_demangled):  Avoid duplicate printing if
demangling is off.  (Fix from J.T. Conklin <jtc@cayenne.com>.)

* infrun.c (proceed):  Cast -1 to (CORE_ADDR) before comparing.
(Fix from pierre@la.tce.com (Pierre Willard).)

* main.c (catch_errors):  Change argument to a char * from an int,
since a char * can point to a struct full of glop, but an int
is not guaranteed to be able to hold a pointer.
* breakpoint.c (breakpoint_cond_eval, bpstat_stop_status,
breakpoint_re_set_one, breakpoint_re_set):  Adapt.
* core.c (core_open, solib_add_stub):  Adapt.
* remote-vx.c (symbol_stub, add_symbol_stub, callers):  Adapt.

gdb/ChangeLog
gdb/breakpoint.c
gdb/core.c
gdb/exec.c
gdb/inferior.h
gdb/infrun.c
gdb/main.c
gdb/remote-vx.c
gdb/solib.c
gdb/tm-sunos.h
gdb/utils.c

index bf5a894c2cd5a5b80ee18571a3ba535c2306d1b1..b72cdf021e942f8535e0facb681e101e11243635 100644 (file)
@@ -1,3 +1,56 @@
+Tue Sep  3 18:37:46 1991  John Gilmore  (gnu at cygint.cygnus.com)
+
+       Make writing to files work properly.  (Fixes to BFD are also needed.)
+
+       * core.c (core_open):  Open file ourselves, read or r/w, depending on
+       write_files.  Use bfd_fdopenr.  
+       * gdbcore.h (write_files):  New variable.
+       * exec.c (write_files):  Define variable, add set&show for it.
+       (exec_file_command):  Use write_files to open for read or r/write.
+
+       Make shared library reading happen automatically.  These changes
+       are mostly from Peter Schauer <pes@regent.e-technik.tu-muenchen.de>.
+
+       * inferior.h (stop_soon_quietly):  Add to exported variables.
+       * infrun.c (child_create_inferior):  call solib hook, if defined.
+       (child_attach):  call solib hook, if defined.
+       * solib.c:  Include inferior.h.  Add from_tty to so_list as kludge.
+       (find_solib):  Use lookup_misc_func rather than hand-rolled.
+       (symbol_add_stub):  New stub for catch_errors.
+       (solib_add):  Avoid output if !from_tty.  Catch errors rather
+       than just calling symbol_file_add and bombing.
+       (solib_create_inferior_hook):  Interface with the target process
+       to let it read and alloc shared libs, then figure out what it did.
+
+       * core.c (validate_files):  Fix typo, soften warning.  
+       (Fix from Hiroto Kagotani <kagotani@cs.titech.ac.jp>.)
+
+       * utils.c (fputs_demangled):  Avoid duplicate printing if
+       demangling is off.  (Fix from J.T. Conklin <jtc@cayenne.com>.)
+
+       * infrun.c (proceed):  Cast -1 to (CORE_ADDR) before comparing.
+       (Fix from pierre@la.tce.com (Pierre Willard).)
+
+       * main.c (catch_errors):  Change argument to a char * from an int,
+       since a char * can point to a struct full of glop, but an int
+       is not guaranteed to be able to hold a pointer.
+       * breakpoint.c (breakpoint_cond_eval, bpstat_stop_status,
+       breakpoint_re_set_one, breakpoint_re_set):  Adapt.
+       * core.c (core_open, solib_add_stub):  Adapt.
+       * remote-vx.c (symbol_stub, add_symbol_stub, callers):  Adapt.
+
+Wed Aug 28 18:18:05 1991  John Gilmore  (gnu at cygint.cygnus.com)
+
+       * Makefile.in:  Update VERSION to 4.0.1.  Evade GNU Make bug
+       by adding .NOEXPORT target.
+
+Fri Aug 23 17:14:25 1991  John Gilmore  (gnu at cygint.cygnus.com)
+
+       * GDB-4.0 release!
+       * Update README.
+       * Makefile.in (VERSION):  Roll to 4.0.
+       (gdb.tar.Z):  Make refcard.ps as well, for shipment.
+
 Fri Aug 23 14:07:09 1991  Roland H. Pesch  (pesch at cygint.cygnus.com)
 
        * doc/gdb.texinfo: minor rewordings, crossref to ptype from print,
@@ -17,12 +70,6 @@ Fri Aug 23 14:07:09 1991  Roland H. Pesch  (pesch at cygint.cygnus.com)
 
        * doc/gdbint.texinfo: add short description of configure +template
 
-Fri Aug 23 13:46:52 1991  John Gilmore  (gnu at cygint.cygnus.com)
-
-       * GDB-4.0 release!
-       * Makefile.in (VERSION):  Roll to 4.0.
-       (gdb.tar.Z):  Make refcard.ps as well, for shipment.
-
 Fri Aug 23 11:46:08 1991  Roland H. Pesch  (pesch at cygint.cygnus.com)
 
        * doc/gdb.texinfo: update, fix bugs in "Installing" appendix
index e3f515221c63ac6db8047dca43cc91696676b2ba..f290ad582c337ea5e235a9157940efc6055eb42a 100644 (file)
@@ -3,19 +3,19 @@
 
 This file is part of GDB.
 
-GDB is free software; you can redistribute it and/or modify
+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 1, or (at your option)
-any later version.
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
 
-GDB is distributed in the hope that it will be useful,
+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 GDB; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include <stdio.h>
 #include <ctype.h>
@@ -255,6 +255,7 @@ condition_command (arg, from_tty)
   error ("No breakpoint number %d.", bnum);
 }
 
+/* ARGSUSED */
 static void
 commands_command (arg, from_tty)
      char *arg;
@@ -280,7 +281,7 @@ commands_command (arg, from_tty)
   ALL_BREAKPOINTS (b)
     if (b->number == bnum)
       {
-       if (input_from_terminal_p ())
+       if (from_tty && input_from_terminal_p ())
          {
            printf ("Type commands for when breakpoint %d is hit, one per line.\n\
 End with a line saying just \"end\".\n", bnum);
@@ -566,6 +567,15 @@ bpstat_clear_actions (bs)
     }
 }
 
+/* Stub for cleaning up our state if we error-out of a breakpoint command */
+/* ARGSUSED */
+static void
+cleanup_executing_breakpoints (ignore)
+     int ignore;
+{
+  executing_breakpoint_commands = 0;
+}
+
 /* Execute all the commands associated with all the breakpoints at this
    location.  Any of these commands could cause the process to proceed
    beyond this point, etc.  We look out for such changes by checking
@@ -575,11 +585,14 @@ bpstat_do_actions (bsp)
      bpstat *bsp;
 {
   bpstat bs;
+  struct cleanup *old_chain;
+
+  executing_breakpoint_commands = 1;
+  old_chain = make_cleanup (cleanup_executing_breakpoints, 0);
 
 top:
   bs = *bsp;
 
-  executing_breakpoint_commands = 1;
   breakpoint_proceeded = 0;
   for (; bs != NULL; bs = bs->next)
     {
@@ -599,6 +612,7 @@ top:
   clear_momentary_breakpoints ();
 
   executing_breakpoint_commands = 0;
+  discard_cleanups (old_chain);
 }
 
 int
@@ -656,12 +670,12 @@ bpstat_print (bs)
 
 /* Evaluate the expression EXP and return 1 if value is zero.
    This is used inside a catch_errors to evaluate the breakpoint condition. 
-   The argument is a "struct expression *" that has been cast to int to 
+   The argument is a "struct expression *" that has been cast to char * to 
    make it pass through catch_errors.  */
 
 static int
 breakpoint_cond_eval (exp)
-     int exp;
+     char *exp;
 {
   return value_zerop (evaluate_expression ((struct expression *)exp));
 }
@@ -713,8 +727,10 @@ bpstat_stop_status (pc, frame_address)
   int stop = 0;
   int print = 0;
   CORE_ADDR bp_addr;
+#if DECR_PC_AFTER_BREAK != 0 || defined (SHIFT_INST_REGS)
   /* True if we've hit a breakpoint (as opposed to a watchpoint).  */
   int real_breakpoint = 0;
+#endif
   /* Root of the chain of bpstat's */
   struct bpstat__struct root_bs[1];
   /* Pointer to the last thing in the chain currently.  */
@@ -790,26 +806,28 @@ which its expression is valid.\n", b->number);
              continue;
            }
        }
+#if DECR_PC_AFTER_BREAK != 0 || defined (SHIFT_INST_REGS)
       else
        real_breakpoint = 1;
+#endif
 
       if (b->frame && b->frame != frame_address)
        this_bp_stop = 0;
       else
        {
-         int value_zero;
+         int value_is_zero;
 
          if (b->cond)
            {
              /* Need to select the frame, with all that implies
                 so that the conditions will have the right context.  */
              select_frame (get_current_frame (), 0);
-             value_zero
-               = catch_errors (breakpoint_cond_eval, (int)(b->cond),
+             value_is_zero
+               = catch_errors (breakpoint_cond_eval, (char *)(b->cond),
                                "Error occurred in testing breakpoint condition.");
              free_all_values ();
            }
-         if (b->cond && value_zero)
+         if (b->cond && value_is_zero)
            {
              this_bp_stop = 0;
            }
@@ -942,7 +960,7 @@ breakpoint_1 (bnum, watchpoints)
                printf_filtered (":%d", b->line_number);
              }
            else
-             print_address_symbolic (b->address, stdout, demangle);
+             print_address_symbolic (b->address, stdout, demangle, " ");
          }
 
        printf_filtered ("\n");
@@ -982,6 +1000,7 @@ breakpoint_1 (bnum, watchpoints)
     set_next_address (last_addr);
 }
 
+/* ARGSUSED */
 static void
 breakpoints_info (bnum_exp, from_tty)
      char *bnum_exp;
@@ -995,6 +1014,7 @@ breakpoints_info (bnum_exp, from_tty)
   breakpoint_1 (bnum, 0);
 }
 
+/* ARGSUSED */
 static void
 watchpoints_info (bnum_exp, from_tty)
      char *bnum_exp;
@@ -1356,6 +1376,7 @@ tbreak_command (arg, from_tty)
   break_command_1 (arg, 1, from_tty);
 }
 
+/* ARGSUSED */
 static void
 watch_command (arg, from_tty)
      char *arg;
@@ -1394,6 +1415,7 @@ watch_command (arg, from_tty)
  * Helper routine for the until_command routine in infcmd.c.  Here
  * because it uses the mechanisms of breakpoints.
  */
+/* ARGSUSED */
 void
 until_break_command (arg, from_tty)
      char *arg;
@@ -1446,6 +1468,8 @@ until_break_command (arg, from_tty)
   proceed (-1, -1, 0);
 }
 \f
+#if 0
+/* These aren't used; I don't konw what they were for.  */
 /* Set a breakpoint at the catch clause for NAME.  */
 static int
 catch_breakpoint (name)
@@ -1467,6 +1491,7 @@ static int
 enable_catch_breakpoint ()
 {
 }
+#endif /* 0 */
 
 struct sal_chain
 {
@@ -1474,6 +1499,8 @@ struct sal_chain
   struct symtab_and_line sal;
 };
 
+#if 0
+/* This isn't used; I don't know what it was for.  */
 /* For each catch clause identified in ARGS, run FUNCTION
    with that clause as an argument.  */
 static struct symtabs_and_lines
@@ -1484,7 +1511,9 @@ map_catch_names (args, function)
   register char *p = args;
   register char *p1;
   struct symtabs_and_lines sals;
+#if 0
   struct sal_chain *sal_chain = 0;
+#endif
 
   if (p == 0)
     error_no_arg ("one or more catch names");
@@ -1523,11 +1552,14 @@ map_catch_names (args, function)
        }
 #endif
       printf ("No catch clause for exception %s.\n", p);
+#if 0
     win:
+#endif
       p = p1;
       while (*p == ' ' || *p == '\t') p++;
     }
 }
+#endif /* 0 */
 
 /* This shares a lot of code with `print_frame_label_vars' from stack.c.  */
 
@@ -1681,7 +1713,10 @@ catch_command_1 (arg, tempflag, from_tty)
     {
       /* Grab selected catch clauses.  */
       error ("catch NAME not implemeneted");
+#if 0
+      /* This isn't used; I don't know what it was for.  */
       sals = map_catch_names (arg, catch_breakpoint);
+#endif
     }
 
   if (! sals.nelts) 
@@ -1741,6 +1776,8 @@ catch_command_1 (arg, tempflag, from_tty)
   free (sals.sals);
 }
 
+#if 0
+/* These aren't used; I don't know what they were for.  */
 /* Disable breakpoints on all catch clauses described in ARGS.  */
 static void
 disable_catch (args)
@@ -1764,6 +1801,7 @@ delete_catch (args)
 {
   /* Map the delete command to catch clauses described in ARGS.  */
 }
+#endif /* 0 */
 
 static void
 catch_command (arg, from_tty)
@@ -1931,9 +1969,13 @@ delete_command (arg, from_tty)
     map_breakpoint_numbers (arg, delete_breakpoint);
 }
 
-static void
+/* Reset a breakpoint given it's struct breakpoint * BINT.
+   The value we return ends up being the return value from catch_errors.
+   Unused in this case.  */
+
+static int
 breakpoint_re_set_one (bint)
-     int bint;
+     char *bint;
 {
   struct breakpoint *b = (struct breakpoint *)bint;  /* get past catch_errs */
   int i;
@@ -1977,6 +2019,7 @@ breakpoint_re_set_one (bint)
       /* Anything without a string can't be re-set. */
       delete_breakpoint (b);
     }
+  return 0;
 }
 
 /* Re-set all breakpoints after symbols have been re-loaded.  */
@@ -1988,7 +2031,7 @@ breakpoint_re_set ()
   ALL_BREAKPOINTS (b)
     {
       b->symtab = 0;           /* Be sure we don't point to old dead symtab */
-      (void) catch_errors (breakpoint_re_set_one, (int) b, 
+      (void) catch_errors (breakpoint_re_set_one, (char *) b, 
                           "Error in re-setting breakpoint");
     }
 
@@ -2056,7 +2099,9 @@ ignore_command (args, from_tty)
   if (*p == 0)
     error ("Second argument (specified ignore-count) is missing.");
 
-  set_ignore_count (num, parse_and_eval_address (p), from_tty);
+  set_ignore_count (num,
+                   longest_to_int (value_as_long (parse_and_eval (p))),
+                   from_tty);
   printf ("\n");
 }
 \f
@@ -2122,6 +2167,7 @@ is valid is not currently in scope.\n", bpt->number);
     }
 }
 
+/* ARGSUSED */
 static void
 enable_command (args, from_tty)
      char *args;
@@ -2147,6 +2193,7 @@ disable_breakpoint (bpt)
   check_duplicates (bpt->address);
 }
 
+/* ARGSUSED */
 static void
 disable_command (args, from_tty)
      char *args;
@@ -2169,6 +2216,7 @@ enable_once_breakpoint (bpt)
   check_duplicates (bpt->address);
 }
 
+/* ARGSUSED */
 static void
 enable_once_command (args, from_tty)
      char *args;
@@ -2186,6 +2234,7 @@ enable_delete_breakpoint (bpt)
   check_duplicates (bpt->address);
 }
 
+/* ARGSUSED */
 static void
 enable_delete_command (args, from_tty)
      char *args;
index 89a417daaae724b1816236ce04e7eb976f01c854..deaae4b9e0bd1b6e48eef37a566f225515a1baa7 100644 (file)
@@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <stdio.h>
 #include <errno.h>
 #include <signal.h>
+#include <fcntl.h>
 #include "defs.h"
 #include "param.h"
 #include "frame.h"  /* required by inferior.h */
@@ -79,9 +80,9 @@ core_close (quitting)
 
 int 
 solib_add_stub (from_tty)
-     int from_tty;
+     char *from_tty;
 {
-    SOLIB_ADD (NULL, from_tty, &core_ops);
+    SOLIB_ADD (NULL, (int)from_tty, &core_ops);
     return 0;
 }
 #endif /* SOLIB_ADD */
@@ -99,6 +100,7 @@ core_open (filename, from_tty)
   char *temp;
   bfd *temp_bfd;
   int ontop;
+  int scratch_chan;
 
   target_preopen (from_tty);
   if (!filename)
@@ -116,7 +118,12 @@ core_open (filename, from_tty)
   }
 
   old_chain = make_cleanup (free, filename);
-  temp_bfd = bfd_openr (filename, NULL);
+
+  scratch_chan = open (filename, write_files? O_RDWR: O_RDONLY, 0);
+  if (scratch_chan < 0)
+    perror_with_name (filename);
+
+  temp_bfd = bfd_fdopenr (filename, NULL, scratch_chan);
   if (temp_bfd == NULL)
     {
       perror_with_name (filename);
@@ -161,7 +168,7 @@ core_open (filename, from_tty)
 
     /* Add symbols and section mappings for any shared libraries */
 #ifdef SOLIB_ADD
-    (void) catch_errors (solib_add_stub, from_tty, (char *)0);
+    (void) catch_errors (solib_add_stub, (char *)from_tty, (char *)0);
 #endif
     /* Now, set up the frame cache, and print the top of stack */
     set_current_frame ( create_new_frame (read_register (FP_REGNUM),
@@ -242,8 +249,8 @@ validate_files ()
 {
   if (exec_bfd && core_bfd)
     {
-      if (core_file_matches_executable_p (core_bfd, exec_bfd))
-       printf ("Warning: core file does not match specified executable file.\n");
+      if (!core_file_matches_executable_p (core_bfd, exec_bfd))
+       printf ("Warning: core file may not match specified executable file.\n");
       else if (bfd_get_mtime(exec_bfd) > bfd_get_mtime(core_bfd))
        printf ("Warning: exec file is newer than core file.\n");
     }
index 32795c640fb5ec5e1c89a59af4953e1f1e8e8e99..9fb378ce98bbdec1ee9bb0035235b31076e78050 100644 (file)
@@ -3,19 +3,19 @@
 
 This file is part of GDB.
 
-GDB is free software; you can redistribute it and/or modify
+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 1, or (at your option)
-any later version.
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
 
-GDB is distributed in the hope that it will be useful,
+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 GDB; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include <stdio.h>
 #include "defs.h"
@@ -23,6 +23,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "frame.h"
 #include "inferior.h"
 #include "target.h"
+#include "gdbcmd.h"
 
 #ifdef USG
 #include <sys/types.h>
@@ -30,6 +31,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include <sys/param.h>
 #include <fcntl.h>
+#include <string.h>
 
 #include "gdbcore.h"
 
@@ -44,21 +46,21 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 extern char *getenv();
 extern void child_create_inferior (), child_attach ();
-extern void add_syms_addr_command ();
 extern void symbol_file_command ();
 
 /* The Binary File Descriptor handle for the executable file.  */
 
 bfd *exec_bfd = NULL;
 
-/* The base and bounds of the table of the exec file's sections.  */
+/* Whether to open exec and core files read-only or read-write.  */
 
-struct section_table *exec_sections, *exec_sections_end;
+int write_files = 0;
 
 /* Forward decl */
 
 extern struct target_ops exec_ops;
 
+/* ARGSUSED */
 void
 exec_close (quitting)
      int quitting;
@@ -67,6 +69,11 @@ exec_close (quitting)
     bfd_close (exec_bfd);
     exec_bfd = NULL;
   }
+  if (exec_ops.sections) {
+    free (exec_ops.sections);
+    exec_ops.sections = NULL;
+    exec_ops.sections_end = NULL;
+  }
 }
 
 void
@@ -89,8 +96,8 @@ exec_file_command (filename, from_tty)
       filename = tilde_expand (filename);
       make_cleanup (free, filename);
       
-/* FIXME, if writeable is set, open for read/write. */
-      scratch_chan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
+      scratch_chan = openp (getenv ("PATH"), 1, filename, 
+                           write_files? O_RDWR: O_RDONLY, 0,
                            &scratch_pathname);
       if (scratch_chan < 0)
        perror_with_name (filename);
@@ -131,7 +138,8 @@ exec_file_command (filename, from_tty)
        }
 #endif FIXME
 
-      if (build_section_table (exec_bfd, &exec_sections, &exec_sections_end))
+      if (build_section_table (exec_bfd, &exec_ops.sections,
+                               &exec_ops.sections_end))
        error ("Can't find the file sections in `%s': %s", 
                exec_bfd->filename, bfd_errmsg (bfd_error));
 
@@ -163,20 +171,24 @@ file_command (arg, from_tty)
 }
 
 \f
-/* Locate all mappable sections of a BFD file.  */
+/* 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.  */
 
 void
-add_to_section_table (abfd, asect, table_pp)
+add_to_section_table (abfd, asect, table_pp_char)
      bfd *abfd;
      sec_ptr asect;
-     struct section_table **table_pp;
+     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;
+  (*table_pp)->bfd = abfd;
   (*table_pp)->sec_ptr = asect;
   (*table_pp)->addr = bfd_section_vma (abfd, asect);
   (*table_pp)->endaddr = (*table_pp)->addr + bfd_section_size (abfd, asect);
@@ -197,7 +209,7 @@ build_section_table (some_bfd, start, end)
     free (*start);
   *start = (struct section_table *) xmalloc (count * sizeof (**start));
   *end = *start;
-  bfd_map_over_sections (some_bfd, add_to_section_table, end);
+  bfd_map_over_sections (some_bfd, add_to_section_table, (char *)end);
   if (*end > *start + count)
     abort();
   /* We could realloc the table, but it probably loses for most files.  */
@@ -206,7 +218,7 @@ build_section_table (some_bfd, start, end)
 \f
 /* Read or write the exec file.
 
-   Args are address within exec file, address within gdb address-space,
+   Args are address within a BFD file, address within gdb address-space,
    length, and a flag indicating whether to read or write.
 
    Result is a length:
@@ -223,13 +235,12 @@ build_section_table (some_bfd, start, end)
     we just tail-call it with more arguments to select between them.  */
 
 int
-xfer_memory (memaddr, myaddr, len, write, abfd, sections, sections_end)
+xfer_memory (memaddr, myaddr, len, write, target)
      CORE_ADDR memaddr;
      char *myaddr;
      int len;
      int write;
-     bfd *abfd;
-     struct section_table *sections, *sections_end;
+     struct target_ops *target;
 {
   boolean res;
   struct section_table *p;
@@ -243,13 +254,13 @@ xfer_memory (memaddr, myaddr, len, write, abfd, sections, sections_end)
   xfer_fn = write? bfd_set_section_contents: bfd_get_section_contents;
   nextsectaddr = memend;
 
-  for (p = sections; p < sections_end; p++)
+  for (p = target->sections; p < target->sections_end; p++)
     {
       if (p->addr <= memaddr)
        if (p->endaddr >= memend)
          {
            /* Entire transfer is within this section.  */
-           res = xfer_fn (abfd, p->sec_ptr, myaddr, memaddr - p->addr, len);
+           res = xfer_fn (p->bfd, p->sec_ptr, myaddr, memaddr - p->addr, len);
            return (res != false)? len: 0;
          }
        else if (p->endaddr <= memaddr)
@@ -261,7 +272,7 @@ xfer_memory (memaddr, myaddr, len, write, abfd, sections, sections_end)
          {
            /* This section overlaps the transfer.  Just do half.  */
            len = p->endaddr - memaddr;
-           res = xfer_fn (abfd, p->sec_ptr, myaddr, memaddr - p->addr, len);
+           res = xfer_fn (p->bfd, p->sec_ptr, myaddr, memaddr - p->addr, len);
            return (res != false)? len: 0;
          }
       else if (p->addr < nextsectaddr)
@@ -274,20 +285,6 @@ xfer_memory (memaddr, myaddr, len, write, abfd, sections, sections_end)
     return - (nextsectaddr - memaddr); /* Next boundary where we can help */
 }
 
-/* The function called by target_xfer_memory via our target_ops */
-
-int
-exec_xfer_memory (memaddr, myaddr, len, write)
-     CORE_ADDR memaddr;
-     char *myaddr;
-     int len;
-     int write;
-{
-  return xfer_memory (memaddr, myaddr, len, write,
-                     exec_bfd, exec_sections, exec_sections_end);
-}
-
-
 #ifdef FIXME
 #ifdef REG_STACK_SEGMENT
 /* MOVE TO BFD... */
@@ -310,7 +307,7 @@ exec_files_info ()
 
   printf ("\tExecutable file `%s'.\n", bfd_get_filename(exec_bfd));
 
-  for (p = exec_sections; p < exec_sections_end; p++)
+  for (p = exec_ops.sections; p < exec_ops.sections_end; p++)
     printf("\texecutable from 0x%08x to 0x%08x is %s\n",
        p->addr, p->endaddr,
        bfd_section_name (exec_bfd, p->sec_ptr));
@@ -338,7 +335,7 @@ set_section_command (args, from_tty)
   /* Parse out new virtual address */
   secaddr = parse_and_eval_address (args);
 
-  for (p = exec_sections; p < exec_sections_end; p++) {
+  for (p = exec_ops.sections; p < exec_ops.sections_end; p++) {
     if (!strncmp (secname, bfd_section_name (exec_bfd, p->sec_ptr), seclen)
        && bfd_section_name (exec_bfd, p->sec_ptr)[seclen] == '\0') {
       offset = secaddr - p->addr;
@@ -363,16 +360,16 @@ Specify the filename of the executable file.",
        child_attach, 0, 0, 0, /* attach, detach, resume, wait, */
        0, 0, /* fetch_registers, store_registers, */
        0, 0, 0, /* prepare_to_store, conv_to, conv_from, */
-       exec_xfer_memory, exec_files_info,
+       xfer_memory, exec_files_info,
        0, 0, /* insert_breakpoint, remove_breakpoint, */
        0, 0, 0, 0, 0, /* terminal stuff */
        0, 0, /* kill, load */
-       add_syms_addr_command,
        0, 0, /* call fn, lookup sym */
        child_create_inferior,
        0, /* mourn_inferior */
        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 */
 };
 
@@ -401,5 +398,11 @@ This can be used if the exec file does not contain section addresses,\n\
 file itself are wrong.  Each section must be changed separately.  The\n\
 ``info files'' command lists all the sections and their addresses.");
 
+  add_show_from_set
+    (add_set_cmd ("write", class_support, var_boolean, (char *)&write_files,
+                 "Set writing into executable and core files.",
+                 &setlist),
+     &showlist);
+  
   add_target (&exec_ops);
 }
index d99c4a62848ca7ff9ec69ae6c1b59a975e27791d..151c2c2b25c1ffda33ddff83f78432b708a8dcf2 100644 (file)
@@ -4,19 +4,19 @@
 
 This file is part of GDB.
 
-GDB is free software; you can redistribute it and/or modify
+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 1, or (at your option)
-any later version.
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
 
-GDB is distributed in the hope that it will be useful,
+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 GDB; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 /* For bpstat.  */
 #include "breakpoint.h"
@@ -87,6 +87,13 @@ extern void init_wait_for_inferior ();
 extern void close_exec_file ();
 extern void reopen_exec_file ();
 
+/* From infcmd.c */
+void attach_command (
+#ifdef __STDC__
+                    char *arg, int from_tty
+#endif
+                    );
+                    
 /* Last signal that the inferior received (why it stopped).  */
 
 extern int stop_signal;
@@ -145,6 +152,13 @@ extern int step_over_calls;
 
 extern int step_multi;
 
+/* Nonzero means expecting a trap and caller will handle it themselves.
+   It is used after attach, due to attaching to a process;
+   when running in the shell before the child program has been exec'd;
+   and when running some kinds of remote stuff (FIXME?).  */
+
+int stop_soon_quietly;
+
 /* Nonzero if proceed is being used for a "finish" command or a similar
    situation when stop_registers should be saved.  */
 
index e48f76136ff383b15fbe1adea130c22c32ea88e1..b6f6a8f43de7e58119d365776f815a9b69047bd8 100644 (file)
@@ -152,10 +152,6 @@ extern char **environ;
 
 extern struct target_ops child_ops;    /* In inftarg.c */
 
-/* Copy of inferior_io_terminal when inferior was last started.  */
-
-extern char *inferior_thisrun_terminal;
-
 
 /* Sigtramp is a routine that the kernel calls (which then calls the
    signal handler).  On most machines it is a library routine that
@@ -298,6 +294,11 @@ resume (step, sig)
   }
 #endif
 
+  /* Handle any optimized stores to the inferior NOW...  */
+#ifdef DO_DEFERRED_STORES
+  DO_DEFERRED_STORES;
+#endif
+
   target_resume (step, sig);
   discard_cleanups (old_cleanups);
 }
@@ -349,7 +350,7 @@ proceed (addr, siggnal, step)
   if (step < 0)
     stop_after_trap = 1;
 
-  if (addr == -1)
+  if (addr == (CORE_ADDR)-1)
     {
       /* If there is a breakpoint at the address we will resume at,
         step one instruction before inserting breakpoints
@@ -405,11 +406,6 @@ The same program may be running in another process.");
   else if (stop_signal < NSIG && !signal_program[stop_signal])
     stop_signal= 0;
 
-  /* Handle any optimized stores to the inferior NOW...  */
-#ifdef DO_DEFERRED_STORES
-  DO_DEFERRED_STORES;
-#endif
-
   /* Resume inferior.  */
   resume (oneproc || step || bpstat_should_step (), stop_signal);
 
@@ -507,6 +503,11 @@ child_create_inferior (exec_file, allargs, env)
      restore it.  */
   save_our_env = environ;
 
+  /* Tell the terminal handling subsystem what tty we plan to run on;
+     it will just record the information for later.  */
+
+  new_tty_prefork (inferior_io_terminal);
+
 #if defined(USG) && !defined(HAVE_VFORK)
   pid = fork ();
 #else
@@ -542,10 +543,10 @@ child_create_inferior (exec_file, allargs, env)
       }
 #endif /* SET_STACK_LIMIT_HUGE */
 
-      /* Tell the terminal handling subsystem what tty we plan to run on;
-        it will now switch to that one if non-null.  */
+      /* Ask the tty subsystem to switch to the one we specified earlier
+        (or to share the current terminal, if none was specified).  */
 
-      new_tty (inferior_io_terminal);
+      new_tty ();
 
       /* Changing the signal handlers for the inferior after
         a vfork can also change them for the superior, so we don't mess
@@ -630,6 +631,13 @@ child_create_inferior (exec_file, allargs, env)
     }
   stop_soon_quietly = 0;
 
+  /* We are now in the child process of interest, having exec'd the
+     correct program, and are poised at the first instruction of the
+     new program.  */
+#ifdef SOLIB_CREATE_INFERIOR_HOOK
+  SOLIB_CREATE_INFERIOR_HOOK ();
+#endif
+
   /* Should this perhaps just be a "proceed" call?  FIXME */
   insert_step_breakpoint ();
   breakpoints_failed = insert_breakpoints ();
@@ -725,6 +733,9 @@ child_attach (args, from_tty)
   /*proceed (-1, 0, -2);*/
   target_terminal_inferior ();
   wait_for_inferior ();
+#ifdef SOLIB_ADD
+  solib_add (NULL, 0);
+#endif
   normal_stop ();
 #endif  /* ATTACH_DETACH */
 }
index b8419a2317354c3143cca334ea8b01eaba4762e9..dd5ac2101c5d645d2865804747e8e0e7f417e523 100644 (file)
@@ -231,7 +231,7 @@ return_to_top_level ()
 int
 catch_errors (func, args, errstring)
      int (*func) ();
-     int args;
+     char *args;
      char *errstring;
 {
   jmp_buf saved;
@@ -392,6 +392,7 @@ main (argc, argv)
 #ifdef ADDITIONAL_OPTIONS
        ADDITIONAL_OPTIONS
 #endif
+       {0, 0, 0, 0},
       };
 
     while (1)
@@ -785,17 +786,13 @@ dont_repeat ()
 /* Read a line from the stream "instream" without command line editing.
 
    It prints PRROMPT once at the start.
+   Action is compatible with "readline", e.g. space for the result is 
+   malloc'd and should be freed by the caller.
 
-   If RETURN_RESULT is set it allocates
-   space for whatever the user types and returns the result.
-   If not, it just discards what the user types and returns a garbage
-   non-NULL value.
-
-   No matter what return_result is, a NULL return means end of file.  */
+   A NULL return means end of file.  */
 char *
-gdb_readline (prrompt, return_result)
+gdb_readline (prrompt)
      char *prrompt;
-     int return_result;
 {
   int c;
   char *result;
@@ -808,42 +805,33 @@ gdb_readline (prrompt, return_result)
       fflush (stdout);
     }
   
-  if (return_result)
-    result = (char *) xmalloc (result_size);
+  result = (char *) xmalloc (result_size);
 
   while (1)
     {
       /* Read from stdin if we are executing a user defined command.
         This is the right thing for prompt_for_continue, at least.  */
       c = fgetc (instream ? instream : stdin);
-      if (c == EOF || c == '\n')
-       break;
-      if (return_result)
+
+      if (c == EOF)
        {
-         result[input_index++] = c;
-         while (input_index >= result_size)
-           {
-             result_size *= 2;
-             result = (char *) xrealloc (result, result_size);
-           }
+         free (result);
+         return NULL;
        }
-    }
 
-  if (c == EOF)
-    {
-      if (return_result)
-       free (result);
-      return NULL;
-    }
+      if (c == '\n')
+       break;
 
-  if (return_result)
-    {
-      result[input_index++] = '\0';
-      return result;
+      result[input_index++] = c;
+      while (input_index >= result_size)
+       {
+         result_size *= 2;
+         result = (char *) xrealloc (result, result_size);
+       }
     }
-  else
-    /* Return any old non-NULL pointer.  */
-    return (char *) "non-NULL";
+
+  result[input_index++] = '\0';
+  return result;
 }
 
 /* Declaration for fancy readline with command line editing.  */
@@ -1031,54 +1019,6 @@ stop_sig ()
 }
 #endif /* STOP_SIGNAL */
 
-#if 0
-Writing the history file upon a terminating signal is not useful,
-  because the info is rarely relevant and is in the core dump anyway.
-  It is an annoyance to have the file cluttering up the place.
-/* The list of signals that would terminate us if not caught.
-   We catch them, but just so that we can write the history file,
-   and so forth. */
-int terminating_signals[] = {
-  SIGHUP, SIGINT, SIGILL, SIGTRAP, SIGIOT,
-  SIGEMT, SIGFPE, SIGKILL, SIGBUS, SIGSEGV, SIGSYS,
-  SIGPIPE, SIGALRM, SIGTERM,
-#ifdef SIGXCPU
-  SIGXCPU,
-#endif
-#ifdef SIGXFSZ
-  SIGXFSZ,
-#endif
-#ifdef SIGVTALRM
-  SIGVTALRM,
-#endif
-#ifdef SIGPROF
-  SIGPROF,
-#endif
-#ifdef SIGLOST
-  SIGLOST,
-#endif
-#ifdef SIGUSR1
-  SIGUSR1, SIGUSR2
-#endif
-    };
-
-#define TERMSIGS_LENGTH (sizeof (terminating_signals) / sizeof (int))
-
-static void
-catch_termination (sig)
-     int sig;
-{
-  /* We are probably here because GDB has a bug.  Write out the history
-     so that we might have a better chance of reproducing it.  */
-  /* Tell the user what we are doing so he can delete the file if
-     it is unwanted.  */
-  write_history (history_filename);
-  printf ("\n%s written.\n", history_filename);
-  signal (sig, SIG_DFL);
-  kill (getpid (), sig);
-}
-#endif
-
 /* Initialize signal handlers. */
 static void
 do_nothing ()
@@ -1089,21 +1029,15 @@ static void
 init_signals ()
 {
   extern void request_quit ();
-#if 0
-  register int i;
-
-  for (i = 0; i < TERMSIGS_LENGTH; i++)
-    signal (terminating_signals[i], catch_termination);
-#endif
 
   signal (SIGINT, request_quit);
 
   /* If we initialize SIGQUIT to SIG_IGN, then the SIG_IGN will get
      passed to the inferior, which we don't want.  It would be
      possible to do a "signal (SIGQUIT, SIG_DFL)" after we fork, but
-     on BSD4.3 systems using vfork, that will (apparently) affect the
+     on BSD4.3 systems using vfork, that can affect the
      GDB process as well as the inferior (the signal handling tables
-     being shared between the two, apparently).  Since we establish
+     might be in memory, shared between the two).  Since we establish
      a handler for SIGQUIT, when we call exec it will set the signal
      to SIG_DFL for us.  */
   signal (SIGQUIT, do_nothing);
@@ -1171,7 +1105,7 @@ command_line_input (prrompt, repeat)
          && ISATTY (instream))
        rl = readline (local_prompt);
       else
-       rl = gdb_readline (local_prompt, 1);
+       rl = gdb_readline (local_prompt);
 
       if (!rl || rl == (char *) EOF)
        {
index 171e712ed6dd1b6b10d57ba6b89b16c8d19de30c..59cd053797d14eeefaf913c8cebededb524437f5 100644 (file)
@@ -1340,16 +1340,15 @@ vx_wait (status)
 \f
 static int
 symbol_stub (arg)
-     int arg;
+     char *arg;
 {
-  char *bootFile = (char *)arg;
-  symbol_file_command (bootFile, 0);
+  symbol_file_command (arg, 0);
   return 1;
 }
 
 static int
 add_symbol_stub (arg)
-     int arg;
+     char *arg;
 {
   struct ldfile *pLoadFile = (struct ldfile *)arg;
 
@@ -1413,7 +1412,7 @@ vx_open (args, from_tty)
     {
       if (*bootFile) {
        printf_filtered ("\t%s: ", bootFile);
-       if (catch_errors (symbol_stub, (int)bootFile,
+       if (catch_errors (symbol_stub, bootFile,
                "Error reading symbols from boot file"))
          puts_filtered ("ok\n");
       } else if (from_tty)
@@ -1450,7 +1449,7 @@ vx_open (args, from_tty)
       /* Botches, FIXME:
         (1)  Searches the PATH, not the source path.
         (2)  data and bss are assumed to be at the usual offsets from text.  */
-      catch_errors (add_symbol_stub, (int)pLoadFile, (char *)0);
+      catch_errors (add_symbol_stub, (char *)pLoadFile, (char *)0);
 #endif
     }
   printf_filtered ("Done.\n");
index 66f5bea89820c8d28f5d92d79f353881cce7de72..f6a96280b2b8f7a364b7757c85b2d8ab986c3363 100644 (file)
@@ -2,19 +2,19 @@
 
 This file is part of GDB.
 
-GDB is free software; you can redistribute it and/or modify
+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 1, or (at your option)
-any later version.
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
 
-GDB is distributed in the hope that it will be useful,
+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 GDB; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 /*
 **     symbol definitions
@@ -32,6 +32,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "command.h"
 #include "target.h"
 #include "frame.h"
+#include "regex.h"
+#include "inferior.h"
+
+extern char *getenv();
 
 /*
 **     local data declarations
@@ -43,10 +47,11 @@ struct so_list {
     long   ld_text;
     char inferior_so_name[MAX_PATH_SIZE];      /* Shared Object Library Name */
     struct so_list *next;                      /* Next Structure */
-    int        symbols_loaded;
+    char       symbols_loaded;                 /* Flag: loaded? */
+    char       from_tty;                       /* Flag: print msgs? */
     bfd *so_bfd;
-    struct section_table *so_sections;
-    struct section_table *so_sections_end;
+    struct section_table *sections;
+    struct section_table *sections_end;
 };
 
 static struct so_list *so_list_head = 0;
@@ -82,11 +87,11 @@ struct so_list *so;
   if (!bfd_check_format (so->so_bfd, bfd_object))
     error ("\"%s\": not in executable format: %s.",
           scratch_pathname, bfd_errmsg (bfd_error));
-  if (build_section_table (so->so_bfd, &so->so_sections, &so->so_sections_end))
+  if (build_section_table (so->so_bfd, &so->sections, &so->sections_end))
     error ("Can't find the file sections in `%s': %s", 
           exec_bfd->filename, bfd_errmsg (bfd_error));
 
-  for (p = so->so_sections; p < so->so_sections_end; p++)
+  for (p = so->sections; p < so->sections_end; p++)
     {
       if (strcmp (bfd_section_name (so->so_bfd, p->sec_ptr), ".text") == 0)
        {
@@ -122,7 +127,6 @@ struct so_list *find_solib(so_list_ptr)
 struct so_list *so_list_ptr;                   /* so_list_head position ptr */
 {
 struct so_list *so_list_next = 0;
-CORE_ADDR inferior_dynamic_ptr = 0;
 struct link_map *inferior_lm = 0;
 struct link_dynamic inferior_dynamic_cpy;
 struct link_dynamic_2 inferior_ld_2_cpy;
@@ -131,14 +135,11 @@ int i;
 
      if (!so_list_ptr) {
         if (!(so_list_next = so_list_head)) {
-            for (i = 0; i < misc_function_count; i++) {
-                if (!strcmp (misc_function_vector[i].name, "_DYNAMIC")) {
-                    inferior_dynamic_ptr = misc_function_vector[i].address;
-                    break;
-                }      
-            }          
-            if (inferior_dynamic_ptr) {
-                read_memory(inferior_dynamic_ptr, &inferior_dynamic_cpy, sizeof(struct link_dynamic));
+            i = lookup_misc_func ("_DYNAMIC");
+            if (i >= 0) {
+                read_memory(misc_function_vector[i].address,
+                            &inferior_dynamic_cpy,
+                            sizeof(struct link_dynamic));
                 if (inferior_dynamic_cpy.ld_version == 3) {
                     read_memory((CORE_ADDR)inferior_dynamic_cpy.ld_un.ld_2,
                                 &inferior_ld_2_cpy,
@@ -200,7 +201,7 @@ int i;
         new->next = 0;
         new->symbols_loaded = 0;
         new->so_bfd = NULL;
-        new->so_sections = NULL;
+        new->sections = NULL;
         if (so_list_ptr)
             so_list_ptr->next = new;
         else
@@ -213,67 +214,101 @@ int i;
      return(so_list_next);
 }
 
-/*
-** Called by core_xfer_memory if the transfer form the core file failed.
-** We try to satisfy the request from the text sections of the shared libs.
-*/
-int
-solib_xfer_memory (memaddr, myaddr, len, write)
-     CORE_ADDR memaddr;
-     char *myaddr;
-     int len;
-     int write;
+/* A small stub to get us past the arg-passing pinhole of catch_errors.  */
+
+static int
+symbol_add_stub (arg)
+     char *arg;
 {
-  int res;
-  register struct so_list *so = 0;
+  register struct so_list *so = (struct so_list *)arg; /* catch_errs bogon */
 
-  while (so = find_solib(so))
-    {
-      res = xfer_memory (memaddr, myaddr, len, write,
-                        so->so_bfd, so->so_sections, so->so_sections_end);
-      if (res)
-       return res;
-    }
-  return 0;
+  symbol_file_add (so->inferior_so_name, so->from_tty,
+                  (unsigned int)so->inferior_lm.lm_addr, 0);
+  return 1;
 }
-/*=======================================================================*/
 
-void solib_add(arg_string, from_tty)
-char *arg_string;
-int from_tty;
+/* The real work of adding a shared library file to the symtab and
+   the section list.  */
+
+void
+solib_add (arg_string, from_tty, target)
+     char *arg_string;
+     int from_tty;
+     struct target_ops *target;
 {      
-    register struct so_list *so = 0;           /* link map state variable */
-    char *val;
+  register struct so_list *so = 0;     /* link map state variable */
+  char *val;
+  int count, old;
+  struct section_table *sec;
+
+  if (arg_string == 0)
+      re_comp (".");
+  else if (val = (char *) re_comp (arg_string)) {
+      error ("Invalid regexp: %s", val);
+  }
 
-    if (arg_string == 0)
-       re_comp (".");
-    else if (val = (char *) re_comp (arg_string)) {
-       error ("Invalid regexp: %s", val);
-    }
+  /* Getting new symbols may change our opinion about what is
+     frameless.  */
+  reinit_frame_cache ();
 
-    /* Getting new symbols may change our opinion about what is
-       frameless.  */
-    reinit_frame_cache ();
-    printf_filtered ("All shared libraries");
+  if (from_tty) {
+    printf_filtered ("Shared libraries");
     if (arg_string)
       printf_filtered (" matching regular expresion \"%s\"", arg_string);
     printf_filtered (":\n");
-    
-    dont_repeat();
+  }
+  
+  dont_repeat();
+
+  while (so = find_solib(so)) {
+      if (re_exec(so->inferior_so_name)) {
+         if (so->symbols_loaded) {
+             if (from_tty)
+               printf("Symbols already loaded for %s\n", so->inferior_so_name);
+         } else {
+             so->symbols_loaded = 1;
+             so->from_tty = from_tty;
+                     catch_errors (symbol_add_stub, (char *)so,
+                   "Error while reading shared library symbols; continuing.");
+         }
+      }
+  }
 
-    while (so = find_solib(so)) {
-       if (re_exec(so->inferior_so_name)) {
-           if (so->symbols_loaded) {
-               printf("Symbols already loaded for %s\n", so->inferior_so_name);
-           } else {
-               symbol_file_add (so->inferior_so_name, from_tty,
-                                (unsigned int)so->inferior_lm.lm_addr, 0);
-               so->symbols_loaded = 1;
-           }
-       }
+  /* Now add the shared library sections to the section table of the
+     specified target, if any.  */
+  if (target) {
+    /* Count how many new section_table entries there are.  */
+    so = 0;
+    count = 0;
+    while (0 != (so = find_solib (so))) {
+      count += so->sections_end - so->sections;
     }
+
+    if (count) {
+      /* Reallocate the target's section table including the new size.  */
+      if (target->sections) {
+       old = target->sections_end - target->sections;
+       target->sections = (struct section_table *)
+           realloc ((char *)target->sections,
+             (sizeof (struct section_table)) * (count + old));
+      } else {
+       old = 0;
+       target->sections = (struct section_table *)
+           malloc ((sizeof (struct section_table)) * count);
+      }
+      target->sections_end = target->sections + (count + old);
+
+      /* Add these section table entries to the target's table.  */
+      while (0 != (so = find_solib (so))) {
+       count = so->sections_end - so->sections;
+       bcopy (so->sections, (char *)(target->sections + old), 
+              (sizeof (struct section_table)) * count);
+       old += count;
+      }
+    }
+  }
 }
+
 /*=======================================================================*/
 
 static void solib_info()
@@ -282,7 +317,7 @@ register struct so_list *so = 0;    /* link map state variable */
 
     while (so = find_solib(so)) {
        if (so == so_list_head) {
-           printf("      Address Range      Symbols     Shared Object Library\n");
+           printf("      Address Range     Syms Read    Shared Object Library\n");
        }
        printf(" 0x%08x - 0x%08x   %s   %s\n", 
            so->inferior_lm.lm_addr, 
@@ -321,24 +356,101 @@ clear_solib()
 struct so_list *next;
 
   while (so_list_head) {
-    if (so_list_head->so_sections)
-      free (so_list_head->so_sections);
+    if (so_list_head->sections)
+      free (so_list_head->sections);
     if (so_list_head->so_bfd)
       bfd_close (so_list_head->so_bfd);
     next = so_list_head->next;
     free(so_list_head);
     so_list_head = next;
   }
-    
+}
+
+/* Called by child_create_inferior when the inferior is stopped at its
+   first instruction.  */
+
+void 
+solib_create_inferior_hook()
+{
+  struct link_dynamic inferior_dynamic_cpy;
+  CORE_ADDR inferior_debug_addr;
+  struct ld_debug inferior_debug_cpy;
+  int in_debugger;
+  CORE_ADDR in_debugger_addr;
+  CORE_ADDR breakpoint_addr;
+  int i;
+
+  /* FIXME:  We should look around in the executable code to find _DYNAMIC,
+     if it isn't in the symbol table.  It's not that hard to find... 
+     Then we can debug stripped executables using shared library symbols.  */
+  i = lookup_misc_func ("_DYNAMIC");
+  if (i < 0)                   /* Can't find shared lib ptr. */
+    return;
+
+  /* Get link_dynamic structure */
+  read_memory(misc_function_vector[i].address,
+             &inferior_dynamic_cpy,
+             sizeof(struct link_dynamic));
+  /* Calc address of debugger interface structure */
+  inferior_debug_addr = (CORE_ADDR)inferior_dynamic_cpy.ldd;
+  /* Calc address of `in_debugger' member of debugger interface structure */
+  in_debugger_addr = inferior_debug_addr + (CORE_ADDR)((char *)&inferior_debug_cpy.ldd_in_debugger - (char *)&inferior_debug_cpy);
+  /* Write a value of 1 to this member.  */
+  in_debugger = 1;
+  write_memory(in_debugger_addr, &in_debugger, sizeof(in_debugger));
+
+  /* Now run the target.  Seeing `in_debugger' set, it will set a
+     breakpoint at some convenient place, remember the original contents
+     of that place, and eventually take a SIGTRAP when it runs into the
+     breakpoint.  We handle this by restoring the contents of the
+     breakpointed location (which is only known after it stops), 
+     chasing around to locate the shared libraries that have been
+     loaded, then resuming.  */
+
+  clear_proceed_status ();
+  stop_soon_quietly = 1;
+  target_resume (0, 0);
+  wait_for_inferior ();
+  while (stop_signal != SIGTRAP)
+    {
+      /* FIXME, what if child has exit()ed?  Must exit loop somehow */
+      target_resume (0, stop_signal);
+      wait_for_inferior ();
+    }
+  stop_soon_quietly = 0;
+
+  /* Set `in_debugger' to zero now.  WHY, is this needed?  */
+  in_debugger = 0;
+  write_memory(in_debugger_addr, &in_debugger, sizeof(in_debugger));
+  read_memory(inferior_debug_addr, &inferior_debug_cpy, sizeof(inferior_debug_cpy));
+  /* FIXME: maybe we should add the common symbols from the ldd_cp chain
+   * to the misc_function_vector ?
+   */
+  breakpoint_addr = (CORE_ADDR)inferior_debug_cpy.ldd_bp_addr;
+  if (stop_pc - DECR_PC_AFTER_BREAK == breakpoint_addr)
+    {
+      write_memory(breakpoint_addr, &inferior_debug_cpy.ldd_bp_inst, sizeof(inferior_debug_cpy.ldd_bp_inst));
+      if (DECR_PC_AFTER_BREAK)
+        {
+          stop_pc -= DECR_PC_AFTER_BREAK;
+          write_register (PC_REGNUM, stop_pc);
+        }
+    }
+  solib_add ((char *)0, 0, (struct target_ops *)0);
+}
+
+void
+sharedlibrary_command (args, from_tty)
+{
+  solib_add (args, from_tty, (struct target_ops *)0);
 }
 
 void
 _initialize_solib()
 {
 
-  add_com("sharedlibrary", class_files, solib_add,
+  add_com("sharedlibrary", class_files, sharedlibrary_command,
           "Load shared object library symbols for files matching REGEXP.");
   add_info("sharedlibrary", solib_info, 
           "Status of loaded shared object libraries");
-
 }
index 43657d2bcd8add46a91ef8b93b6246ed1a05389e..3abfe9bfa205aadb14de6f1962e168383f259a50 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1990 Free Software Foundation, Inc.
+/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -18,12 +18,16 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 /* This is for SunOS version 4, not for earlier versions.  */
 
-#define CLEAR_SOLIB clear_solib
+#define CLEAR_SOLIB                    clear_solib
+extern void clear_solib ();
+
 #define SOLIB_ADD(filename, from_tty, targ) solib_add (filename, from_tty, targ)
+extern void solib_add ();
+
+#define SOLIB_CREATE_INFERIOR_HOOK     solib_create_inferior_hook
+extern void solib_create_inferior_hook();
 
 /* If we can't set a breakpoint, and it's in a shared library, just
    disable it.  */
-#define DISABLE_UNSETTABLE_BREAK(addr) solib_address(addr)
+#define DISABLE_UNSETTABLE_BREAK(addr) solib_address(addr)
 extern int solib_address ();                   /* solib.c */
-extern void solib_add ();
-extern void clear_solib ();
index 28a723bfbdd3445b0b36b94e96e4c5439407722c..632616e6821678b8a1a6589f74cd45bc8e5efbc7 100644 (file)
@@ -918,6 +918,7 @@ fputs_demangled (linebuffer, stream, arg_mode)
   /* If user wants to see raw output, no problem.  */
   if (!demangle) {
     fputs_filtered (linebuffer, stream);
+    return;
   }
 
   p = linebuffer;
@@ -1211,8 +1212,9 @@ struct queue *item;
 }
 #endif /* QUEUE_MISSING */
 \f
+#ifndef HAVE_STRSTR
 /* Simple implementation of strstr, since some implementations lack it. */
-char *
+const char *
 strstr (in, find)
      const char *in, *find;
 {
@@ -1220,10 +1222,11 @@ strstr (in, find)
 
   while (0 != (p = strchr (p+1, *find))) {
     if (strcmp (p, find))
-      return (char *)p;
+      return p;
   }
   return 0;
 }
+#endif /* do not HAVE_STRSTR */
 \f
 void
 _initialize_utils ()