From bdbd5f508635fa9581f85bd6ba7ec3620970674d Mon Sep 17 00:00:00 2001 From: John Gilmore Date: Wed, 4 Sep 1991 07:43:50 +0000 Subject: [PATCH] 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 . * 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 .) * utils.c (fputs_demangled): Avoid duplicate printing if demangling is off. (Fix from J.T. Conklin .) * 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 | 59 +++++++++-- gdb/breakpoint.c | 87 ++++++++++++---- gdb/core.c | 19 ++-- gdb/exec.c | 85 +++++++-------- gdb/inferior.h | 26 +++-- gdb/infrun.c | 37 ++++--- gdb/main.c | 116 +++++---------------- gdb/remote-vx.c | 11 +- gdb/solib.c | 262 +++++++++++++++++++++++++++++++++-------------- gdb/tm-sunos.h | 14 ++- gdb/utils.c | 7 +- 11 files changed, 453 insertions(+), 270 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index bf5a894c2cd..b72cdf021e9 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -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 . + + * 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 .) + + * utils.c (fputs_demangled): Avoid duplicate printing if + demangling is off. (Fix from J.T. Conklin .) + + * 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 diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index e3f515221c6..f290ad582c3 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -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 #include @@ -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); } +#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"); } @@ -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; diff --git a/gdb/core.c b/gdb/core.c index 89a417daaae..deaae4b9e0b 100644 --- a/gdb/core.c +++ b/gdb/core.c @@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include +#include #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"); } diff --git a/gdb/exec.c b/gdb/exec.c index 32795c640fb..9fb378ce98b 100644 --- a/gdb/exec.c +++ b/gdb/exec.c @@ -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 #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 @@ -30,6 +31,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include +#include #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) } -/* 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) /* 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); } diff --git a/gdb/inferior.h b/gdb/inferior.h index d99c4a62848..151c2c2b25c 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -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. */ diff --git a/gdb/infrun.c b/gdb/infrun.c index e48f76136ff..b6f6a8f43de 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -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 */ } diff --git a/gdb/main.c b/gdb/main.c index b8419a23173..dd5ac2101c5 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -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) { diff --git a/gdb/remote-vx.c b/gdb/remote-vx.c index 171e712ed6d..59cd053797d 100644 --- a/gdb/remote-vx.c +++ b/gdb/remote-vx.c @@ -1340,16 +1340,15 @@ vx_wait (status) 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"); diff --git a/gdb/solib.c b/gdb/solib.c index 66f5bea8982..f6a96280b2b 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -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"); - } diff --git a/gdb/tm-sunos.h b/gdb/tm-sunos.h index 43657d2bcd8..3abfe9bfa20 100644 --- a/gdb/tm-sunos.h +++ b/gdb/tm-sunos.h @@ -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 (); diff --git a/gdb/utils.c b/gdb/utils.c index 28a723bfbdd..632616e6821 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -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 */ +#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 */ void _initialize_utils () -- 2.30.2