summaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>1999-05-02 11:25:35 +0000
committerdfr <dfr@FreeBSD.org>1999-05-02 11:25:35 +0000
commit878c26ec6fd51ce62b32ca0d459ced0dcdf212ed (patch)
tree37ffbff343ba62400334aa3f7a1a477cba0f1644 /contrib
parente8b7e98f0e492397a32c608e582295445df98eee (diff)
downloadFreeBSD-src-878c26ec6fd51ce62b32ca0d459ced0dcdf212ed.zip
FreeBSD-src-878c26ec6fd51ce62b32ca0d459ced0dcdf212ed.tar.gz
Merge local changes into gdb-4.18 and add changes for FreeBSD/alpha.
Diffstat (limited to 'contrib')
-rw-r--r--contrib/gdb/gdb/coffread.c2
-rw-r--r--contrib/gdb/gdb/config/alpha/tm-alpha.h2
-rw-r--r--contrib/gdb/gdb/core-aout.c56
-rw-r--r--contrib/gdb/gdb/core-regset.c10
-rw-r--r--contrib/gdb/gdb/dbxread.c2
-rw-r--r--contrib/gdb/gdb/defs.h2
-rw-r--r--contrib/gdb/gdb/demangle.c2
-rw-r--r--contrib/gdb/gdb/doc/gdb.texinfo2650
-rw-r--r--contrib/gdb/gdb/doc/stabs.texinfo121
-rw-r--r--contrib/gdb/gdb/exec.c293
-rw-r--r--contrib/gdb/gdb/gdbserver/gdbreplay.c1
-rw-r--r--contrib/gdb/gdb/gdbserver/utils.c3
-rw-r--r--contrib/gdb/gdb/i386-tdep.c5
-rw-r--r--contrib/gdb/gdb/i386b-nat.c2
-rw-r--r--contrib/gdb/gdb/infptrace.c240
-rw-r--r--contrib/gdb/gdb/main.c1
-rw-r--r--contrib/gdb/gdb/objfiles.c249
-rw-r--r--contrib/gdb/gdb/partial-stab.h2
-rw-r--r--contrib/gdb/gdb/remote.c2274
-rw-r--r--contrib/gdb/gdb/ser-unix.c85
-rw-r--r--contrib/gdb/gdb/solib.c297
-rw-r--r--contrib/gdb/gdb/symfile.c1503
-rw-r--r--contrib/gdb/gdb/symtab.c2
-rw-r--r--contrib/gdb/gdb/target.c981
-rw-r--r--contrib/gdb/gdb/target.h541
-rw-r--r--contrib/gdb/gdb/thread.c4
26 files changed, 7519 insertions, 1811 deletions
diff --git a/contrib/gdb/gdb/coffread.c b/contrib/gdb/gdb/coffread.c
index 340e77f..60a524f 100644
--- a/contrib/gdb/gdb/coffread.c
+++ b/contrib/gdb/gdb/coffread.c
@@ -1047,7 +1047,7 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
struct minimal_symbol *msym;
msym = prim_record_minimal_symbol_and_info
- (cs->c_name, tmpaddr, ms_type, (char *)cs->c_sclass, sec,
+ (cs->c_name, tmpaddr, ms_type, (char *)(long)cs->c_sclass, sec,
NULL, objfile);
#ifdef COFF_MAKE_MSYMBOL_SPECIAL
if(msym)
diff --git a/contrib/gdb/gdb/config/alpha/tm-alpha.h b/contrib/gdb/gdb/config/alpha/tm-alpha.h
index d9b9812..cfe97cf 100644
--- a/contrib/gdb/gdb/config/alpha/tm-alpha.h
+++ b/contrib/gdb/gdb/config/alpha/tm-alpha.h
@@ -425,9 +425,11 @@ init_extra_frame_info PARAMS ((struct frame_info *));
extern struct frame_info *setup_arbitrary_frame PARAMS ((int, CORE_ADDR *));
/* This is used by heuristic_proc_start. It should be shot it the head. */
+#ifndef __FreeBSD__
#ifndef VM_MIN_ADDRESS
#define VM_MIN_ADDRESS (CORE_ADDR)0x120000000
#endif
+#endif
/* If PC is in a shared library trampoline code, return the PC
where the function itself actually starts. If not, return 0. */
diff --git a/contrib/gdb/gdb/core-aout.c b/contrib/gdb/gdb/core-aout.c
index ce3a95a..08cca22 100644
--- a/contrib/gdb/gdb/core-aout.c
+++ b/contrib/gdb/gdb/core-aout.c
@@ -1,5 +1,5 @@
/* Extract registers from a "standard" core file, for GDB.
- Copyright (C) 1988-1995 Free Software Foundation, Inc.
+ Copyright (C) 1988-1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -23,6 +23,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
more machine specific. */
#include "defs.h"
+
+#ifdef HAVE_PTRACE_H
+# include <ptrace.h>
+#else
+# ifdef HAVE_SYS_PTRACE_H
+# include <sys/ptrace.h>
+# endif
+#endif
+
#include <sys/types.h>
#include <sys/param.h>
#include "gdbcore.h"
@@ -34,13 +43,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <sys/file.h>
#include "gdb_stat.h"
#include <sys/user.h>
-#ifndef NO_PTRACE_H
-# ifdef PTRACE_IN_WRONG_PLACE
-# include <ptrace.h>
-# else /* !PTRACE_IN_WRONG_PLACE */
-# include <sys/ptrace.h>
-# endif /* !PTRACE_IN_WRONG_PLACE */
-#endif /* NO_PTRACE_H */
#endif
#ifndef CORE_REGISTER_ADDR
@@ -51,6 +53,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <sys/core.h>
#endif
+static void fetch_core_registers PARAMS ((char *, unsigned, int, CORE_ADDR));
+
+void _initialize_core_aout PARAMS ((void));
+
/* Extract the register values out of the core file and store
them where `read_register' will find them.
@@ -66,15 +72,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
static void
fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
- char *core_reg_sect;
- unsigned core_reg_size;
- int which;
- CORE_ADDR reg_addr;
+ char *core_reg_sect;
+ unsigned core_reg_size;
+ int which;
+ CORE_ADDR reg_addr;
{
- register int regno;
- register CORE_ADDR addr;
+ int regno;
+ CORE_ADDR addr;
int bad_reg = -1;
- register CORE_ADDR reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */
+ CORE_ADDR reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */
int numregs = ARCH_NUM_REGS;
/* If u.u_ar0 was an absolute address in the core file, relativize it now,
@@ -89,17 +95,15 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
for (regno = 0; regno < numregs; regno++)
{
addr = CORE_REGISTER_ADDR (regno, reg_ptr);
- if (addr >= core_reg_size) {
- if (bad_reg < 0)
- bad_reg = regno;
- } else {
- supply_register (regno, core_reg_sect + addr);
- }
+ if (addr >= core_reg_size
+ && bad_reg < 0)
+ bad_reg = regno;
+ else
+ supply_register (regno, core_reg_sect + addr);
}
+
if (bad_reg >= 0)
- {
- error ("Register %s not found in core file.", reg_names[bad_reg]);
- }
+ error ("Register %s not found in core file.", REGISTER_NAME (bad_reg));
}
@@ -108,10 +112,10 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
/* Return the address in the core dump or inferior of register REGNO.
BLOCKEND is the address of the end of the user structure. */
-unsigned int
+CORE_ADDR
register_addr (regno, blockend)
int regno;
- int blockend;
+ CORE_ADDR blockend;
{
CORE_ADDR addr;
diff --git a/contrib/gdb/gdb/core-regset.c b/contrib/gdb/gdb/core-regset.c
index 68b0845..d925abe 100644
--- a/contrib/gdb/gdb/core-regset.c
+++ b/contrib/gdb/gdb/core-regset.c
@@ -1,5 +1,5 @@
/* Machine independent GDB support for core files on systems using "regsets".
- Copyright 1993-1996 Free Software Foundation, Inc.
+ Copyright 1993-1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -47,6 +47,10 @@ regardless of whether or not the actual target has floating point hardware.
#include "command.h"
#include "gdbcore.h"
+static void fetch_core_registers PARAMS ((char *, unsigned, int, CORE_ADDR));
+
+void _initialize_core_regset PARAMS ((void));
+
/*
GLOBAL FUNCTION
@@ -57,7 +61,7 @@ SYNOPSIS
void fetch_core_registers (char *core_reg_sect,
unsigned core_reg_size,
- int which, unsigned in reg_addr)
+ int which, CORE_ADDR reg_addr)
DESCRIPTION
@@ -77,7 +81,7 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
char *core_reg_sect;
unsigned core_reg_size;
int which;
- unsigned int reg_addr; /* Unused in this version */
+ CORE_ADDR reg_addr; /* Unused in this version */
{
#if defined (HAVE_GREGSET_T) && defined (HAVE_FPREGSET_T)
gregset_t gregset;
diff --git a/contrib/gdb/gdb/dbxread.c b/contrib/gdb/gdb/dbxread.c
index 0749412..2f99398 100644
--- a/contrib/gdb/gdb/dbxread.c
+++ b/contrib/gdb/gdb/dbxread.c
@@ -2406,7 +2406,9 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
file's symbols at once. */
case N_ENDM: /* Solaris 2: End of module */
case N_MAIN: /* Name of main routine. */
+#if 0 /* XXX remove when binutils 2.9.2 is imported */
case N_ALIAS: /* SunPro F77: alias name, ignore for now. */
+#endif
break;
}
diff --git a/contrib/gdb/gdb/defs.h b/contrib/gdb/gdb/defs.h
index c0552a1..41e1011 100644
--- a/contrib/gdb/gdb/defs.h
+++ b/contrib/gdb/gdb/defs.h
@@ -25,6 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <stdio.h>
#include <errno.h> /* System call error return status */
#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
#ifdef HAVE_STDDEF_H
# include <stddef.h>
diff --git a/contrib/gdb/gdb/demangle.c b/contrib/gdb/gdb/demangle.c
index 669d9ab..6b1555f 100644
--- a/contrib/gdb/gdb/demangle.c
+++ b/contrib/gdb/gdb/demangle.c
@@ -81,6 +81,7 @@ demanglers[] =
"ARM style demangling"
}
,
+#if 0 /* XXX remove when binutils 2.9.2 is imported */
{
HP_DEMANGLING_STYLE_STRING,
hp_demangling,
@@ -93,6 +94,7 @@ demanglers[] =
"EDG style demangling"
}
,
+#endif
{
NULL, unknown_demangling, NULL
}
diff --git a/contrib/gdb/gdb/doc/gdb.texinfo b/contrib/gdb/gdb/doc/gdb.texinfo
index 1bde79c..127da78 100644
--- a/contrib/gdb/gdb/doc/gdb.texinfo
+++ b/contrib/gdb/gdb/doc/gdb.texinfo
@@ -1,5 +1,5 @@
\input texinfo @c -*-texinfo-*-
-@c Copyright 1988 1989 1990 1991 1992 1993 1994 1995
+@c Copyright 1988-1999
@c Free Software Foundation, Inc.
@c
@c %**start of header
@@ -15,7 +15,6 @@
@ifclear GENERIC
@settitle Debugging with @value{GDBN} (@value{TARGET})
@end ifclear
-@clear RENAMED
@setchapternewpage odd
@c %**end of header
@@ -31,14 +30,10 @@
@syncodeindex vr cp
@c !!set GDB manual's edition---not the same as GDB version!
-@set EDITION 4.12
+@set EDITION Seventh
@c !!set GDB manual's revision date
-@set DATE January 1994
-
-@c GDB CHANGELOG CONSULTED BETWEEN:
-@c Fri Oct 11 23:27:06 1991 John Gilmore (gnu at cygnus.com)
-@c Sat Dec 22 02:51:40 1990 John Gilmore (gnu at cygint)
+@set DATE February 1999
@c THIS MANUAL REQUIRES TEXINFO-2 macros and info-makers to format properly.
@@ -57,12 +52,11 @@ END-INFO-DIR-ENTRY
This file documents the @sc{gnu} debugger @value{GDBN}.
-This is Edition @value{EDITION}, @value{DATE},
+This is the @value{EDITION} Edition, @value{DATE},
of @cite{Debugging with @value{GDBN}: the @sc{gnu} Source-Level Debugger}
for @value{GDBN} Version @value{GDBVN}.
-Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995
-Free Software Foundation, Inc.
+Copyright (C) 1988-1999 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@@ -91,28 +85,45 @@ into another language, under the above conditions for modified versions.
@subtitle (@value{TARGET})
@end ifclear
@sp 1
-@subtitle Edition @value{EDITION}, for @value{GDBN} version @value{GDBVN}
+@ifclear HPPA
+@subtitle @value{EDITION} Edition, for @value{GDBN} version @value{GDBVN}
+@subtitle @value{DATE}
+@author Richard M. Stallman and Roland H. Pesch
+@end ifclear
+@ifset HPPA
+@subtitle Edition @value{EDITION}, for @value{HPVER} (based on @value{GDBN} @value{GDBVN})
@subtitle @value{DATE}
-@author Richard M. Stallman and Cygnus Support
+@author Richard M. Stallman and Roland H. Pesch (modified by HP)
+@end ifset
@page
+@ifclear HPPA
@tex
{\parskip=0pt
\hfill (Send bugs and comments on @value{GDBN} to bug-gdb\@prep.ai.mit.edu.)\par
\hfill {\it Debugging with @value{GDBN}}\par
\hfill \TeX{}info \texinfoversion\par
-\hfill doc\@cygnus.com\par
}
@end tex
+@end ifclear
+@ifset HPPA
+@tex
+{\parskip=0pt
+\hfill {\it Debugging with @value{GDBN}}\par
+\hfill \TeX{}info \texinfoversion\par
+}
+@end tex
+@end ifset
@vskip 0pt plus 1filll
-Copyright @copyright{} 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995
-Free Software Foundation, Inc.
+Copyright @copyright{} 1988-1999 Free Software Foundation, Inc.
@sp 2
+@ifclear HPPA
Published by the Free Software Foundation @*
59 Temple Place - Suite 330, @*
Boston, MA 02111-1307 USA @*
Printed copies are available for $20 each. @*
ISBN 1-882114-11-6 @*
+@end ifclear
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@@ -129,14 +140,15 @@ into another language, under the above conditions for modified versions.
@page
@ifinfo
-@node Top
+@node Top, Summary, (dir), (dir)
@top Debugging with @value{GDBN}
This file describes @value{GDBN}, the @sc{gnu} symbolic debugger.
-This is Edition @value{EDITION}, @value{DATE}, for @value{GDBN} Version
+This is the @value{EDITION} Edition, @value{DATE}, for @value{GDBN} Version
@value{GDBVN}.
+Copyright (C) 1988-1999 Free Software Foundation, Inc.
@menu
* Summary:: Summary of @value{GDBN}
@ifclear BARETARGET
@@ -153,10 +165,10 @@ This is Edition @value{EDITION}, @value{DATE}, for @value{GDBN} Version
@ifclear CONLY
* Languages:: Using @value{GDBN} with different languages
@end ifclear
+
@ifset CONLY
* C:: C language support
@end ifset
-@c remnant makeinfo bug, blank line needed after two end-ifs?
* Symbols:: Examining the symbol table
* Altering:: Altering execution
@@ -169,21 +181,269 @@ This is Edition @value{EDITION}, @value{DATE}, for @value{GDBN} Version
@end ifclear
* GDB Bugs:: Reporting bugs in @value{GDBN}
-* Command Line Editing:: Facilities of the readline library
-* Using History Interactively::
-@c @ifset NOVEL
-@c * Renamed Commands::
-@c @end ifset
+
@ifclear PRECONFIGURED
+@ifclear HPPA
* Formatting Documentation:: How to format and print @value{GDBN} documentation
-* Installing GDB:: Installing GDB
@end ifclear
+@end ifclear
+
+* Command Line Editing:: Command Line Editing
+* Using History Interactively:: Using History Interactively
+* Installing GDB:: Installing GDB
* Index:: Index
+
+ --- The Detailed Node Listing ---
+
+Summary of @value{GDBN}
+
+* Free Software:: Freely redistributable software
+* Contributors:: Contributors to GDB
+
+Getting In and Out of @value{GDBN}
+
+* Invoking GDB:: How to start @value{GDBN}
+* Quitting GDB:: How to quit @value{GDBN}
+* Shell Commands:: How to use shell commands inside @value{GDBN}
+
+Invoking @value{GDBN}
+
+* File Options:: Choosing files
+* Mode Options:: Choosing modes
+
+@value{GDBN} Commands
+
+* Command Syntax:: How to give commands to @value{GDBN}
+* Completion:: Command completion
+* Help:: How to ask @value{GDBN} for help
+
+Running Programs Under @value{GDBN}
+
+* Compilation:: Compiling for debugging
+* Starting:: Starting your program
+@ifclear BARETARGET
+* Arguments:: Your program's arguments
+* Environment:: Your program's environment
+@end ifclear
+
+* Working Directory:: Your program's working directory
+* Input/Output:: Your program's input and output
+* Attach:: Debugging an already-running process
+* Kill Process:: Killing the child process
+@ifclear HPPA
+* Process Information:: Additional process information
+@end ifclear
+
+* Threads:: Debugging programs with multiple threads
+* Processes:: Debugging programs with multiple processes
+
+Stopping and Continuing
+
+* Breakpoints:: Breakpoints, watchpoints, and catchpoints
+* Continuing and Stepping:: Resuming execution
+@ifset POSIX
+* Signals:: Signals
+@end ifset
+@ifclear BARETARGET
+* Thread Stops:: Stopping and starting multi-thread programs
+@end ifclear
+
+Breakpoints and watchpoints
+
+* Set Breaks:: Setting breakpoints
+* Set Watchpoints:: Setting watchpoints
+* Set Catchpoints:: Setting catchpoints
+* Delete Breaks:: Deleting breakpoints
+* Disabling:: Disabling breakpoints
+* Conditions:: Break conditions
+* Break Commands:: Breakpoint command lists
+@ifclear CONLY
+* Breakpoint Menus:: Breakpoint menus
+@end ifclear
+
+Examining the Stack
+
+* Frames:: Stack frames
+* Backtrace:: Backtraces
+* Selection:: Selecting a frame
+* Frame Info:: Information on a frame
+* Alpha/MIPS Stack:: Alpha and MIPS machines and the function stack
+
+Examining Source Files
+
+* List:: Printing source lines
+@ifclear DOSHOST
+* Search:: Searching source files
+@end ifclear
+* Source Path:: Specifying source directories
+* Machine Code:: Source and machine code
+
+Examining Data
+
+* Expressions:: Expressions
+* Variables:: Program variables
+* Arrays:: Artificial arrays
+* Output Formats:: Output formats
+* Memory:: Examining memory
+* Auto Display:: Automatic display
+* Print Settings:: Print settings
+* Value History:: Value history
+* Convenience Vars:: Convenience variables
+* Registers:: Registers
+@ifclear HAVE-FLOAT
+* Floating Point Hardware:: Floating point hardware
+@end ifclear
+
+Using @value{GDBN} with Different Languages
+
+* Setting:: Switching between source languages
+* Show:: Displaying the language
+@ifset MOD2
+* Checks:: Type and range checks
+@end ifset
+
+* Support:: Supported languages
+
+Switching between source languages
+
+* Filenames:: Filename extensions and languages.
+* Manually:: Setting the working language manually
+* Automatically:: Having @value{GDBN} infer the source language
+
+@ifset MOD2
+Type and range checking
+
+* Type Checking:: An overview of type checking
+* Range Checking:: An overview of range checking
+@end ifset
+
+Supported languages
+
+@ifset MOD2
+* C:: C and C++
+
+C Language Support
+
+* C Operators:: C operators
+
+C Language Support
+@end ifset
+
+* C Operators:: C and C++ operators
+* C Constants:: C and C++ constants
+* Cplus expressions:: C++ expressions
+* C Defaults:: Default settings for C and C++
+@ifset MOD2
+* C Checks:: C and C++ type and range checks
+@end ifset
+* Debugging C:: @value{GDBN} and C
+* Debugging C plus plus:: @value{GDBN} features for C++
+
+@ifset MOD2
+Modula-2
+
+* M2 Operators:: Built-in operators
+* Built-In Func/Proc:: Built-in functions and procedures
+* M2 Constants:: Modula-2 constants
+* M2 Defaults:: Default settings for Modula-2
+* Deviations:: Deviations from standard Modula-2
+* M2 Checks:: Modula-2 type and range checks
+* M2 Scope:: The scope operators @code{::} and @code{.}
+* GDB/M2:: @value{GDBN} and Modula-2
+@end ifset
+
+Altering Execution
+
+* Assignment:: Assignment to variables
+* Jumping:: Continuing at a different address
+@ifclear BARETARGET
+* Signaling:: Giving your program a signal
+@end ifclear
+* Returning:: Returning from a function
+* Calling:: Calling your program's functions
+* Patching:: Patching your program
+
+@value{GDBN} Files
+
+* Files:: Commands to specify files
+* Symbol Errors:: Errors reading symbol files
+
+Specifying a Debugging Target
+
+* Active Targets:: Active targets
+* Target Commands:: Commands for managing targets
+@ifclear HPPA
+* Byte Order:: Choosing target byte order
+* Remote:: Remote debugging
+
+Remote debugging
+@end ifclear
+
+@ifset REMOTESTUB
+* Remote Serial:: @value{GDBN} remote serial protocol
+@end ifset
+
+@ifset I960
+* i960-Nindy Remote:: @value{GDBN} with a remote i960 (Nindy)
+@end ifset
+
+@ifset AMD29K
+* UDI29K Remote:: The UDI protocol for AMD29K
+* EB29K Remote:: The EBMON protocol for AMD29K
+@end ifset
+
+@ifset VXWORKS
+* VxWorks Remote:: @value{GDBN} and VxWorks
+@end ifset
+
+@ifset ST2000
+* ST2000 Remote:: @value{GDBN} with a Tandem ST2000
+@end ifset
+
+@ifset H8
+* Hitachi Remote:: @value{GDBN} and Hitachi Microprocessors
+@end ifset
+
+@ifset MIPS
+* MIPS Remote:: @value{GDBN} and MIPS boards
+@end ifset
+
+@ifset SIMS
+* Simulator:: Simulated CPU target
+@end ifset
+
+Controlling @value{GDBN}
+
+* Prompt:: Prompt
+* Editing:: Command editing
+* History:: Command history
+* Screen Size:: Screen size
+* Numbers:: Numbers
+* Messages/Warnings:: Optional warnings and messages
+
+Canned Sequences of Commands
+
+* Define:: User-defined commands
+* Hooks:: User-defined command hooks
+* Command Files:: Command files
+* Output:: Commands for controlled output
+
+Reporting Bugs in @value{GDBN}
+
+* Bug Criteria:: Have you found a bug?
+* Bug Reporting:: How to report bugs
+
+Installing @value{GDBN}
+
+* Separate Objdir:: Compiling @value{GDBN} in another directory
+* Config Names:: Specifying names for hosts and targets
+* Configure Options:: Summary of options for configure
@end menu
+
@end ifinfo
-@node Summary
+@node Summary, Sample Session, Top, Top
@unnumbered Summary of @value{GDBN}
The purpose of a debugger such as @value{GDBN} is to allow you to see what is
@@ -224,8 +484,8 @@ see @ref{Modula-2,,Modula-2}. There is no further documentation on Chill yet.
Debugging Pascal programs which use sets, subranges, file variables, or nested
functions does not currently work. @value{GDBN} does not support
entering expressions, printing values, or similar features using Pascal syntax.
-
@end ifset
+
@ifset FORTRAN
@cindex Fortran
@value{GDBN} can be used to debug programs written in Fortran, although
@@ -235,12 +495,21 @@ some variables with a trailing underscore.
@end ifset
@end ifclear
+@ifset HPPA
+This version of the manual documents HP Wildebeest (WDB) Version 0.75,
+implemented on HP 9000 systems running Release 10.20, 10.30, or 11.0 of
+the HP-UX operating system. HP WDB 0.75 can be used to debug code
+generated by the HP ANSI C and HP ANSI C++ compilers as well as the
+@sc{gnu} C and C++ compilers. It does not support the debugging of
+Fortran, Modula-2, or Chill programs.
+@end ifset
+
@menu
* Free Software:: Freely redistributable software
* Contributors:: Contributors to GDB
@end menu
-@node Free Software
+@node Free Software, Contributors, Summary, Summary
@unnumberedsec Free software
@value{GDBN} is @dfn{free software}, protected by the @sc{gnu}
@@ -256,16 +525,16 @@ Fundamentally, the General Public License is a license which says that
you have these freedoms and that you cannot take these freedoms away
from anyone else.
-@node Contributors
+@node Contributors, , Free Software, Summary
@unnumberedsec Contributors to GDB
-Richard Stallman was the original author of GDB, and of many other @sc{gnu}
-programs. Many others have contributed to its development. This
-section attempts to credit major contributors. One of the virtues of
-free software is that everyone is free to contribute to it; with
+Richard Stallman was the original author of GDB, and of many other
+@sc{gnu} programs. Many others have contributed to its development.
+This section attempts to credit major contributors. One of the virtues
+of free software is that everyone is free to contribute to it; with
regret, we cannot actually acknowledge everyone here. The file
-@file{ChangeLog} in the @value{GDBN} distribution approximates a blow-by-blow
-account.
+@file{ChangeLog} in the @value{GDBN} distribution approximates a
+blow-by-blow account.
Changes much prior to version 2.0 are lost in the mists of time.
@@ -275,17 +544,17 @@ or your friends (or enemies, to be evenhanded) have been unfairly
omitted from this list, we would like to add your names!
@end quotation
-So that they may not regard their long labor as thankless, we
-particularly thank those who shepherded GDB through major releases:
-Stan Shebs (release 4.14),
-Fred Fish (releases 4.13, 4.12, 4.11, 4.10, and 4.9),
-Stu Grossman and John Gilmore (releases 4.8, 4.7, 4.6, 4.5, and 4.4),
+So that they may not regard their many labors as thankless, we
+particularly thank those who shepherded @value{GDBN} through major
+releases:
+Jim Blandy (release 4.18);
+Jason Molenda (release 4.17);
+Stan Shebs (release 4.14);
+Fred Fish (releases 4.16, 4.15, 4.13, 4.12, 4.11, 4.10, and 4.9);
+Stu Grossman and John Gilmore (releases 4.8, 4.7, 4.6, 4.5, and 4.4);
John Gilmore (releases 4.3, 4.2, 4.1, 4.0, and 3.9);
Jim Kingdon (releases 3.5, 3.4, and 3.3);
and Randy Smith (releases 3.2, 3.1, and 3.0).
-As major maintainer of @value{GDBN} for some period, each
-contributed significantly to the structure, stability, and capabilities
-of the entire debugger.
Richard Stallman, assisted at various times by Peter TerMaat, Chris
Hanson, and Richard Mlynarik, handled releases through 2.8.
@@ -304,6 +573,8 @@ Henkel-Wallace, Rich Pixley, Steve Chamberlain, and John Gilmore.
David Johnson wrote the original COFF support; Pace Willison did
the original support for encapsulated COFF.
+Brent Benson of Harris Computer Systems contributed DWARF 2 support.
+
Adam de Boor and Bradley Davis contributed the ISI Optimum V support.
Per Bothner, Noboyuki Hikichi, and Alessandro Forin contributed MIPS
support.
@@ -323,15 +594,18 @@ Tim Tucker contributed support for the Gould NP1 and Gould Powernode.
Pace Willison contributed Intel 386 support.
Jay Vosburgh contributed Symmetry support.
+Andreas Schwab contributed M68K Linux support.
+
Rich Schaefer and Peter Schauer helped with support of SunOS shared
libraries.
-Jay Fenlason and Roland McGrath ensured that @value{GDBN} and GAS agree about
-several machine instruction sets.
+Jay Fenlason and Roland McGrath ensured that @value{GDBN} and GAS agree
+about several machine instruction sets.
-Patrick Duval, Ted Goldstein, Vikram Koka and Glenn Engel helped
-develop remote debugging. Intel Corporation and Wind River Systems
-contributed remote debugging modules for their products.
+Patrick Duval, Ted Goldstein, Vikram Koka and Glenn Engel helped develop
+remote debugging. Intel Corporation, Wind River Systems, AMD, and ARM
+contributed remote debugging modules for the i960, VxWorks, A29K UDI,
+and RDI targets, respectively.
Brian Fox is the author of the readline libraries providing
command-line editing and command history.
@@ -348,18 +622,56 @@ He also enhanced the command-completion support to cover C++ overloaded
symbols.
@end ifclear
-Hitachi America, Ltd. sponsored the support for Hitachi microprocessors.
+Hitachi America, Ltd. sponsored the support for H8/300, H8/500, and
+Super-H processors.
+
+NEC sponsored the support for the v850, Vr4xxx, and Vr5xxx processors.
+
+Mitsubishi sponsored the support for D10V, D30V, and M32R/D processors.
+
+Toshiba sponsored the support for the TX39 Mips processor.
+
+Matsushita sponsored the support for the MN10200 and MN10300 processors.
+
+Fujitsu sponsored the support for SPARClite and FR30 processors
Kung Hsu, Jeff Law, and Rick Sladkey added support for hardware
watchpoints.
+Michael Snyder added support for tracepoints.
+
Stu Grossman wrote gdbserver.
Jim Kingdon, Peter Schauer, Ian Taylor, and Stu Grossman made
nearly innumerable bug fixes and cleanups throughout GDB.
+The following people at the Hewlett-Packard Company contributed
+support for the PA-RISC 2.0 architecture, HP-UX 10.20, 10.30, and 11.0
+(narrow mode), HP's implementation of kernel threads, HP's aC++
+compiler, and the terminal user interface: Ben Krepp, Richard Title,
+John Bishop, Susan Macchia, Kathy Mann, Satish Pai, India Paul, Steve
+Rehrauer, and Elena Zannoni. Kim Haase provided HP-specific
+information in this manual.
+
+Cygnus Solutions has sponsored GDB maintenance and much of its
+development since 1991. Cygnus engineers who have worked on GDB
+fulltime include Mark Alexander, Jim Blandy, Per Bothner, Edith Epstein,
+Chris Faylor, Fred Fish, Martin Hunt, Jim Ingham, John Gilmore, Stu
+Grossman, Kung Hsu, Jim Kingdon, John Metzler, Fernando Nasser, Geoffrey
+Noer, Dawn Perchik, Rich Pixley, Zdenek Radouch, Keith Seitz, Stan
+Shebs, David Taylor, and Elena Zannoni. In addition, Dave Brolley, Ian
+Carmichael, Steve Chamberlain, Nick Clifton, JT Conklin, Stan Cox, DJ
+Delorie, Ulrich Drepper, Frank Eigler, Doug Evans, Sean Fagan, David
+Henkel-Wallace, Richard Henderson, Jeff Holcomb, Jeff Law, Jim Lemke,
+Tom Lord, Bob Manson, Michael Meissner, Jason Merrill, Catherine Moore,
+Drew Moseley, Ken Raeburn, Gavin Romig-Koch, Rob Savoye, Jamie Smith,
+Mike Stump, Ian Taylor, Angela Thomas, Michael Tiemann, Tom Tromey, Ron
+Unrau, Jim Wilson, and David Zuhn have made contributions both large
+and small.
+
+
@ifclear BARETARGET
-@node Sample Session
+@node Sample Session, Invocation, Summary, Top
@chapter A Sample @value{GDBN} Session
You can use this manual at your leisure to read all about @value{GDBN}.
@@ -406,6 +718,7 @@ m4: End of input: 0: fatal error: EOF in string
@noindent
Let us use @value{GDBN} to try to see what is going on.
+@ifclear HPPA
@smallexample
$ @b{@value{GDBP} m4}
@c FIXME: this falsifies the exact text played out, to permit smallbook
@@ -416,9 +729,24 @@ $ @b{@value{GDBP} m4}
There is absolutely no warranty for @value{GDBN}; type "show warranty"
for details.
-@value{GDBN} @value{GDBVN}, Copyright 1995 Free Software Foundation, Inc...
+@value{GDBN} @value{GDBVN}, Copyright 1999 Free Software Foundation, Inc...
+(@value{GDBP})
+@end smallexample
+@end ifclear
+@ifset HPPA
+@smallexample
+$ @b{@value{GDBP} m4}
+Wildebeest is free software and you are welcome to distribute copies of
+it under certain conditions; type "show copying" to see the conditions.
+There is absolutely no warranty for Wildebeest; type "show warranty"
+for details.
+
+Hewlett-Packard Wildebeest 0.75 (based on GDB 4.16)
+(built for PA-RISC 1.1 or 2.0, HP-UX 10.20)
+Copyright 1996, 1997 Free Software Foundation, Inc.
(@value{GDBP})
@end smallexample
+@end ifset
@noindent
@value{GDBN} reads only enough symbol data to know where to find the
@@ -630,7 +958,7 @@ session with the @value{GDBN} @code{quit} command.
@end smallexample
@end ifclear
-@node Invocation
+@node Invocation, Commands, Sample Session, Top
@chapter Getting In and Out of @value{GDBN}
This chapter discusses how to start @value{GDBN}, and how to get out of it.
@@ -644,11 +972,11 @@ type @kbd{quit} or @kbd{C-d} to exit.
@menu
* Invoking GDB:: How to start @value{GDBN}
-* Quitting GDB:: How to quit @value{GDBN}
+* Quitting GDB:: How to quit @value{GDBN}
* Shell Commands:: How to use shell commands inside @value{GDBN}
@end menu
-@node Invoking GDB
+@node Invoking GDB, Quitting GDB, Invocation, Invocation
@section Invoking @value{GDBN}
@ifset H8EXCLUSIVE
@@ -696,17 +1024,19 @@ to debug a running process:
would attach @value{GDBN} to process @code{1234} (unless you also have a file
named @file{1234}; @value{GDBN} does check for a core file first).
+@ifclear HPPA
Taking advantage of the second command-line argument requires a fairly
complete operating system; when you use @value{GDBN} as a remote debugger
attached to a bare board, there may not be any notion of ``process'',
and there is often no way to get a core dump.
@end ifclear
+@end ifclear
You can run @code{gdb} without printing the front material, which describes
@value{GDBN}'s non-warranty, by specifying @code{-silent}:
@smallexample
-@value{GDBP} @var{-silent}
+@value{GDBP} -silent
@end smallexample
@noindent
@@ -753,6 +1083,9 @@ in sequential order. The order makes a difference when the
@ifset MIPS
* MIPS Remote:: @value{GDBN} and MIPS boards
@end ifset
+@ifset SPARCLET
+* Sparclet Remote:: @value{GDBN} and Sparclet boards
+@end ifset
@ifset SIMS
* Simulator:: Simulated CPU target
@end ifset
@@ -764,8 +1097,10 @@ in sequential order. The order makes a difference when the
@end menu
@ifclear GENERIC
+@ifclear HPPA
@include remote.texi
@end ifclear
+@end ifclear
@node File Options
@subsection Choosing files
@@ -833,6 +1168,7 @@ Files,, Command files}.
Add @var{directory} to the path to search for source files.
@ifclear BARETARGET
+@ifclear HPPA
@item -m
@itemx -mapped
@emph{Warning: this option depends on operating system facilities that are not
@@ -850,27 +1186,32 @@ The @file{.syms} file is specific to the host machine where @value{GDBN}
is run. It holds an exact image of the internal @value{GDBN} symbol
table. It cannot be shared across multiple host platforms.
@end ifclear
+@end ifclear
+@ifclear HPPA
@item -r
@itemx -readnow
Read each symbol file's entire symbol table immediately, rather than
the default, which is to read it incrementally as it is needed.
This makes startup slower, but makes future operations faster.
+@end ifclear
@end table
@ifclear BARETARGET
+@ifclear HPPA
The @code{-mapped} and @code{-readnow} options are typically combined in
order to build a @file{.syms} file that contains complete symbol
-information. (@xref{Files,,Commands to specify files}, for information
-
-a @file{.syms} file for future use is:
+information. (@xref{Files,,Commands to specify files}, for
+information on @file{.syms} files.) A simple GDB invocation to do
+nothing but build a @file{.syms} file for future use is:
@example
gdb -batch -nx -mapped -readnow programname
@end example
@end ifclear
+@end ifclear
-@node Mode Options
+@node Mode Options, , File Options, Invoking GDB
@subsection Choosing modes
You can run @value{GDBN} in various alternative modes---for example, in
@@ -880,9 +1221,9 @@ batch mode or quiet mode.
@item -nx
@itemx -n
Do not execute commands from any initialization files (normally called
-@file{@value{GDBINIT}}). Normally, the commands in these files are
-executed after all the command options and arguments have been
-processed. @xref{Command Files,,Command files}.
+@file{.gdbinit}, or @file{gdb.ini} on PCs). Normally, the commands in
+these files are executed after all the command options and arguments
+have been processed. @xref{Command Files,,Command files}.
@item -quiet
@itemx -q
@@ -912,16 +1253,6 @@ terminates) is not issued when running in batch mode.
Run @value{GDBN} using @var{directory} as its working directory,
instead of the current directory.
-@ifset LUCID
-@item -context @var{authentication}
-When the Energize programming system starts up @value{GDBN}, it uses this
-option to trigger an alternate mode of interaction.
-@var{authentication} is a pair of numeric codes that identify @value{GDBN}
-as a client in the Energize environment. Avoid this option when you run
-@value{GDBN} directly from the command line. See @ref{Energize,,Using
-@value{GDBN} with Energize} for more discussion of using @value{GDBN} with Energize.
-@end ifset
-
@ifclear DOSHOST
@item -fullname
@itemx -f
@@ -936,17 +1267,34 @@ a signal to display the source code for the frame.
@end ifclear
@ifset SERIAL
+@ifclear HPPA
@item -b @var{bps}
Set the line speed (baud rate or bits per second) of any serial
interface used by @value{GDBN} for remote debugging.
+@end ifclear
@item -tty @var{device}
Run using @var{device} for your program's standard input and output.
@c FIXME: kingdon thinks there is more to -tty. Investigate.
@end ifset
+
+@ifset HPPA
+@item -tui
+Use a Terminal User Interface. For information, use your Web browser to
+read the file @file{TUI.html}, which is usually installed in the
+directory @code{/opt/langtools/wdb/doc} on HP-UX systems. Do not use
+this option if you run @value{GDBN} from Emacs (see @pxref{Emacs, ,Using
+@value{GDBN} under @sc{gnu} Emacs}).
+
+@item -xdb
+Run in XDB compatibility mode, allowing the use of certain XDB commands.
+For information, see the file @file{xdb_trans.html}, which is usually
+installed in the directory @code{/opt/langtools/wdb/doc} on HP-UX
+systems.
+@end ifset
@end table
-@node Quitting GDB
+@node Quitting GDB, Shell Commands, Invoking GDB, Invocation
@section Quitting @value{GDBN}
@cindex exiting @value{GDBN}
@cindex leaving @value{GDBN}
@@ -974,7 +1322,7 @@ device, you can release it with the @code{detach} command
(@pxref{Attach, ,Debugging an already-running process}).
@end ifclear
-@node Shell Commands
+@node Shell Commands, , Quitting GDB, Invocation
@section Shell commands
If you need to execute occasional shell commands during your
@@ -985,7 +1333,7 @@ just use the @code{shell} command.
@kindex shell
@cindex shell escape
@item shell @var{command string}
-Invoke a the standard shell to execute @var{command string}.
+Invoke a standard shell to execute @var{command string}.
@ifclear DOSHOST
If it exists, the environment variable @code{SHELL} determines which
shell to run. Otherwise @value{GDBN} uses @code{/bin/sh}.
@@ -1004,7 +1352,7 @@ Execute the @code{make} program with the specified
arguments. This is equivalent to @samp{shell make @var{make-args}}.
@end table
-@node Commands
+@node Commands, Running, Invocation, Top
@chapter @value{GDBN} Commands
You can abbreviate a @value{GDBN} command to the first few letters of the command
@@ -1019,7 +1367,7 @@ show you the alternatives available, if there is more than one possibility).
* Help:: How to ask @value{GDBN} for help
@end menu
-@node Command Syntax
+@node Command Syntax, Completion, Commands, Commands
@section Command syntax
A @value{GDBN} command is a single line of input. There is no limit on
@@ -1062,7 +1410,7 @@ Any text from a @kbd{#} to the end of the line is a comment; it does
nothing. This is useful mainly in command files (@pxref{Command
Files,,Command files}).
-@node Completion
+@node Completion, Help, Command Syntax, Commands
@section Command completion
@cindex completion
@@ -1178,10 +1526,15 @@ place:
In general, @value{GDBN} can tell that a quote is needed (and inserts it) if
you have not yet started typing the argument list when you ask for
completion on an overloaded symbol.
+
+For more information about overloaded functions, @pxref{Cplus
+expressions, ,C++ expressions}. You can use the command @code{set
+overload-resolution off} to disable overload resolution;
+@pxref{Debugging C plus plus, ,@value{GDBN} features for C++}.
@end ifclear
-@node Help
+@node Help, , Completion, Commands
@section Getting help
@cindex online documentation
@kindex help
@@ -1259,9 +1612,11 @@ complete i
@noindent results in:
@smallexample
+@group
info
inspect
ignore
+@end group
@end smallexample
@noindent This is intended for use by @sc{gnu} Emacs.
@@ -1288,7 +1643,7 @@ You can get a complete list of the @code{info} sub-commands with
@kindex set
@item set
-You can assign the result of an expresson to an environment variable with
+You can assign the result of an expression to an environment variable with
@code{set}. For example, you can set the @value{GDBN} prompt to a $-sign with
@code{set prompt $}.
@@ -1334,7 +1689,7 @@ Display information about permission for copying @value{GDBN}.
Display the @sc{gnu} ``NO WARRANTY'' statement.
@end table
-@node Running
+@node Running, Stopping, Commands, Top
@chapter Running Programs Under @value{GDBN}
When you run a program under @value{GDBN}, you must first generate
@@ -1351,17 +1706,21 @@ already running process, or kill a child process.
@ifclear BARETARGET
* Arguments:: Your program's arguments
* Environment:: Your program's environment
+@end ifclear
+
* Working Directory:: Your program's working directory
* Input/Output:: Your program's input and output
* Attach:: Debugging an already-running process
* Kill Process:: Killing the child process
+@ifclear HPPA
* Process Information:: Additional process information
-* Threads:: Debugging programs with multiple threads
-* Processes:: Debugging programs with multiple processes
@end ifclear
+
+* Threads:: Debugging programs with multiple threads
+* Processes:: Debugging programs with multiple processes
@end menu
-@node Compilation
+@node Compilation, Starting, Running, Running
@section Compiling for debugging
In order to debug a program effectively, you need to generate
@@ -1377,7 +1736,13 @@ Many C compilers are unable to handle the @samp{-g} and @samp{-O}
options together. Using those compilers, you cannot generate optimized
executables containing debugging information.
+@ifclear HPPA
@value{NGCC}, the @sc{gnu} C compiler, supports @samp{-g} with or without
+@end ifclear
+@ifset HPPA
+The HP ANSI C and C++ compilers, as well as @value{NGCC}, the @sc{gnu} C
+compiler, support @samp{-g} with or without
+@end ifset
@samp{-O}, making it possible to debug optimized code. We recommend
that you @emph{always} use @samp{-g} whenever you compile a program.
You may think your program is correct, but there is no sense in pushing
@@ -1402,7 +1767,7 @@ Older versions of the @sc{gnu} C compiler permitted a variant option
format; if your @sc{gnu} C compiler has this option, do not use it.
@need 2000
-@node Starting
+@node Starting, Arguments, Compilation, Running
@section Starting your program
@cindex starting
@cindex running
@@ -1441,9 +1806,10 @@ Specify the arguments to give your program as the arguments of the
@code{run} command. If a shell is available on your target, the shell
is used to pass the arguments, so that you may use normal conventions
(such as wildcard expansion or variable substitution) in describing
-the arguments. In Unix systems, you can control which shell is used
-with the @code{SHELL} environment variable. @xref{Arguments, ,Your
-program's arguments}.
+the arguments.
+In Unix systems, you can control which shell is used with the
+@code{SHELL} environment variable.
+@xref{Arguments, ,Your program's arguments}.
@item The @emph{environment.}
Your program normally inherits its environment from @value{GDBN}, but you can
@@ -1483,16 +1849,17 @@ table, and reads it again. When it does this, @value{GDBN} tries to retain
your current breakpoints.
@ifclear BARETARGET
-@node Arguments
+@node Arguments, Environment, Starting, Running
@section Your program's arguments
@cindex arguments (to your program)
The arguments to your program can be specified by the arguments of the
-@code{run} command. They are passed to a shell, which expands wildcard
-characters and performs redirection of I/O, and thence to your program.
-Your @code{SHELL} environment variable (if it exists) specifies what
-shell @value{GDBN} uses. If you do not define @code{SHELL},
-@value{GDBN} uses @code{/bin/sh}.
+@code{run} command.
+They are passed to a shell, which expands wildcard characters and
+performs redirection of I/O, and thence to your program. Your
+@code{SHELL} environment variable (if it exists) specifies what shell
+@value{GDBN} uses. If you do not define @code{SHELL}, @value{GDBN} uses
+@code{/bin/sh}.
@code{run} with no arguments uses the same arguments used by the previous
@code{run}, or those set by the @code{set args} command.
@@ -1511,7 +1878,7 @@ it again without arguments.
Show the arguments to give your program when it is started.
@end table
-@node Environment
+@node Environment, Working Directory, Arguments, Running
@section Your program's environment
@cindex environment (of your program)
@@ -1592,7 +1959,7 @@ your program. You may wish to move setting of environment variables to
files that are only run when you sign on, such as @file{.login} or
@file{.profile}.
-@node Working Directory
+@node Working Directory, Input/Output, Environment, Running
@section Your program's working directory
@cindex working directory (of your program)
@@ -1616,7 +1983,7 @@ Set the @value{GDBN} working directory to @var{directory}.
Print the @value{GDBN} working directory.
@end table
-@node Input/Output
+@node Input/Output, Attach, Working Directory, Running
@section Your program's input and output
@cindex redirection
@@ -1670,7 +2037,7 @@ When you use the @code{tty} command or redirect input in the @code{run}
command, only the input @emph{for your program} is affected. The input
for @value{GDBN} still comes from your terminal.
-@node Attach
+@node Attach, Kill Process, Input/Output, Running
@section Debugging an already-running process
@kindex attach
@cindex attach
@@ -1692,14 +2059,23 @@ which supports processes; for example, @code{attach} does not work for
programs on bare-board targets that lack an operating system. You must
also have permission to send the process a signal.
-When using @code{attach}, you should first use the @code{file} command
-to specify the program running in the process and load its symbol table.
-@xref{Files, ,Commands to Specify Files}.
+When you use @code{attach}, the debugger finds the program running in
+the process first by looking in the current working directory, then (if
+the program is not found) by using the source file search path
+(@pxref{Source Path, ,Specifying source directories}). You can also use
+the @code{file} command to load the program. @xref{Files, ,Commands to
+Specify Files}.
The first thing @value{GDBN} does after arranging to debug the specified
process is to stop it. You can examine and modify an attached process
with all the @value{GDBN} commands that are ordinarily available when you start
+@ifclear HPPA
processes with @code{run}. You can insert breakpoints; you can step and
+@end ifclear
+@ifset HPPA
+processes with @code{run}. You can insert breakpoints (except in shared
+libraries); you can step and
+@end ifset
continue; you can modify storage. If you would rather the process
continue running, you may use the @code{continue} command after
attaching @value{GDBN} to the process.
@@ -1723,9 +2099,14 @@ control whether or not you need to confirm by using the @code{set
confirm} command (@pxref{Messages/Warnings, ,Optional warnings and
messages}).
-@node Kill Process
-@c @group
+@ifset HPPA
+@node Kill Process, Threads, Attach, Running
+@section Killing the child process
+@end ifset
+@ifclear HPPA
+@node Kill Process, Process Information, Attach, Running
@section Killing the child process
+@end ifclear
@table @code
@kindex kill
@@ -1736,7 +2117,6 @@ Kill the child process in which your program is running under @value{GDBN}.
This command is useful if you wish to debug a core dump instead of a
running process. @value{GDBN} ignores any core dump file while your program
is running.
-@c @end group
On some operating systems, a program cannot be executed outside @value{GDBN}
while you have breakpoints set on it inside @value{GDBN}. You can use the
@@ -1750,7 +2130,8 @@ next type @code{run}, @value{GDBN} notices that the file has changed, and
reads the symbol table again (while trying to preserve your current
breakpoint settings).
-@node Process Information
+@ifclear HPPA
+@node Process Information, Threads, Kill Process, Running
@section Additional process information
@kindex /proc
@@ -1791,20 +2172,27 @@ received.
@item info proc all
Show all the above information about the process.
@end table
+@end ifclear
-@node Threads
+@ifset HPPA
+@node Threads, Processes, Kill Process, Running
@section Debugging programs with multiple threads
+@end ifset
+@ifclear HPPA
+@node Threads, Processes, Process Information, Running
+@section Debugging programs with multiple threads
+@end ifclear
@cindex threads of execution
@cindex multiple threads
@cindex switching threads
-In some operating systems, a single program may have more than one
-@dfn{thread} of execution. The precise semantics of threads differ from
-one operating system to another, but in general the threads of a single
-program are akin to multiple processes---except that they share one
-address space (that is, they can all examine and modify the same
-variables). On the other hand, each thread has its own registers and
-execution stack, and perhaps private memory.
+In some operating systems, such as HP-UX and Solaris, a single program
+may have more than one @dfn{thread} of execution. The precise semantics
+of threads differ from one operating system to another, but in general
+the threads of a single program are akin to multiple processes---except
+that they share one address space (that is, they can all examine and
+modify the same variables). On the other hand, each thread has its own
+registers and execution stack, and perhaps private memory.
@value{GDBN} provides these facilities for debugging multi-thread
programs:
@@ -1818,6 +2206,7 @@ a command to apply a command to a list of threads
@item thread-specific breakpoints
@end itemize
+@ifclear HPPA
@quotation
@emph{Warning:} These facilities are not yet available on every
@value{GDBN} configuration where the operating system supports threads.
@@ -1835,6 +2224,7 @@ see the IDs of currently known threads.
@c FIXME to implementors: how hard would it be to say "sorry, this GDB
@c doesn't support threads"?
@end quotation
+@end ifclear
@cindex focus of debugging
@cindex current thread
@@ -1844,6 +2234,7 @@ control, one thread in particular is always the focus of debugging.
This thread is called the @dfn{current thread}. Debugging commands show
program information from the perspective of the current thread.
+@ifclear HPPA
@kindex New @var{systag}
@cindex thread identifier (system)
@c FIXME-implementors!! It would be more helpful if the [New...] message
@@ -1906,6 +2297,62 @@ For example,
* 1 process 35 thread 13 main (argc=1, argv=0x7ffffff8)
at threadtest.c:68
@end smallexample
+@end ifclear
+@ifset HPPA
+
+@cindex thread number
+@cindex thread identifier (GDB)
+For debugging purposes, @value{GDBN} associates its own thread
+number---a small integer assigned in thread-creation order---with each
+thread in your program.
+
+@kindex New @var{systag}
+@cindex thread identifier (system)
+@c FIXME-implementors!! It would be more helpful if the [New...] message
+@c included GDB's numeric thread handle, so you could just go to that
+@c thread without first checking `info threads'.
+Whenever @value{GDBN} detects a new thread in your program, it displays
+both @value{GDBN}'s thread number and the target system's identification for the thread with a message in the
+form @samp{[New @var{systag}]}. @var{systag} is a thread identifier
+whose form varies depending on the particular system. For example, on
+HP-UX, you see
+
+@example
+[New thread 2 (system thread 26594)]
+@end example
+
+@noindent
+when @value{GDBN} notices a new thread.
+
+@table @code
+@kindex info threads
+@item info threads
+Display a summary of all threads currently in your
+program. @value{GDBN} displays for each thread (in this order):
+
+@enumerate
+@item the thread number assigned by @value{GDBN}
+
+@item the target system's thread identifier (@var{systag})
+
+@item the current stack frame summary for that thread
+@end enumerate
+
+@noindent
+An asterisk @samp{*} to the left of the @value{GDBN} thread number
+indicates the current thread.
+
+For example,
+@end table
+@c end table here to get a little more width for example
+
+@example
+(@value{GDBP}) info threads
+ * 3 system thread 26607 worker (wptr=0x7b09c318 "@@") at quicksort.c:137
+ 2 system thread 26606 0x7b0030d8 in __ksleep () from /usr/lib/libc.2
+ 1 system thread 27905 0x7b003498 in _brk () from /usr/lib/libc.2
+@end example
+@end ifset
@table @code
@kindex thread @var{threadno}
@@ -1919,7 +2366,12 @@ you selected, and its current stack frame summary:
@smallexample
@c FIXME!! This example made up; find a @value{GDBN} w/threads and get real one
(@value{GDBP}) thread 2
+@ifclear HPPA
[Switching to process 35 thread 23]
+@end ifclear
+@ifset HPPA
+[Switching to thread 2 (system thread 26594)]
+@end ifset
0x34e5 in sigpause ()
@end smallexample
@@ -1955,7 +2407,8 @@ programs with multiple threads.
watchpoints in programs with multiple threads.
@end ifclear
-@node Processes
+@ifclear HPPA
+@node Processes, , Threads, Running
@section Debugging programs with multiple processes
@cindex fork, debugging programs which call
@@ -1978,8 +2431,68 @@ get its process ID. Then tell @value{GDBN} (a new invocation of
@value{GDBN} if you are also debugging the parent process) to attach to
the child process (see @ref{Attach}). From that point on you can debug
the child process just like any other process which you attached to.
+@end ifclear
+@ifset HPPA
+@node Processes, , Threads, Running
+@section Debugging programs with multiple processes
-@node Stopping
+@cindex fork, debugging programs which call
+@cindex multiple processes
+@cindex processes, multiple
+
+@value{GDBN} provides support for debugging programs that create
+additional processes using the @code{fork} or @code{vfork} function.
+
+By default, when a program forks, @value{GDBN} will continue to debug
+the parent process and the child process will run unimpeded.
+
+If you want to follow the child process instead of the parent process,
+use the command @w{@code{set follow-fork-mode}}.
+
+@table @code
+@kindex set follow-fork-mode
+@item set follow-fork-mode @var{mode}
+Set the debugger response to a program call of @code{fork} or
+@code{vfork}. A call to @code{fork} or @code{vfork} creates a new
+process. The @var{mode} can be:
+
+@table @code
+@item parent
+The original process is debugged after a fork. The child process runs
+unimpeded.
+
+@item child
+The new process is debugged after a fork. The parent process runs
+unimpeded.
+
+@item ask
+The debugger will ask for one of the above choices.
+@end table
+
+@item show follow-fork-mode
+Display the current debugger response to a fork or vfork call.
+@end table
+
+If you ask to debug a child process and a @code{vfork} is followed by an
+@code{exec}, @value{GDBN} executes the new target up to the first
+breakpoint in the new target. If you have a breakpoint set on
+@code{main} in your original program, the breakpoint will also be set on
+the child process's @code{main}.
+
+When a child process is spawned by @code{vfork}, you cannot debug the
+child or parent until an @code{exec} call completes.
+
+If you issue a @code{run} command to @value{GDBN} after an @code{exec}
+call executes, the new target restarts. To restart the parent process,
+use the @code{file} command with the parent executable name as its
+argument.
+
+You can use the @code{catch} command to make @value{GDBN} stop whenever
+a @code{fork}, @code{vfork}, or @code{exec} call is made. @xref{Set
+Catchpoints, ,Setting catchpoints}.
+@end ifset
+
+@node Stopping, Stack, Running, Top
@chapter Stopping and Continuing
The principal purposes of using a debugger are so that you can stop your
@@ -2010,51 +2523,36 @@ and why it stopped.
@end table
@menu
-@ifclear CONLY
-* Breakpoints:: Breakpoints, watchpoints, and exceptions
-@end ifclear
-@ifset CONLY
-* Breakpoints:: Breakpoints and watchpoints
-@end ifset
-@c Remnant makeinfo bug requires blank line after *successful* end-if in menu:
-
+* Breakpoints:: Breakpoints, watchpoints, and catchpoints
* Continuing and Stepping:: Resuming execution
@ifset POSIX
* Signals:: Signals
@end ifset
+
@ifclear BARETARGET
-* Thread Stops:: Stopping and starting multi-thread programs
+* Thread Stops:: Stopping and starting multi-thread programs
@end ifclear
+
@end menu
-@c makeinfo node-defaulting requires adjacency of @node and sectioning cmds
-@c ...hence distribute @node Breakpoints over two possible @if expansions.
-@c
-@ifclear CONLY
-@node Breakpoints
-@section Breakpoints, watchpoints, and exceptions
-@end ifclear
-@ifset CONLY
-@node Breakpoints
-@section Breakpoints and watchpoints
-@end ifset
+@node Breakpoints, Continuing and Stepping, Stopping, Stopping
+@section Breakpoints, watchpoints, and catchpoints
@cindex breakpoints
A @dfn{breakpoint} makes your program stop whenever a certain point in
-the program is reached. For each breakpoint, you can add
-conditions to control in finer detail whether your program stops.
-You can set breakpoints with the @code{break} command and its variants
-(@pxref{Set Breaks, ,Setting breakpoints}), to specify the place where
-your program should stop by line number, function name or exact address
-in the program.
-@ifclear CONLY
-In languages with exception handling (such as @sc{gnu} C++), you can also set
-breakpoints where an exception is raised (@pxref{Exception Handling,,
-Breakpoints and exceptions}).
-@end ifclear
+the program is reached. For each breakpoint, you can add conditions to
+control in finer detail whether your program stops. You can set
+breakpoints with the @code{break} command and its variants (@pxref{Set
+Breaks, ,Setting breakpoints}), to specify the place where your program
+should stop by line number, function name or exact address in the
+program.
-In SunOS 4.x, SVR4, and Alpha OSF/1 configurations, you can now set
-breakpoints in shared libraries before the executable is run.
+In HP-UX, SunOS 4.x, SVR4, and Alpha OSF/1 configurations, you can set
+breakpoints in shared libraries before the executable is run. There is
+a minor limitation on HP-UX systems: you must wait until the executable
+is run in order to set breakpoints in shared library routines that are
+not called directly by the program (for example, routines that are
+arguments in a @code{pthread_create} call).
@cindex watchpoints
@cindex memory tracing
@@ -2071,22 +2569,30 @@ You can arrange to have values from your program displayed automatically
whenever @value{GDBN} stops at a breakpoint. @xref{Auto Display,,
Automatic display}.
+@cindex catchpoints
+@cindex breakpoint on events
+A @dfn{catchpoint} is another special breakpoint that stops your program
+when a certain kind of event occurs, such as the throwing of a C++
+exception or the loading of a library. As with watchpoints, you use a
+different command to set a catchpoint (@pxref{Set Catchpoints, ,Setting
+catchpoints}), but aside from that, you can manage a catchpoint like any
+other breakpoint. (To stop when your program receives a signal, use the
+@code{handle} command; @pxref{Signals, ,Signals}.)
+
@cindex breakpoint numbers
@cindex numbers for breakpoints
-@value{GDBN} assigns a number to each breakpoint or watchpoint when you
-create it; these numbers are successive integers starting with one. In
-many of the commands for controlling various features of breakpoints you
-use the breakpoint number to say which breakpoint you want to change.
-Each breakpoint may be @dfn{enabled} or @dfn{disabled}; if disabled, it has
-no effect on your program until you enable it again.
+@value{GDBN} assigns a number to each breakpoint, watchpoint, or
+catchpoint when you create it; these numbers are successive integers
+starting with one. In many of the commands for controlling various
+features of breakpoints you use the breakpoint number to say which
+breakpoint you want to change. Each breakpoint may be @dfn{enabled} or
+@dfn{disabled}; if disabled, it has no effect on your program until you
+enable it again.
@menu
* Set Breaks:: Setting breakpoints
* Set Watchpoints:: Setting watchpoints
-@ifclear CONLY
-* Exception Handling:: Breakpoints and exceptions
-@end ifclear
-
+* Set Catchpoints:: Setting catchpoints
* Delete Breaks:: Deleting breakpoints
* Disabling:: Disabling breakpoints
* Conditions:: Break conditions
@@ -2094,12 +2600,13 @@ no effect on your program until you enable it again.
@ifclear CONLY
* Breakpoint Menus:: Breakpoint menus
@end ifclear
+
@c @ifclear BARETARGET
@c * Error in Breakpoints:: ``Cannot insert breakpoints''
@c @end ifclear
@end menu
-@node Set Breaks
+@node Set Breaks, Set Watchpoints, Breakpoints, Breakpoints
@subsection Setting breakpoints
@c FIXME LMB what does GDB do if no code on line of breakpt?
@@ -2186,6 +2693,7 @@ same as for the @code{break} command, and the breakpoint is set in the same
way, but the breakpoint is automatically deleted after the first time your
program stops there. @xref{Disabling, ,Disabling breakpoints}.
+@ifclear HPPA
@kindex hbreak
@item hbreak @var{args}
Set a hardware-assisted breakpoint. @var{args} are the same as for the
@@ -2195,10 +2703,10 @@ have this support. The main purpose of this is EPROM/ROM code
debugging, so you can set a breakpoint at an instruction without
changing the instruction. This can be used with the new trap-generation
provided by SPARClite DSU. DSU will generate traps when a program accesses
-some date or instruction address that is assigned to the debug registers.
+some data or instruction address that is assigned to the debug registers.
However the hardware breakpoint registers can only take two data breakpoints,
and @value{GDBN} will reject this command if more than two are used.
-Delete or disable usused hardware breakpoints before setting
+Delete or disable unused hardware breakpoints before setting
new ones. @xref{Conditions, ,Break conditions}.
@kindex thbreak
@@ -2211,6 +2719,7 @@ first time your program stops there. Also, like the @code{hbreak}
command, the breakpoint requires hardware support and some target hardware
may not have this support. @xref{Disabling, ,Disabling breakpoints}.
Also @xref{Conditions, ,Break conditions}.
+@end ifclear
@kindex rbreak
@cindex regular expression
@@ -2235,13 +2744,13 @@ classes.
@item info breakpoints @r{[}@var{n}@r{]}
@itemx info break @r{[}@var{n}@r{]}
@itemx info watchpoints @r{[}@var{n}@r{]}
-Print a table of all breakpoints and watchpoints set and not
-deleted, with the following columns for each breakpoint:
+Print a table of all breakpoints, watchpoints, and catchpoints set and
+not deleted, with the following columns for each breakpoint:
@table @emph
@item Breakpoint Numbers
@item Type
-Breakpoint or watchpoint.
+Breakpoint, watchpoint, or catchpoint.
@item Disposition
Whether the breakpoint is marked to be disabled or deleted when hit.
@item Enabled or Disabled
@@ -2267,12 +2776,12 @@ the @code{x} command are set to the address of the last breakpoint
listed (@pxref{Memory, ,Examining memory}).
@noindent
-@code{info break} now displays a count of the number of times the
-breakpoint has been hit. This is especially useful in conjunction with
-the @code{ignore} command. You can ignore a large number of breakpoint
-hits, look at the breakpoint info to see how many times the
-breakpoint was hit, and then run again, ignoring one less than that
-number. This will get you quickly to the last hit of that breakpoint.
+@code{info break} displays a count of the number of times the breakpoint
+has been hit. This is especially useful in conjunction with the
+@code{ignore} command. You can ignore a large number of breakpoint
+hits, look at the breakpoint info to see how many times the breakpoint
+was hit, and then run again, ignoring one less than that number. This
+will get you quickly to the last hit of that breakpoint.
@end table
@value{GDBN} allows you to set any number of breakpoints at the same place in
@@ -2318,50 +2827,45 @@ Temporary internal breakpoint used by the @value{GDBN} @code{until} command.
@item finish
Temporary internal breakpoint used by the @value{GDBN} @code{finish} command.
-@end table
+@ifset HPPA
+@item shlib events
+Shared library events.
+@end ifset
+@end table
@end table
-@node Set Watchpoints
+@node Set Watchpoints, Set Catchpoints, Set Breaks, Breakpoints
@subsection Setting watchpoints
-@cindex setting watchpoints
+@cindex setting watchpoints
+@cindex software watchpoints
+@cindex hardware watchpoints
You can use a watchpoint to stop execution whenever the value of an
-expression changes, without having to predict a particular place
-where this may happen.
-
-Watchpoints currently execute two orders of magnitude more slowly than
-other breakpoints, but this can be well worth it to catch errors where
-you have no clue what part of your program is the culprit.
-
-@c FIXME - did Stan mean to @ignore this out?
-@ignore
-Some processors provide special hardware to support watchpoint
-evaluation; @value{GDBN} will use such hardware if it is available,
-and if the support code has been added for that configuration.
-@end ignore
+expression changes, without having to predict a particular place where
+this may happen.
+
+Depending on your system, watchpoints may be implemented in software or
+hardware. GDB does software watchpointing by single-stepping your
+program and testing the variable's value each time, which is hundreds of
+times slower than normal execution. (But this may still be worth it, to
+catch errors where you have no clue what part of your program is the
+culprit.)
+
+On some systems, such as HP-UX and Linux, GDB includes support for
+hardware watchpoints, which do not slow down the running of your
+program.
@table @code
@kindex watch
@item watch @var{expr}
Set a watchpoint for an expression. @value{GDBN} will break when @var{expr}
is written into by the program and its value changes.
-This can be used with the new trap-generation provided by
-SPARClite DSU. DSU will generate traps when a program accesses
-some date or instruction address that is assigned to the debug registers.
-For the data addresses, DSU facilitates the @code{watch} command.
-However the hardware breakpoint registers can only take two data watchpoints,
-and both watchpoints must be the same kind. For example, you can set two
-watchpoints with @code{watch} commands, two with @code{rwatch}
-commands, @strong{or} two with @code{awatch} commands, but you cannot set one
-watchpoint with one command and the other with a different command.
-@value{GBDN} will reject the command if you try to mix watchpoints.
-Delete or disable unused watchpoint commands before setting new ones.
@kindex rwatch
@item rwatch @var{expr}
-Set a watchpoint that will break when watch @var{args} is read by the program.
+Set a watchpoint that will break when watch @var{expr} is read by the program.
If you use both watchpoints, both must be set with the @code{rwatch}
command.
@@ -2373,15 +2877,47 @@ by the program. If you use both watchpoints, both must be set with the
@kindex info watchpoints
@item info watchpoints
-This command prints a list of watchpoints and breakpoints; it is the
-same as @code{info break}.
+This command prints a list of watchpoints, breakpoints, and catchpoints;
+it is the same as @code{info break}.
@end table
+@value{GDBN} sets a @dfn{hardware watchpoint} if possible. Hardware
+watchpoints execute very quickly, and the debugger reports a change in
+value at the exact instruction where the change occurs. If @value{GDBN}
+cannot set a hardware watchpoint, it sets a software watchpoint, which
+executes more slowly and reports the change in value at the next
+statement, not the instruction, after the change occurs.
+
+When you issue the @code{watch} command, @value{GDBN} reports
+
+@example
+Hardware watchpoint @var{num}: @var{expr}
+@end example
+
+@noindent
+if it was able to set a hardware watchpoint.
+
+The SPARClite DSU will generate traps when a program accesses
+some data or instruction address that is assigned to the debug registers.
+For the data addresses, DSU facilitates the @code{watch} command.
+However the hardware breakpoint registers can only take two data watchpoints,
+and both watchpoints must be the same kind. For example, you can set two
+watchpoints with @code{watch} commands, two with @code{rwatch}
+commands, @strong{or} two with @code{awatch} commands, but you cannot set one
+watchpoint with one command and the other with a different command.
+@value{GDBN} will reject the command if you try to mix watchpoints.
+Delete or disable unused watchpoint commands before setting new ones.
+
+If you call a function interactively using @code{print} or @code{call},
+any watchpoints you have set will be inactive until GDB reaches another
+kind of breakpoint or the call completes.
+
@ifclear BARETARGET
@quotation
@cindex watchpoints and threads
@cindex threads and watchpoints
-@emph{Warning:} in multi-thread programs, watchpoints have only limited
+@ifclear HPPA
+@emph{Warning:} In multi-thread programs, watchpoints have only limited
usefulness. With the current watchpoint implementation, @value{GDBN}
can only watch the value of an expression @emph{in a single thread}. If
you are confident that the expression can only change due to the current
@@ -2389,40 +2925,90 @@ thread's activity (and if you are also confident that no other thread
can become current), then you can use watchpoints as usual. However,
@value{GDBN} may not notice when a non-current thread's activity changes
the expression.
+@end ifclear
+@ifset HPPA
+@emph{Warning:} In multi-thread programs, software watchpoints have only
+limited usefulness. If @value{GDBN} creates a software watchpoint, it
+can only watch the value of an expression @emph{in a single thread}. If
+you are confident that the expression can only change due to the current
+thread's activity (and if you are also confident that no other thread
+can become current), then you can use software watchpoints as usual.
+However, @value{GDBN} may not notice when a non-current thread's
+activity changes the expression. (Hardware watchpoints, in contrast,
+watch an expression in all threads.)
+@end ifset
@end quotation
@end ifclear
-@ifclear CONLY
-@node Exception Handling
-@subsection Breakpoints and exceptions
+@node Set Catchpoints, Delete Breaks, Set Watchpoints, Breakpoints
+@subsection Setting catchpoints
+@cindex catchpoints
@cindex exception handlers
+@cindex event handling
-Some languages, such as @sc{gnu} C++, implement exception handling. You can
-use @value{GDBN} to examine what caused your program to raise an exception,
-and to list the exceptions your program is prepared to handle at a
-given point in time.
+You can use @dfn{catchpoints} to cause the debugger to stop for certain
+kinds of program events, such as C++ exceptions or the loading of a
+shared library. Use the @code{catch} command to set a catchpoint.
@table @code
@kindex catch
-@item catch @var{exceptions}
-You can set breakpoints at active exception handlers by using the
-@code{catch} command. @var{exceptions} is a list of names of exceptions
-to catch.
+@item catch @var{event}
+Stop when @var{event} occurs. @var{event} can be any of the following:
+@table @code
+@item throw
+@kindex catch throw
+The throwing of a C++ exception.
+
+@item catch
+@kindex catch catch
+The catching of a C++ exception.
+
+@item exec
+@kindex catch exec
+A call to @code{exec}. This is currently only available for HP-UX.
+
+@item fork
+@kindex catch fork
+A call to @code{fork}. This is currently only available for HP-UX.
+
+@item vfork
+@kindex catch vfork
+A call to @code{vfork}. This is currently only available for HP-UX.
+
+@item load
+@itemx load @var{libname}
+@kindex catch load
+The dynamic loading of any shared library, or the loading of the library
+@var{libname}. This is currently only available for HP-UX.
+
+@item unload
+@itemx unload @var{libname}
+@kindex catch unload
+The unloading of any dynamically loaded shared library, or the unloading
+of the library @var{libname}. This is currently only available for HP-UX.
@end table
-You can use @code{info catch} to list active exception handlers.
-@xref{Frame Info, ,Information about a frame}.
+@item tcatch @var{event}
+Set a catchpoint that is enabled only for one stop. The catchpoint is
+automatically deleted after the first time the event is caught.
-There are currently some limitations to exception handling in @value{GDBN}:
+@end table
+
+Use the @code{info break} command to list the current catchpoints.
+
+There are currently some limitations to C++ exception handling
+(@code{catch throw} and @code{catch catch}) in @value{GDBN}:
@itemize @bullet
@item
If you call a function interactively, @value{GDBN} normally returns
control to you when the function has finished executing. If the call
raises an exception, however, the call may bypass the mechanism that
-returns control to you and cause your program to simply continue
-running until it hits a breakpoint, catches a signal that @value{GDBN} is
-listening for, or exits.
+returns control to you and cause your program either to abort or to
+simply continue running until it hits a breakpoint, catches a signal
+that @value{GDBN} is listening for, or exits. This is the case even if
+you set a catchpoint for the exception; catchpoints on exceptions are
+disabled within interactive calls.
@item
You cannot raise an exception interactively.
@@ -2460,30 +3046,30 @@ that depends on the value of @var{id}, you can stop your program when
a specific exception is raised. You can use multiple conditional
breakpoints to stop your program when any of a number of exceptions are
raised.
-@end ifclear
-@node Delete Breaks
+
+@node Delete Breaks, Disabling, Set Catchpoints, Breakpoints
@subsection Deleting breakpoints
-@cindex clearing breakpoints, watchpoints
-@cindex deleting breakpoints, watchpoints
-It is often necessary to eliminate a breakpoint or watchpoint once it
-has done its job and you no longer want your program to stop there. This
-is called @dfn{deleting} the breakpoint. A breakpoint that has been
-deleted no longer exists; it is forgotten.
+@cindex clearing breakpoints, watchpoints, catchpoints
+@cindex deleting breakpoints, watchpoints, catchpoints
+It is often necessary to eliminate a breakpoint, watchpoint, or
+catchpoint once it has done its job and you no longer want your program
+to stop there. This is called @dfn{deleting} the breakpoint. A
+breakpoint that has been deleted no longer exists; it is forgotten.
With the @code{clear} command you can delete breakpoints according to
where they are in your program. With the @code{delete} command you can
-delete individual breakpoints or watchpoints by specifying their
-breakpoint numbers.
+delete individual breakpoints, watchpoints, or catchpoints by specifying
+their breakpoint numbers.
It is not necessary to delete a breakpoint to proceed past it. @value{GDBN}
automatically ignores breakpoints on the first instruction to be executed
when you continue execution without changing the execution address.
@table @code
-@item clear
@kindex clear
+@item clear
Delete any breakpoints at the next instruction to be executed in the
selected stack frame (@pxref{Selection, ,Selecting a frame}). When
the innermost frame is selected, this is a good way to delete a
@@ -2501,30 +3087,30 @@ Delete any breakpoints set at or within the code of the specified line.
@kindex delete
@kindex d
@item delete @r{[}breakpoints@r{]} @r{[}@var{bnums}@dots{}@r{]}
-Delete the breakpoints or watchpoints of the numbers specified as
-arguments. If no argument is specified, delete all breakpoints (@value{GDBN}
-asks confirmation, unless you have @code{set confirm off}). You
-can abbreviate this command as @code{d}.
+Delete the breakpoints, watchpoints, or catchpoints of the numbers
+specified as arguments. If no argument is specified, delete all
+breakpoints (@value{GDBN} asks confirmation, unless you have @code{set
+confirm off}). You can abbreviate this command as @code{d}.
@end table
-@node Disabling
+@node Disabling, Conditions, Delete Breaks, Breakpoints
@subsection Disabling breakpoints
@kindex disable breakpoints
@kindex enable breakpoints
-Rather than deleting a breakpoint or watchpoint, you might prefer to
-@dfn{disable} it. This makes the breakpoint inoperative as if it had
-been deleted, but remembers the information on the breakpoint so that
-you can @dfn{enable} it again later.
+Rather than deleting a breakpoint, watchpoint, or catchpoint, you might
+prefer to @dfn{disable} it. This makes the breakpoint inoperative as if
+it had been deleted, but remembers the information on the breakpoint so
+that you can @dfn{enable} it again later.
-You disable and enable breakpoints and watchpoints with the
-@code{enable} and @code{disable} commands, optionally specifying one or
-more breakpoint numbers as arguments. Use @code{info break} or
-@code{info watch} to print a list of breakpoints or watchpoints if you
-do not know which numbers to use.
+You disable and enable breakpoints, watchpoints, and catchpoints with
+the @code{enable} and @code{disable} commands, optionally specifying one
+or more breakpoint numbers as arguments. Use @code{info break} or
+@code{info watch} to print a list of breakpoints, watchpoints, and
+catchpoints if you do not know which numbers to use.
-A breakpoint or watchpoint can have any of four different states of
-enablement:
+A breakpoint, watchpoint, or catchpoint can have any of four different
+states of enablement:
@itemize @bullet
@item
@@ -2541,8 +3127,8 @@ Enabled for deletion. The breakpoint stops your program, but
immediately after it does so it is deleted permanently.
@end itemize
-You can use the following commands to enable or disable breakpoints and
-watchpoints:
+You can use the following commands to enable or disable breakpoints,
+watchpoints, and catchpoints:
@table @code
@kindex disable breakpoints
@@ -2578,7 +3164,7 @@ breakpoint of its own, but it does not change the state of your other
breakpoints; see @ref{Continuing and Stepping, ,Continuing and
stepping}.)
-@node Conditions
+@node Conditions, Break Commands, Disabling, Breakpoints
@subsection Break conditions
@cindex conditional breakpoints
@cindex breakpoint conditions
@@ -2618,20 +3204,31 @@ purpose of performing side effects when a breakpoint is reached
Break conditions can be specified when a breakpoint is set, by using
@samp{if} in the arguments to the @code{break} command. @xref{Set
Breaks, ,Setting breakpoints}. They can also be changed at any time
-with the @code{condition} command. The @code{watch} command does not
-recognize the @code{if} keyword; @code{condition} is the only way to
-impose a further condition on a watchpoint.
+with the @code{condition} command.
+@ifclear HPPA
+@c The watch command now seems to recognize the if keyword.
+@c catch doesn't, though.
+The @code{watch} command does not recognize the @code{if} keyword;
+@code{condition} is the only way to impose a further condition on a
+watchpoint.
+@end ifclear
+@ifset HPPA
+You can also use the @code{if} keyword with the @code{watch} command.
+The @code{catch} command does not recognize the @code{if} keyword;
+@code{condition} is the only way to impose a further condition on a
+catchpoint.
+@end ifset
@table @code
@kindex condition
@item condition @var{bnum} @var{expression}
-Specify @var{expression} as the break condition for breakpoint or
-watchpoint number @var{bnum}. After you set a condition, breakpoint
-@var{bnum} stops your program only if the value of @var{expression} is
-true (nonzero, in C). When you use @code{condition}, @value{GDBN}
-checks @var{expression} immediately for syntactic correctness, and to
-determine whether symbols in it have referents in the context of your
-breakpoint.
+Specify @var{expression} as the break condition for breakpoint,
+watchpoint, or catchpoint number @var{bnum}. After you set a condition,
+breakpoint @var{bnum} stops your program only if the value of
+@var{expression} is true (nonzero, in C). When you use
+@code{condition}, @value{GDBN} checks @var{expression} immediately for
+syntactic correctness, and to determine whether symbols in it have
+referents in the context of your breakpoint.
@c FIXME so what does GDB do if there is no referent? Moreover, what
@c about watchpoints?
@value{GDBN} does
@@ -2681,14 +3278,17 @@ is decremented each time. @xref{Convenience Vars, ,Convenience
variables}.
@end table
-@node Break Commands
+Ignore counts apply to breakpoints, watchpoints, and catchpoints.
+
+
+@node Break Commands, Breakpoint Menus, Conditions, Breakpoints
@subsection Breakpoint command lists
@cindex breakpoint commands
-You can give any breakpoint (or watchpoint) a series of commands to
-execute when your program stops due to that breakpoint. For example, you
-might want to print the values of certain expressions, or enable other
-breakpoints.
+You can give any breakpoint (or watchpoint or catchpoint) a series of
+commands to execute when your program stops due to that breakpoint. For
+example, you might want to print the values of certain expressions, or
+enable other breakpoints.
@table @code
@kindex commands
@@ -2704,8 +3304,8 @@ To remove all commands from a breakpoint, type @code{commands} and
follow it immediately with @code{end}; that is, give no commands.
With no @var{bnum} argument, @code{commands} refers to the last
-breakpoint or watchpoint set (not to the breakpoint most recently
-encountered).
+breakpoint, watchpoint, or catchpoint set (not to the breakpoint most
+recently encountered).
@end table
Pressing @key{RET} as a means of repeating the last @value{GDBN} command is
@@ -2763,7 +3363,7 @@ end
@end example
@ifclear CONLY
-@node Breakpoint Menus
+@node Breakpoint Menus, , Break Commands, Breakpoints
@subsection Breakpoint menus
@cindex overloading
@cindex symbol overloading
@@ -2788,6 +3388,7 @@ We choose three particular definitions of that function name:
@c FIXME! This is likely to change to show arg type lists, at least
@smallexample
+@group
(@value{GDBP}) b String::after
[0] cancel
[1] all
@@ -2805,6 +3406,7 @@ Multiple breakpoints were set.
Use the "delete" command to delete unwanted
breakpoints.
(@value{GDBP})
+@end group
@end smallexample
@end ifclear
@@ -2838,7 +3440,7 @@ Use the "delete" command to delete unwanted
@c @end enumerate
@c @end ifclear
-@node Continuing and Stepping
+@node Continuing and Stepping, Signals, Breakpoints, Stopping
@section Continuing and stepping
@cindex stepping
@@ -2886,17 +3488,11 @@ calling function; or @code{jump} (@pxref{Jumping, ,Continuing at a
different address}) to go to an arbitrary location in your program.
A typical technique for using stepping is to set a breakpoint
-@ifclear CONLY
-(@pxref{Breakpoints, ,Breakpoints; watchpoints; and exceptions})
-@end ifclear
-@ifset CONLY
-(@pxref{Breakpoints, ,Breakpoints and watchpoints})
-@end ifset
-at the
-beginning of the function or the section of your program where a
-problem is believed to lie, run your program until it stops at that
-breakpoint, and then step through the suspect area, examining the
-variables that are interesting, until you see the problem happen.
+(@pxref{Breakpoints, ,Breakpoints; watchpoints; and catchpoints}) at the
+beginning of the function or the section of your program where a problem
+is believed to lie, run your program until it stops at that breakpoint,
+and then step through the suspect area, examining the variables that are
+interesting, until you see the problem happen.
@table @code
@kindex step
@@ -2961,7 +3557,7 @@ An argument @var{count} is a repeat count, as for @code{step}.
The @code{next} command now only stops at the first instruction of a
source line. This prevents the multiple stops that used to occur in
-swtch statements, for loops, etc.
+switch statements, for loops, etc.
@kindex finish
@item finish
@@ -2972,9 +3568,9 @@ Contrast this with the @code{return} command (@pxref{Returning,
,Returning from a function}).
@kindex until
-@itemx u
@kindex u
@item until
+@itemx u
Continue running until a source line past the current line, in the
current stack frame, is reached. This command is used to avoid single
stepping through a loop more than once. It is like the @code{next}
@@ -3050,7 +3646,7 @@ An argument is a repeat count, as in @code{next}.
@end table
@ifset POSIX
-@node Signals
+@node Signals, Thread Stops, Continuing and Stepping, Stopping
@section Signals
@cindex signals
@@ -3146,7 +3742,7 @@ program a signal}.
@end ifset
@ifclear BARETARGET
-@node Thread Stops
+@node Thread Stops, , Signals, Stopping
@section Stopping and starting multi-thread programs
When your program has multiple threads (@pxref{Threads,, Debugging
@@ -3208,9 +3804,32 @@ You might even find your program stopped in another thread after
continuing or even single-stepping. This happens whenever some other
thread runs into a breakpoint, a signal, or an exception before the
first thread completes whatever you requested.
+
+On some OSes, you can lock the OS scheduler and thus allow only a single
+thread to run.
+
+@table @code
+@item set scheduler-locking @var{mode}
+Set the scheduler locking mode. If it is @code{off}, then there is no
+locking and any thread may run at any time. If @code{on}, then only the
+current thread may run when the inferior is resumed. The @code{step}
+mode optimizes for single-stepping. It stops other threads from
+``seizing the prompt'' by preempting the current thread while you are
+stepping. Other threads will only rarely (or never) get a chance to run
+when you step. They are more likely to run when you ``next'' over a
+function call, and they are completely free to run when you use commands
+like ``continue'', ``until'', or ``finish''. However, unless another
+thread hits a breakpoint during its timeslice, they will never steal the
+GDB prompt away from the thread that you are debugging.
+
+@item show scheduler-locking
+Display the current scheduler locking mode.
+@end table
+
@end ifclear
-@node Stack
+
+@node Stack, Source, Stopping, Top
@chapter Examining the Stack
When your program has stopped, the first thing you need to know is where it
@@ -3246,12 +3865,11 @@ currently executing frame and describes it briefly, similar to the
* Backtrace:: Backtraces
* Selection:: Selecting a frame
* Frame Info:: Information on a frame
-@ifset MIPS
-* MIPS Stack:: MIPS machines and the function stack
-@end ifset
+* Alpha/MIPS Stack:: Alpha and MIPS machines and the function stack
+
@end menu
-@node Frames
+@node Frames, Backtrace, Stack, Stack
@section Stack frames
@cindex frame
@@ -3307,7 +3925,7 @@ no provision for frameless functions elsewhere in the stack.
@item frame @var{args}
The @code{frame} command allows you to move from one stack frame to another,
and to print the stack frame you select. @var{args} may be either the
-address of the frame of the stack frame number. Without an argument,
+address of the frame or the stack frame number. Without an argument,
@code{frame} prints the current stack frame.
@kindex select-frame
@@ -3317,9 +3935,12 @@ to another without printing the frame. This is the silent version of
@code{frame}.
@end table
-@node Backtrace
+@node Backtrace, Selection, Frames, Stack
@section Backtraces
+@cindex backtraces
+@cindex tracebacks
+@cindex stack traces
A backtrace is a summary of how your program got where it is. It shows one
line per frame, for many frames, starting with the currently executing
frame (frame zero), followed by its caller (frame one), and on up the
@@ -3377,7 +3998,7 @@ The display for frame zero does not begin with a program counter
value, indicating that your program has stopped at the beginning of the
code for line @code{993} of @code{builtin.c}.
-@node Selection
+@node Selection, Frame Info, Backtrace, Stack
@section Selecting a frame
Most commands for examining the stack and other data in your program work on
@@ -3404,6 +4025,7 @@ addition, this can be useful when your program has multiple stacks and
switches between them.
@ifclear H8EXCLUSIVE
+@ifclear HPPA
On the SPARC architecture, @code{frame} needs two addresses to
select an arbitrary frame: a frame pointer and a stack pointer.
@@ -3416,6 +4038,7 @@ pointer, a program counter, and a memory stack pointer.
@c SETUP_ARBITRARY_FRAME in the tm-*.h files. The above is up to date
@c as of 27 Jan 1994.
@end ifclear
+@end ifclear
@kindex up
@item up @var{n}
@@ -3465,7 +4088,7 @@ in @value{GDBN} command scripts, where the output might be unnecessary and
distracting.
@end table
-@node Frame Info
+@node Frame Info, Alpha/MIPS Stack, Selection, Stack
@section Information about a frame
There are several other commands to print information about the selected
@@ -3527,6 +4150,7 @@ line. These are all variables (declared either static or automatic)
accessible at the point of execution of the selected frame.
@ifclear CONLY
+@ifclear HPPA
@kindex info catch
@cindex catch exceptions
@cindex exception handlers
@@ -3535,19 +4159,21 @@ Print a list of all the exception handlers that are active in the
current stack frame at the current point of execution. To see other
exception handlers, visit the associated frame (using the @code{up},
@code{down}, or @code{frame} commands); then type @code{info catch}.
-@xref{Exception Handling, ,Breakpoints and exceptions}.
+@xref{Set Catchpoints, , Setting catchpoints}.
+@end ifclear
@end ifclear
@end table
-@ifset MIPS
-@node MIPS Stack
-@section MIPS machines and the function stack
+@node Alpha/MIPS Stack, , Frame Info, Stack
+@section MIPS/Alpha machines and the function stack
+@cindex stack on Alpha
@cindex stack on MIPS
+@cindex Alpha stack
@cindex MIPS stack
-MIPS based computers use an unusual stack frame, which sometimes
-requires @value{GDBN} to search backward in the object code to find the
-beginning of a function.
+Alpha- and MIPS-based computers use an unusual stack frame, which
+sometimes requires @value{GDBN} to search backward in the object code to
+find the beginning of a function.
@cindex response time, MIPS debugging
To improve response time (especially for embedded applications, where
@@ -3556,7 +4182,7 @@ you may want to limit the size of this search, using one of these
commands:
@table @code
-@cindex @code{heuristic-fence-post} (MIPS)
+@cindex @code{heuristic-fence-post} (Alpha,MIPS)
@item set heuristic-fence-post @var{limit}
Restrict @value{GDBN} to examining at most @var{limit} bytes in its search
for the beginning of a function. A value of @var{0} (the default)
@@ -3570,10 +4196,10 @@ Display the current limit.
@noindent
These commands are available @emph{only} when @value{GDBN} is configured
-for debugging programs on MIPS processors.
-@end ifset
+for debugging programs on Alpha or MIPS processors.
+
-@node Source
+@node Source, Data, Stack, Top
@chapter Examining Source Files
@value{GDBN} can print parts of your program's source, since the debugging
@@ -3600,7 +4226,7 @@ Emacs facilities to view source; @pxref{Emacs, ,Using @value{GDBN} under @sc{gnu
* Machine Code:: Source and machine code
@end menu
-@node List
+@node List, Search, Source, Source
@section Printing source lines
@kindex list
@@ -3718,7 +4344,7 @@ Specifies the line containing the program address @var{address}.
@end table
@ifclear DOSHOST
-@node Search
+@node Search, Source Path, List, Source
@section Searching source files
@cindex searching
@kindex reverse-search
@@ -3745,7 +4371,7 @@ this command as @code{rev}.
@end table
@end ifclear
-@node Source Path
+@node Source Path, Machine Code, Search, Source
@section Specifying source directories
@cindex source path
@@ -3825,7 +4451,7 @@ directories you want in the source path. You can add all the
directories in one command.
@end enumerate
-@node Machine Code
+@node Machine Code, , Source Path, Source
@section Source and machine code
You can use the command @code{info line} to map source lines to program
@@ -3885,22 +4511,20 @@ surrounding this value. Two arguments specify a range of addresses
@end table
@ifclear H8EXCLUSIVE
-We can use @code{disassemble} to inspect the object code
-range shown in the last @code{info line} example (the example
-shows SPARC machine instructions):
-
+The following example shows the disassembly of a range of addresses of
+HP PA-RISC 2.0 code:
@smallexample
-(@value{GDBP}) disas 0x63e4 0x6404
-Dump of assembler code from 0x63e4 to 0x6404:
-0x63e4 <builtin_init+5340>: ble 0x63f8 <builtin_init+5360>
-0x63e8 <builtin_init+5344>: sethi %hi(0x4c00), %o0
-0x63ec <builtin_init+5348>: ld [%i1+4], %o0
-0x63f0 <builtin_init+5352>: b 0x63fc <builtin_init+5364>
-0x63f4 <builtin_init+5356>: ld [%o0+4], %o0
-0x63f8 <builtin_init+5360>: or %o0, 0x1a4, %o0
-0x63fc <builtin_init+5364>: call 0x9288 <path_search>
-0x6400 <builtin_init+5368>: nop
+(@value{GDBP}) disas 0x32c4 0x32e4
+Dump of assembler code from 0x32c4 to 0x32e4:
+0x32c4 <main+204>: addil 0,dp
+0x32c8 <main+208>: ldw 0x22c(sr0,r1),r26
+0x32cc <main+212>: ldil 0x3000,r31
+0x32d0 <main+216>: ble 0x3f8(sr4,r31)
+0x32d4 <main+220>: ldo 0(r31),rp
+0x32d8 <main+224>: addil -0x800,dp
+0x32dc <main+228>: ldo 0x588(r1),r26
+0x32e0 <main+232>: ldil 0x3000,r31
End of assembler dump.
@end smallexample
@end ifclear
@@ -3926,7 +4550,26 @@ to 0x808c:
@end smallexample
@end ifset
-@node Data
+Some architectures have more than one commonly-used set of instruction
+mnemonics or other syntax.
+
+@table @code
+@kindex set assembly-language
+@cindex assembly instructions
+@cindex instructions, assembly
+@cindex machine instructions
+@cindex listing machine instructions
+@item set assembly-language @var{instruction-set}
+Select the instruction set to use when disassembling the
+program via the @code{disassemble} or @code{x/i} commands.
+
+Currently this command is only defined for the Intel x86 family. You
+can set @var{instruction-set} to either @code{i386} or @code{i8086}.
+The default is @code{i386}.
+@end table
+
+
+@node Data, Languages, Source, Top
@chapter Examining Data
@cindex printing data
@@ -3986,9 +4629,10 @@ command rather than @code{print}. @xref{Symbols, ,Examining the Symbol Table}.
@ifclear HAVE-FLOAT
* Floating Point Hardware:: Floating point hardware
@end ifclear
+
@end menu
-@node Expressions
+@node Expressions, Variables, Data, Data
@section Expressions
@cindex expressions
@@ -4043,7 +4687,7 @@ a cast). This construct is allowed regardless of what kind of data is
normally supposed to reside at @var{addr}.
@end table
-@node Variables
+@node Variables, Arrays, Expressions, Data
@section Program variables
The most common kind of expression to use is the name of a variable
@@ -4054,7 +4698,7 @@ Variables in expressions are understood in the selected stack frame
@itemize @bullet
@item
-global (or static)
+global (or file-static)
@end itemize
@noindent or
@@ -4139,7 +4783,11 @@ also takes more than one machine instruction to destroy a stack frame;
after you begin stepping through that group of instructions, local
variable definitions may be gone.
-@node Arrays
+This may also happen when the compiler does significant optimizations.
+To be sure of always seeing accurate values, turn off all optimization
+when compiling.
+
+@node Arrays, Output Formats, Variables, Data
@section Artificial arrays
@cindex artificial array
@@ -4211,7 +4859,7 @@ p dtab[$i++]->fv
@dots{}
@end example
-@node Output Formats
+@node Output Formats, Memory, Arrays, Data
@section Output formats
@cindex formatted output
@@ -4280,7 +4928,7 @@ To reprint the last value in the value history with a different format,
you can use the @code{print} command with just a format and no
expression. For example, @samp{p/x} reprints the last value in hex.
-@node Memory
+@node Memory, Auto Display, Output Formats, Data
@section Examining memory
You can use the command @code{x} (for ``examine'') to examine memory in
@@ -4385,7 +5033,7 @@ If the @code{x} command has a repeat count, the address and contents saved
are from the last memory unit printed; this is not the same as the last
address printed if several units were printed on the last line of output.
-@node Auto Display
+@node Auto Display, Print Settings, Memory, Data
@section Automatic display
@cindex automatic display
@cindex display of expressions
@@ -4481,7 +5129,7 @@ there is no variable @code{last_char}---the display is disabled
automatically. The next time your program stops where @code{last_char}
is meaningful, you can enable the display expression once again.
-@node Print Settings
+@node Print Settings, Value History, Auto Display, Data
@section Print settings
@cindex format options
@@ -4777,7 +5425,12 @@ Allow @value{GDBN} to choose a decoding style by inspecting your program.
@item gnu
Decode based on the @sc{gnu} C++ compiler (@code{g++}) encoding algorithm.
+@ifclear HPPA
This is the default.
+@end ifclear
+
+@item hp
+Decode based on the HP ANSI C++ (@code{aCC}) encoding algorithm.
@item lucid
Decode based on the Lucid C++ compiler (@code{lcc}) encoding algorithm.
@@ -4788,9 +5441,8 @@ Decode using the algorithm in the @cite{C++ Annotated Reference Manual}.
debugging @code{cfront}-generated executables. @value{GDBN} would
require further enhancement to permit that.
-@item foo
-Show the list of formats.
@end table
+If you omit @var{style}, you will see a list of possible formats.
@kindex show demangle-style
@item show demangle-style
@@ -4823,10 +5475,15 @@ Do not print static members when displaying a C++ object.
@item show print static-members
Show whether C++ static members are printed, or not.
+@c These don't work with HP ANSI C++ yet.
@kindex set print vtbl
@item set print vtbl
@itemx set print vtbl on
Pretty print C++ virtual function tables. The default is off.
+@ifset HPPA
+(The @code{vtbl} commands do not work on programs compiled with the HP
+ANSI C++ compiler (@code{aCC}).)
+@end ifset
@item set print vtbl off
Do not pretty print C++ virtual function tables.
@@ -4837,7 +5494,7 @@ Show whether C++ virtual function tables are pretty printed, or not.
@end table
@end ifclear
-@node Value History
+@node Value History, Convenience Vars, Print Settings, Data
@section Value history
@cindex value history
@@ -4914,7 +5571,7 @@ values are available, @code{show values +} produces no display.
Pressing @key{RET} to repeat @code{show values @var{n}} has exactly the
same effect as @samp{show values +}.
-@node Convenience Vars
+@node Convenience Vars, Registers, Value History, Data
@section Convenience variables
@cindex convenience variables
@@ -4995,7 +5652,13 @@ The variable @code{$_exitcode} is automatically set to the exit code when
the program being debugged terminates.
@end table
-@node Registers
+@ifset HPPA
+If you refer to a function or variable name that begins with a dollar
+sign, @value{GDBN} searches for a user or system name first, before it
+searches for a convenience variable.
+@end ifset
+
+@node Registers, Floating Point Hardware, Convenience Vars, Data
@section Registers
@cindex registers
@@ -5117,7 +5780,7 @@ processors.
@end ifset
@ifclear HAVE-FLOAT
-@node Floating Point Hardware
+@node Floating Point Hardware, , Registers, Data
@section Floating point hardware
@cindex floating point
@@ -5135,7 +5798,7 @@ the ARM and x86 machines.
@end ifclear
@ifclear CONLY
-@node Languages
+@node Languages, Symbols, Data, Top
@chapter Using @value{GDBN} with Different Languages
@cindex languages
@@ -5166,7 +5829,7 @@ language}.
* Support:: Supported languages
@end menu
-@node Setting
+@node Setting, Show, Languages, Languages
@section Switching between source languages
There are two ways to control the working language---either have @value{GDBN}
@@ -5198,33 +5861,40 @@ program, and will display that source code, not the generated C code.
* Automatically:: Having @value{GDBN} infer the source language
@end menu
-@node Filenames
+@node Filenames, Manually, Setting, Setting
@subsection List of filename extensions and languages
If a source file name ends in one of the following extensions, then
@value{GDBN} infers that its language is the one indicated.
@table @file
-@ifset MOD2
-@item .mod
-Modula-2 source file
-@end ifset
@item .c
C source file
@item .C
@itemx .cc
-@itemx .cxx
-@itemx .cpp
@itemx .cp
+@itemx .cpp
+@itemx .cxx
@itemx .c++
C++ source file
+@item .f
+@itemx .F
+Fortran source file
+
+@ifclear HPPA
@item .ch
@itemx .c186
@itemx .c286
CHILL source file.
+@end ifclear
+
+@ifset MOD2
+@item .mod
+Modula-2 source file
+@end ifset
@item .s
@itemx .S
@@ -5232,7 +5902,10 @@ Assembler source file. This actually behaves almost like C, but
@value{GDBN} does not skip over function prologues when stepping.
@end table
-@node Manually
+In addition, you may set the language associated with a filename
+extension. @xref{Show, , Displaying the language}.
+
+@node Manually, Automatically, Filenames, Setting
@subsection Setting the working language
If you allow @value{GDBN} to set the language automatically,
@@ -5251,6 +5924,13 @@ a language, such as
@end ifset
For a list of the supported languages, type @samp{set language}.
+@ifclear MOD2
+Setting the language manually prevents @value{GDBN} from updating the
+working language automatically. For example, if you used the @code{c}
+setting to debug a C++ program, names might not be demangled properly,
+overload resolution would not work, user-defined operators might not be
+interpreted correctly, and so on.
+@end ifclear
@ifset MOD2
Setting the language manually prevents @value{GDBN} from updating the working
language automatically. This can lead to confusion if you try
@@ -5271,7 +5951,7 @@ printed would be the value of @code{a}. In Modula-2, this means to compare
@code{a} to the result of @code{b+c}, yielding a @code{BOOLEAN} value.
@end ifset
-@node Automatically
+@node Automatically, , Manually, Setting
@subsection Having @value{GDBN} infer the source language
To have @value{GDBN} set the working language automatically, use
@@ -5290,8 +5970,14 @@ written in one source language can be used by a main program written in
a different source language. Using @samp{set language auto} in this
case frees you from having to set the working language manually.
-@node Show
+@ifset MOD2
+@node Show, Checks, Setting, Languages
+@section Displaying the language
+@end ifset
+@ifclear MOD2
+@node Show, Support, Setting, Languages
@section Displaying the language
+@end ifclear
The following commands help you find out which language is the
working language, and also what language source files were written in.
@@ -5317,8 +6003,23 @@ Display the source language of this source file.
information listed here.
@end table
+In unusual circumstances, you may have source files with extensions
+not in the standard list. You can then set the extension associated
+with a language explicitly:
+
+@kindex set extension-language
+@kindex info extensions
+@table @code
+@item set extension-language @var{.ext} @var{language}
+Set source files with extension @var{.ext} to be assumed to be in
+the source language @var{language}.
+
+@item info extensions
+List all the filename extensions and the associated languages.
+@end table
+
@ifset MOD2
-@node Checks
+@node Checks, Support, Show, Languages
@section Type and range checking
@quotation
@@ -5351,7 +6052,7 @@ for the default settings of supported languages.
@cindex type checking
@cindex checks, type
-@node Type Checking
+@node Type Checking, Range Checking, Checks, Checks
@subsection An overview of type checking
Some languages, such as Modula-2, are strongly typed, meaning that the
@@ -5422,7 +6123,7 @@ is setting it automatically.
@cindex range checking
@cindex checks, range
-@node Range Checking
+@node Range Checking, , Type Checking, Checks
@subsection An overview of range checking
In some languages (such as Modula-2), it is an error to exceed the
@@ -5482,14 +6183,20 @@ being set automatically by @value{GDBN}.
@end table
@end ifset
-@node Support
+@ifset MOD2
+@node Support, , Checks, Languages
+@section Supported languages
+@end ifset
+@ifclear MOD2
+@node Support, , Show, Languages
@section Supported languages
+@end ifclear
@ifset MOD2
-@value{GDBN} 4 supports C, C++, and Modula-2.
+@value{GDBN} supports C, C++, Fortran, Chill, assembly, and Modula-2.
@end ifset
@ifclear MOD2
-@value{GDBN} 4 supports C, and C++.
+@value{GDBN} supports C, C++, Fortran, Chill, and assembly.
@end ifclear
Some @value{GDBN} features may be used in expressions regardless of the
language you use: the @value{GDBN} @code{@@} and @code{::} operators,
@@ -5511,50 +6218,70 @@ language reference or tutorial.
* Modula-2:: Modula-2
@end menu
-@node C
+@node C, Modula-2, , Support
@subsection C and C++
@cindex C and C++
@cindex expressions in C or C++
+@end ifset
Since C and C++ are so closely related, many features of @value{GDBN} apply
to both languages. Whenever this is the case, we discuss those languages
together.
-@end ifset
+
@ifclear MOD2
@c Cancel this below, under same condition, at end of this chapter!
@raisesections
@end ifclear
+@ifclear HPPA
@cindex C++
@kindex g++
@cindex @sc{gnu} C++
-The C++ debugging facilities are jointly implemented by the @sc{gnu} C++
+The C++ debugging facilities are jointly implemented by the C++
compiler and @value{GDBN}. Therefore, to debug your C++ code
-effectively, you must compile your C++ programs with the @sc{gnu} C++
-compiler, @code{g++}.
+effectively, you must compile your C++ programs with a supported
+C++ compiler, such as @sc{gnu} @code{g++}, or the HP ANSI C++
+compiler (@code{aCC}).
-For best results when debugging C++ programs, use the stabs debugging
+For best results when using @sc{gnu} C++, use the stabs debugging
format. You can select that format explicitly with the @code{g++}
command-line options @samp{-gstabs} or @samp{-gstabs+}. See
-@ref{Debugging Options,,Options for Debugging Your Program or @sc{gnu} CC,
-gcc.info, Using @sc{gnu} CC}, for more information.
+@ref{Debugging Options,,Options for Debugging Your Program or @sc{gnu}
+CC, gcc.info, Using @sc{gnu} CC}, for more information.
+@end ifclear
+@ifset HPPA
+@cindex C++
+@kindex g++
+@cindex @sc{gnu} C++
+You can use @value{GDBN} to debug C programs compiled with either the HP
+C compiler (@code{cc}) or the GNU C compiler (@code{gcc}), and to debug
+programs compiled with either the HP ANSI C++ compiler (@code{aCC}) or
+the @sc{gnu} C++ compiler (@code{g++}).
+
+If you compile with the @sc{gnu} C++ compiler, use the stabs debugging
+format for best results when debugging. You can select that format
+explicitly with the @code{g++} command-line options @samp{-gstabs} or
+@samp{-gstabs+}. See @ref{Debugging Options,,Options for Debugging Your
+Program or @sc{gnu} CC, gcc.info, Using @sc{gnu} CC}, for more
+information.
+@end ifset
@end ifclear
+
@ifset CONLY
-@node C
+@node C, Symbols, Data, Top
@chapter C Language Support
@cindex C language
@cindex expressions in C
Information specific to the C language is built into @value{GDBN} so that you
-can use C expressions while degugging. This also permits @value{GDBN} to
+can use C expressions while debugging. This also permits @value{GDBN} to
output values in a manner consistent with C conventions.
@menu
* C Operators:: C operators
-* C Constants:: C constants
-* Debugging C:: @value{GDBN} and C
@end menu
@end ifset
+
@ifclear CONLY
@menu
* C Operators:: C and C++ operators
@@ -5566,18 +6293,18 @@ output values in a manner consistent with C conventions.
@end ifset
* Debugging C:: @value{GDBN} and C
-* Debugging C plus plus:: Special features for C++
+* Debugging C plus plus:: @value{GDBN} features for C++
@end menu
@end ifclear
@ifclear CONLY
@cindex C and C++ operators
-@node C Operators
+@node C Operators, C Constants, , C
@subsubsection C and C++ operators
@end ifclear
@ifset CONLY
@cindex C operators
-@node C Operators
+@node C Operators, C Constants, C, C
@section C operators
@end ifset
@@ -5591,8 +6318,14 @@ For the purposes of C and C++, the following definitions hold:
@itemize @bullet
@item
+@ifclear HPPA
@emph{Integral types} include @code{int} with any of its storage-class
specifiers; @code{char}; and @code{enum}.
+@end ifclear
+@ifset HPPA
+@emph{Integral types} include @code{int} with any of its storage-class
+specifiers; @code{char}; @code{enum}; and, for C++, @code{bool}.
+@end ifset
@item
@emph{Floating-point types} include @code{float} and @code{double}.
@@ -5710,6 +6443,11 @@ Structure member, and pointer-to-structure member. For convenience,
pointer based on the stored type information.
Defined on @code{struct} and @code{union} data.
+@ifset HPPA
+@item .*@r{, }->*
+Dereferences of pointers to members.
+@end ifset
+
@item []
Array indexing. @code{@var{a}[@var{i}]} is defined as
@code{*(@var{a}+@var{i})}. Same precedence as @code{->}.
@@ -5735,17 +6473,33 @@ Same precedence as @code{::}, above.
@end ifclear
@end table
+@ifset HPPA
+If an operator is redefined in the user code, @value{GDBN} usually
+attempts to invoke the redefined version instead of using the operator's
+predefined meaning.
+@end ifset
+
@ifclear CONLY
-@cindex C and C++ constants
-@node C Constants
+@menu
+* C Constants::
+@end menu
+
+@ifset MOD2
+@node C Constants, Cplus expressions, C Operators, C
@subsubsection C and C++ constants
+@end ifset
+@ifclear MOD2
+@node C Constants, Cplus expressions, C Operators, Support
+@subsubsection C and C++ constants
+@end ifclear
+@cindex C and C++ constants
@value{GDBN} allows you to express the constants of C and C++ in the
following ways:
@end ifclear
@ifset CONLY
@cindex C constants
-@node C Constants
+@node C Constants, Debugging C, C Operators, C
@section C constants
@value{GDBN} allows you to express the constants of C in the
@@ -5797,13 +6551,29 @@ and @samp{@{&"hi", &"there", &"fred"@}} is a three-element array of pointers.
@end itemize
@ifclear CONLY
-@node Cplus expressions
+@menu
+* Cplus expressions::
+* C Defaults::
+@ifset MOD2
+* C Checks::
+@end ifset
+
+* Debugging C::
+@end menu
+
+@ifset MOD2
+@node Cplus expressions, C Defaults, C Constants, C
+@subsubsection C++ expressions
+@end ifset
+@ifclear MOD2
+@node Cplus expressions, C Defaults, C Constants, Support
@subsubsection C++ expressions
+@end ifclear
@cindex expressions in C++
-@value{GDBN} expression handling has a number of extensions to
-interpret a significant subset of C++ expressions.
+@value{GDBN} expression handling can interpret most C++ expressions.
+@ifclear HPPA
@cindex C++ support, not in @sc{coff}
@cindex @sc{coff} versus C++
@cindex C++ and object formats
@@ -5816,18 +6586,18 @@ interpret a significant subset of C++ expressions.
@c FIXME!! GDB may eventually be able to debug C++ using DWARF; check
@c periodically whether this has happened...
@quotation
-@emph{Warning:} @value{GDBN} can only debug C++ code if you compile with
-the @sc{gnu} C++ compiler. Moreover, C++ debugging depends on the use of
+@emph{Warning:} @value{GDBN} can only debug C++ code if you use the
+proper compiler. Typically, C++ debugging depends on the use of
additional debugging information in the symbol table, and thus requires
-special support. @value{GDBN} has this support @emph{only} with the
-stabs debug format. In particular, if your compiler generates a.out,
-MIPS @sc{ecoff}, RS/6000 @sc{xcoff}, or @sc{elf} with stabs extensions
-to the symbol table, these facilities are all available. (With @sc{gnu} CC,
+special support. In particular, if your compiler generates a.out, MIPS
+@sc{ecoff}, RS/6000 @sc{xcoff}, or @sc{elf} with stabs extensions to the
+symbol table, these facilities are all available. (With @sc{gnu} CC,
you can use the @samp{-gstabs} option to request stabs debugging
extensions explicitly.) Where the object code format is standard
@sc{coff} or @sc{dwarf} in @sc{elf}, on the other hand, most of the C++
support in @value{GDBN} does @emph{not} work.
@end quotation
+@end ifclear
@enumerate
@@ -5847,6 +6617,7 @@ expressions have the same namespace available as the member function;
that is, @value{GDBN} allows implicit references to the class instance
pointer @code{this} following the same rules as C++.
+@ifclear HPPA
@cindex call overloaded functions
@cindex type conversions in C++
@item
@@ -5855,6 +6626,38 @@ call to the right definition, with one restriction---you must use
arguments of the type required by the function that you want to call.
@value{GDBN} does not perform conversions requiring constructors or
user-defined type operators.
+@end ifclear
+@ifset HPPA
+@cindex call overloaded functions
+@cindex overloaded functions
+@cindex type conversions in C++
+@item
+You can call overloaded functions; @value{GDBN} resolves the function
+call to the right definition, with some restrictions. GDB does not
+perform overload resolution involving user-defined type conversions,
+calls to constructors, or instantiations of templates that do not exist
+in the program. It also cannot handle ellipsis argument lists or
+default arguments.
+
+It does perform integral conversions and promotions, floating-point
+promotions, arithmetic conversions, pointer conversions, conversions of
+class objects to base classes, and standard conversions such as those of
+functions or arrays to pointers; it requires an exact match on the
+number of function arguments.
+
+Overload resolution is always performed, unless you have specified
+@code{set overload-resolution off}. @xref{Debugging C plus plus,
+,@value{GDBN} features for C++}.
+
+You must specify@code{set overload-resolution off} in order to use an
+explicit function signature to call an overloaded function, as in
+@smallexample
+p 'foo(char,int)'('x', 13)
+@end smallexample
+The @value{GDBN} command-completion facility can simplify this;
+@pxref{Completion, ,Command completion}.
+
+@end ifset
@cindex reference declarations
@item
@@ -5878,27 +6681,41 @@ resolving name scope by reference to source files, in both C and C++
debugging (@pxref{Variables, ,Program variables}).
@end enumerate
-@node C Defaults
+@ifset HPPA
+In addition, @value{GDBN} supports calling virtual functions correctly,
+printing out virtual bases of objects, calling functions in a base
+subobject, casting objects, and invoking user-defined operators.
+@end ifset
+
+@ifset MOD2
+@node C Defaults, C Checks, Cplus expressions, C
@subsubsection C and C++ defaults
+@end ifset
+@ifclear MOD2
+@node C Defaults, Debugging C, Cplus expressions, Support
+@subsubsection C and C++ defaults
+@end ifclear
@cindex C and C++ defaults
+@ifclear HPPA
If you allow @value{GDBN} to set type and range checking automatically, they
both default to @code{off} whenever the working language changes to
C or C++. This happens regardless of whether you or @value{GDBN}
selects the working language.
+@end ifclear
-If you allow @value{GDBN} to set the language automatically, it recognizes
-source files whose names end with @file{.c}, @file{.C}, or @file{.cc}, and
-when @value{GDBN} enters code compiled from one of these files,
-it sets the working language to C or C++.
-@xref{Automatically, ,Having @value{GDBN} infer the source language}, for
-further details.
+If you allow @value{GDBN} to set the language automatically, it
+recognizes source files whose names end with @file{.c}, @file{.C}, or
+@file{.cc}, etc, and when @value{GDBN} enters code compiled from one of
+these files, it sets the working language to C or C++.
+@xref{Automatically, ,Having @value{GDBN} infer the source language},
+for further details.
@ifset MOD2
@c Type checking is (a) primarily motivated by Modula-2, and (b)
@c unimplemented. If (b) changes, it might make sense to let this node
@c appear even if Mod-2 does not, but meanwhile ignore it. roland 16jul93.
-@node C Checks
+@node C Checks, Debugging C, C Defaults, C Constants
@subsubsection C and C++ type and range checks
@cindex C and C++ checks
@@ -5932,11 +6749,17 @@ that is not itself an array.
@end ifclear
@ifclear CONLY
-@node Debugging C
+@ifset MOD2
+@node Debugging C, Debugging C plus plus, C Checks, C
+@subsubsection @value{GDBN} and C
+@end ifset
+@ifclear MOD2
+@node Debugging C, Debugging C plus plus, C Defaults, Support
@subsubsection @value{GDBN} and C
@end ifclear
+@end ifclear
@ifset CONLY
-@node Debugging C
+@node Debugging C, , C Constants, C
@section @value{GDBN} and C
@end ifset
@@ -5954,8 +6777,18 @@ with pointers and a memory allocation function. @xref{Expressions,
,Expressions}.
@ifclear CONLY
-@node Debugging C plus plus
+@menu
+* Debugging C plus plus::
+@end menu
+
+@ifset MOD2
+@node Debugging C plus plus, , Debugging C, C
+@subsubsection @value{GDBN} features for C++
+@end ifset
+@ifclear MOD2
+@node Debugging C plus plus, , Debugging C, Support
@subsubsection @value{GDBN} features for C++
+@end ifclear
@cindex commands for C++
Some @value{GDBN} commands are particularly useful with C++, and some are
@@ -5976,10 +6809,10 @@ classes.
@xref{Set Breaks, ,Setting breakpoints}.
@cindex C++ exception handling
-@item catch @var{exceptions}
-@itemx info catch
-Debug C++ exception handling using these commands. @xref{Exception
-Handling, ,Breakpoints and exceptions}.
+@item catch throw
+@itemx catch catch
+Debug C++ exception handling using these commands. @xref{Set
+Catchpoints, , Setting catchpoints}.
@cindex inheritance
@item ptype @var{typename}
@@ -6005,6 +6838,29 @@ Choose whether to print derived (actual) or declared types of objects.
@itemx show print vtbl
Control the format for printing virtual function tables.
@xref{Print Settings, ,Print settings}.
+@ifset HPPA
+(The @code{vtbl} commands do not work on programs compiled with the HP
+ANSI C++ compiler (@code{aCC}).)
+
+@kindex set overload-resolution
+@cindex overloaded functions
+@item set overload-resolution on
+Enable overload resolution for C++ expression evaluation. The default
+is on. For overloaded functions, @value{GDBN} evaluates the arguments
+and searches for a function whose signature matches the argument types,
+using the standard C++ conversion rules (@pxref{Cplus expressions, ,C++
+expressions} for details). If it cannot find a match, it emits a
+message.
+
+@item set overload-resolution off
+Disable overload resolution for C++ expression evaluation. For
+overloaded functions that are not class member functions, @value{GDBN}
+chooses the first function of the specified name that it finds in the
+symbol table, whether or not its arguments are of the correct type. For
+overloaded functions that are class member functions, @value{GDBN}
+searches for a function whose signature @emph{exactly} matches the
+argument types.
+@end ifset
@item @r{Overloaded symbol names}
You can specify a particular definition of an overloaded symbol, using
@@ -6020,7 +6876,7 @@ available choices, or to finish the type list for you.
@end ifclear
@ifset MOD2
-@node Modula-2
+@node Modula-2, ,C , Support
@subsection Modula-2
@cindex Modula-2
@@ -6034,7 +6890,7 @@ table.
@cindex expressions in Modula-2
@menu
* M2 Operators:: Built-in operators
-* Built-In Func/Proc:: Built-in functions and procedures
+* Built-In Func/Proc:: Built-in functions and procedures
* M2 Constants:: Modula-2 constants
* M2 Defaults:: Default settings for Modula-2
* Deviations:: Deviations from standard Modula-2
@@ -6043,7 +6899,7 @@ table.
* GDB/M2:: @value{GDBN} and Modula-2
@end menu
-@node M2 Operators
+@node M2 Operators, Built-In Func/Proc, Modula-2, Modula-2
@subsubsection Operators
@cindex Modula-2 operators
@@ -6167,7 +7023,7 @@ treats the use of the operator @code{IN}, or the use of operators
@end quotation
@cindex Modula-2 built-ins
-@node Built-In Func/Proc
+@node Built-In Func/Proc, M2 Constants, M2 Operators, Modula-2
@subsubsection Built-in functions and procedures
Modula-2 also makes available several built-in procedures and functions.
@@ -6279,7 +7135,7 @@ an error.
@end quotation
@cindex Modula-2 constants
-@node M2 Constants
+@node M2 Constants, M2 Defaults, Built-In Func/Proc, Modula-2
@subsubsection Constants
@value{GDBN} allows you to express the constants of Modula-2 in the following
@@ -6328,7 +7184,7 @@ Pointer constants consist of integral values only.
Set constants are not yet supported.
@end itemize
-@node M2 Defaults
+@node M2 Defaults, Deviations, M2 Constants, Modula-2
@subsubsection Modula-2 defaults
@cindex Modula-2 defaults
@@ -6342,7 +7198,7 @@ code compiled from a file whose name ends with @file{.mod} sets the
working language to Modula-2. @xref{Automatically, ,Having @value{GDBN} set
the language automatically}, for further details.
-@node Deviations
+@node Deviations, M2 Checks, M2 Defaults, Modula-2
@subsubsection Deviations from standard Modula-2
@cindex Modula-2, deviations from
@@ -6372,7 +7228,7 @@ argument.
All built-in procedures both modify @emph{and} return their argument.
@end itemize
-@node M2 Checks
+@node M2 Checks, M2 Scope, Deviations, Modula-2
@subsubsection Modula-2 type and range checks
@cindex Modula-2 checks
@@ -6400,7 +7256,7 @@ whose types are not equivalent is an error.
Range checking is done on all mathematical operations, assignment, array
index bounds, and all built-in functions and procedures.
-@node M2 Scope
+@node M2 Scope, GDB/M2, M2 Checks, Modula-2
@subsubsection The scope operators @code{::} and @code{.}
@cindex scope
@kindex .
@@ -6440,7 +7296,7 @@ an error if the identifier @var{id} was not imported from definition
module @var{module}, or if @var{id} is not an identifier in
@var{module}.
-@node GDB/M2
+@node GDB/M2, , M2 Scope, Modula-2
@subsubsection @value{GDBN} and Modula-2
Some @value{GDBN} commands have little use when debugging Modula-2 programs.
@@ -6463,7 +7319,7 @@ interpreted as the beginning of a comment. Use @code{<>} instead.
@end ifset
@end ifclear
-@node Symbols
+@node Symbols, Altering, Languages, Top
@chapter Examining the Symbol Table
The commands described in this section allow you to inquire about the
@@ -6617,6 +7473,7 @@ from the @code{ptype} command can be overwhelming and hard to use. The
which match the regular-expression @var{regexp}.
@end ignore
+@ifclear HPPA
@cindex reloading symbols
Some systems allow individual object files that make up your program to
be replaced without stopping and restarting your program.
@@ -6645,6 +7502,31 @@ different directories or libraries) with the same name.
@item show symbol-reloading
Show the current @code{on} or @code{off} setting.
@end table
+@end ifclear
+
+@ifset HPPA
+@kindex set opaque-type-resolution
+@item set opaque-type-resolution on
+Tell @value{GDBN} to resolve opaque types. An opaque type is a type
+declared as a pointer to a @code{struct}, @code{class}, or
+@code{union}---for example, @code{struct MyType *}---that is used in one
+source file although the full declaration of @code{struct MyType} is in
+another source file. The default is on.
+
+A change in the setting of this subcommand will not take effect until
+the next time symbols for a file are loaded.
+
+@item set opaque-type-resolution off
+Tell @value{GDBN} not to resolve opaque types. In this case, the type
+is printed as follows:
+@smallexample
+@{<no data fields>@}
+@end smallexample
+
+@kindex show opaque-type-resolution
+@item show opaque-type-resolution
+Show whether opaque types are resolved or not.
+@end ifset
@kindex maint print symbols
@cindex symbol dump
@@ -6669,7 +7551,7 @@ required for each object file from which @value{GDBN} has read some symbols.
@value{GDBN} reads symbols (in the description of @code{symbol-file}).
@end table
-@node Altering
+@node Altering, GDB Files, Symbols, Top
@chapter Altering Execution
Once you think you have found an error in your program, you might want to
@@ -6700,7 +7582,7 @@ at a different address, or even return prematurely from a function.
* Patching:: Patching your program
@end menu
-@node Assignment
+@node Assignment, Jumping, Altering, Altering
@section Assignment to variables
@cindex assignment
@@ -6728,13 +7610,14 @@ really the same as @code{print} except that the expression's value is
not printed and is not put in the value history (@pxref{Value History,
,Value history}). The expression is evaluated only for its effects.
+@ifclear HPPA
If the beginning of the argument string of the @code{set} command
appears identical to a @code{set} subcommand, use the @code{set
variable} command instead of just @code{set}. This command is identical
-to @code{set} except for its lack of subcommands. For example, if
-your program has a variable @code{width}, you get
-an error if you try to set a new value with just @samp{set width=13},
-because @value{GDBN} has the command @code{set width}:
+to @code{set} except for its lack of subcommands. For example, if your
+program has a variable @code{width}, you get an error if you try to set
+a new value with just @samp{set width=13}, because @value{GDBN} has the
+command @code{set width}:
@example
(@value{GDBP}) whatis width
@@ -6752,6 +7635,43 @@ order to actually set the program's variable @code{width}, use
@example
(@value{GDBP}) set var width=47
@end example
+@end ifclear
+@ifset HPPA
+Because the @code{set} command has many subcommands that can conflict
+with the names of program variables, it is a good idea to use the
+@code{set variable} command instead of just @code{set}. For example, if
+your program has a variable @code{g}, you run into problems if you try
+to set a new value with just @samp{set g=4}, because @value{GDBN} has
+the command @code{set gnutarget}, abbreviated @code{set g}:
+
+@example
+@group
+(@value{GDBP}) whatis g
+type = double
+(@value{GDBP}) p g
+$1 = 1
+(@value{GDBP}) set g=4
+(gdb) p g
+$2 = 1
+(@value{GDBP}) r
+The program being debugged has been started already.
+Start it from the beginning? (y or n) y
+Starting program: /home/smith/cc_progs/a.out
+"/home/smith/cc_progs/a.out": can't open to read symbols: Invalid bfd target.
+(@value{GDBP}) show g
+The current BFD target is "=4".
+@end group
+@end example
+
+@noindent
+The program variable @code{g} did not change, and you silently set the
+@code{gnutarget} to an invalid value. In order to set the variable
+@code{g}, use
+
+@example
+(@value{GDBP}) set var g=4
+@end example
+@end ifset
@value{GDBN} allows more implicit conversions in assignments than C; you can
freely store an integer value into a pointer variable or vice versa,
@@ -6773,7 +7693,7 @@ set @{int@}0x83040 = 4
@noindent
stores the value 4 into that memory location.
-@node Jumping
+@node Jumping, Signaling, Assignment, Altering
@section Continuing at a different address
Ordinarily, when you continue your program, you do so at the place where
@@ -6786,7 +7706,9 @@ an address of your own choosing, with the following commands:
Resume execution at line @var{linespec}. Execution stops again
immediately if there is a breakpoint there. @xref{List, ,Printing
source lines}, for a description of the different forms of
-@var{linespec}.
+@var{linespec}. It is common practice to use the @code{tbreak} command
+in conjunction with @code{jump}. @xref{Set Breaks, ,Setting
+breakpoints}.
The @code{jump} command does not change the current stack frame, or
the stack pointer, or the contents of any memory location or any
@@ -6802,6 +7724,8 @@ well acquainted with the machine-language code of your program.
Resume execution at the instruction at address @var{address}.
@end table
+@ifclear HPPA
+@c Doesn't work on HP-UX; have to set $pcoqh and $pcoqt.
You can get much the same effect as the @code{jump} command by storing a
new value into the register @code{$pc}. The difference is that this
does not start your program running; it only changes the address of where it
@@ -6815,14 +7739,16 @@ set $pc = 0x485
makes the next @code{continue} command or stepping command execute at
address @code{0x485}, rather than at the address where your program stopped.
@xref{Continuing and Stepping, ,Continuing and stepping}.
+@end ifclear
-The most common occasion to use the @code{jump} command is to back up--
-perhaps with more breakpoints set--over a portion of a program that has
-already executed, in order to examine its execution in more detail.
+The most common occasion to use the @code{jump} command is to back
+up---perhaps with more breakpoints set---over a portion of a program
+that has already executed, in order to examine its execution in more
+detail.
@ifclear BARETARGET
@c @group
-@node Signaling
+@node Signaling, Returning, Jumping, Altering
@section Giving your program a signal
@table @code
@@ -6852,7 +7778,7 @@ passes the signal directly to your program.
@end ifclear
-@node Returning
+@node Returning, Calling, Signaling, Altering
@section Returning from a function
@table @code
@@ -6883,7 +7809,7 @@ returned. In contrast, the @code{finish} command (@pxref{Continuing
and Stepping, ,Continuing and stepping}) resumes execution until the
selected stack frame returns naturally.
-@node Calling
+@node Calling, Patching, Returning, Altering
@section Calling program functions
@cindex calling functions
@@ -6899,13 +7825,15 @@ execute a function from your program, but without cluttering the output
with @code{void} returned values. If the result is not void, it
is printed and saved in the value history.
-A new user-controlled variable, @var{call_scratch_address}, specifies
-the location of a scratch area to be used when @value{GDBN} calls a
-function in the target. This is necessary because the usual method
-of putting the scratch area on the stack does not work in systems that
-have separate instruction and data spaces.
+@ifclear HPPA
+For the A29K, a user-controlled variable @code{call_scratch_address},
+specifies the location of a scratch area to be used when @value{GDBN}
+calls a function in the target. This is necessary because the usual
+method of putting the scratch area on the stack does not work in systems
+that have separate instruction and data spaces.
+@end ifclear
-@node Patching
+@node Patching, , Calling, Altering
@section Patching programs
@cindex patching binaries
@cindex writing into executables
@@ -6955,7 +7883,7 @@ and core files
are opened for writing as well as reading.
@end table
-@node GDB Files
+@node GDB Files, Targets, Altering, Top
@chapter @value{GDBN} Files
@value{GDBN} needs to know the file name of the program to be debugged, both in
@@ -6970,7 +7898,7 @@ the name of the core dump file.
* Symbol Errors:: Errors reading symbol files
@end menu
-@node Files
+@node Files, Symbol Errors, GDB Files, GDB Files
@section Commands to specify files
@cindex symbol table
@@ -7005,6 +7933,7 @@ directories to search, just as the shell does when looking for a program
to run. You can change the value of this variable, for both @value{GDBN}
and your program, using the @code{path} command.
+@ifclear HPPA
On systems with memory-mapped files, an auxiliary file
@file{@var{filename}.syms} may hold symbol table information for
@var{filename}. If so, @value{GDBN} maps in the symbol table from
@@ -7013,6 +7942,7 @@ descriptions of the file options @samp{-mapped} and @samp{-readnow}
(available on the command line, and with the commands @code{file},
@code{symbol-file}, or @code{add-symbol-file}, described below),
for more information.
+@end ifclear
@item file
@code{file} with no argument makes @value{GDBN} discard any information it
@@ -7046,26 +7976,32 @@ executing it once.
When @value{GDBN} is configured for a particular environment, it
understands debugging information in whatever format is the standard
generated for that environment; you may use either a @sc{gnu} compiler, or
-other compilers that adhere to the local conventions. Best results are
-usually obtained from @sc{gnu} compilers; for example, using @code{@value{GCC}}
-you can generate debugging information for optimized code.
-
-On some kinds of object files, the @code{symbol-file} command does not
-normally read the symbol table in full right away. Instead, it scans
-the symbol table quickly to find which source files and which symbols
-are present. The details are read later, one source file at a time,
-as they are needed.
-
-The purpose of this two-stage reading strategy is to make @value{GDBN} start up
-faster. For the most part, it is invisible except for occasional
-pauses while the symbol table details for a particular source file are
-being read. (The @code{set verbose} command can turn these pauses
-into messages if desired. @xref{Messages/Warnings, ,Optional warnings
-and messages}.)
+other compilers that adhere to the local conventions.
+@ifclear HPPA
+Best results are usually obtained from @sc{gnu} compilers; for example,
+using @code{@value{GCC}} you can generate debugging information for
+optimized code.
+@end ifclear
+
+For most kinds of object files, with the exception of old SVR3 systems
+using COFF, the @code{symbol-file} command does not normally read the
+symbol table in full right away. Instead, it scans the symbol table
+quickly to find which source files and which symbols are present. The
+details are read later, one source file at a time, as they are needed.
+The purpose of this two-stage reading strategy is to make @value{GDBN}
+start up faster. For the most part, it is invisible except for
+occasional pauses while the symbol table details for a particular source
+file are being read. (The @code{set verbose} command can turn these
+pauses into messages if desired. @xref{Messages/Warnings, ,Optional
+warnings and messages}.)
+
+@ifclear HPPA
We have not implemented the two-stage strategy for COFF yet. When the
symbol table is stored in COFF format, @code{symbol-file} reads the
-symbol table data in full right away.
+symbol table data in full right away. Note that ``stabs-in-COFF''
+still does the two-stage strategy, since the debug info is actually
+in stabs format.
@kindex readnow
@cindex reading symbols immediately
@@ -7079,8 +8015,10 @@ You can override the @value{GDBN} two-stage strategy for reading symbol
tables by using the @samp{-readnow} option with any of the commands that
load symbol table information, if you want to be sure @value{GDBN} has the
entire symbol table available.
+@end ifclear
@ifclear BARETARGET
+@ifclear HPPA
If memory-mapped files are available on your system through the
@code{mmap} system call, you can use another option, @samp{-mapped}, to
cause @value{GDBN} to write the symbols for your program into a reusable
@@ -7102,6 +8040,7 @@ needed.
The @file{.syms} file is specific to the host machine where you run
@value{GDBN}. It holds an exact image of the internal @value{GDBN}
symbol table. It cannot be shared across multiple host platforms.
+@end ifclear
@c FIXME: for now no mention of directories, since this seems to be in
@c flux. 13mar1992 status is that in theory GDB would look either in
@@ -7129,54 +8068,8 @@ program is running. To do this, use the @code{kill} command
(@pxref{Kill Process, ,Killing the child process}).
@end ifclear
-@kindex load @var{filename}
-@item load @var{filename}
-@ifset GENERIC
-Depending on what remote debugging facilities are configured into
-@value{GDBN}, the @code{load} command may be available. Where it exists, it
-is meant to make @var{filename} (an executable) available for debugging
-on the remote system---by downloading, or dynamic linking, for example.
-@code{load} also records the @var{filename} symbol table in @value{GDBN}, like
-the @code{add-symbol-file} command.
-
-If your @value{GDBN} does not have a @code{load} command, attempting to
-execute it gets the error message ``@code{You can't do that when your
-target is @dots{}}''
-@end ifset
-
-The file is loaded at whatever address is specified in the executable.
-For some object file formats, you can specify the load address when you
-link the program; for other formats, like a.out, the object file format
-specifies a fixed address.
-@c FIXME! This would be a good place for an xref to the GNU linker doc.
-
-@ifset VXWORKS
-On VxWorks, @code{load} links @var{filename} dynamically on the
-current target system as well as adding its symbols in @value{GDBN}.
-@end ifset
-
-@ifset I960
-@cindex download to Nindy-960
-With the Nindy interface to an Intel 960 board, @code{load}
-downloads @var{filename} to the 960 as well as adding its symbols in
-@value{GDBN}.
-@end ifset
-
-@ifset H8
-@cindex download to H8/300 or H8/500
-@cindex H8/300 or H8/500 download
-@cindex download to Hitachi SH
-@cindex Hitachi SH download
-When you select remote debugging to a Hitachi SH, H8/300, or H8/500 board
-(@pxref{Hitachi Remote,,@value{GDBN} and Hitachi Microprocessors}),
-the @code{load} command downloads your program to the Hitachi board and also
-opens it as the current executable target for @value{GDBN} on your host
-(like the @code{file} command).
-@end ifset
-
-@code{load} does not repeat if you press @key{RET} again after using it.
-
@ifclear BARETARGET
+@ifclear HPPA
@kindex add-symbol-file
@cindex dynamic linking
@item add-symbol-file @var{filename} @var{address}
@@ -7207,7 +8100,9 @@ operating system for the Motorola 88k. @value{GDBN} automatically looks for
shared libraries, however if @value{GDBN} does not find yours, you can run
@code{add-shared-symbol-file}. It takes no arguments.
@end ifclear
+@end ifclear
+@ifclear HPPA
@kindex section
@item section
The @code{section} command changes the base address of section SECTION of
@@ -7216,6 +8111,7 @@ section addresses, (such as in the a.out format), or when the addresses
specified in the file itself are wrong. Each section must be changed
separately. The ``info files'' command lists all the sections and their
addresses.
+@end ifclear
@kindex info files
@kindex info target
@@ -7241,12 +8137,23 @@ name and remembers it that way.
@ifclear BARETARGET
@cindex shared libraries
-@value{GDBN} supports SunOS, SVr4, Irix 5, and IBM RS/6000 shared libraries.
+@ifclear HPPA
+@c added HP-UX -- Kim (HP writer)
+@value{GDBN} supports HP-UX, SunOS, SVr4, Irix 5, and IBM RS/6000 shared
+libraries.
+@end ifclear
+@ifset HPPA
+@value{GDBN} supports HP-UX shared libraries.
+@end ifset
@value{GDBN} automatically loads symbol definitions from shared libraries
when you use the @code{run} command, or when you examine a core file.
(Before you issue the @code{run} command, @value{GDBN} does not understand
references to a function in a shared library, however---unless you are
debugging a core file).
+@ifset HPPA
+If the program loads a library explicitly, @value{GDBN} automatically
+loads the symbols at the time of the @code{shl_load} call.
+@end ifset
@c FIXME: some @value{GDBN} release may permit some refs to undef
@c FIXME...symbols---eg in a break cmd---assuming they are from a shared
@c FIXME...lib; check this from time to time when updating manual
@@ -7270,9 +8177,39 @@ required by your program for a core file or after typing @code{run}. If
@var{regex} is omitted all shared libraries required by your program are
loaded.
@end table
+
+@ifset HPPA
+@value{GDBN} detects the loading of a shared library and automatically
+reads in symbols from the newly loaded library, up to a threshold that
+is initially set but that you can modify if you wish.
+
+Beyond that threshold, symbols from shared libraries must be explicitly
+loaded. To load these symbols, use the command @code{sharedlibrary}
+@var{filename}. The base address of the shared library is determined
+automatically by @value{GDBN} and need not be specified.
+
+To display or set the threshold, use the commands:
+
+@table @code
+@kindex set auto-solib-add
+@item set auto-solib-add @var{threshold}
+Set the autoloading size threshold, in megabytes. If @var{threshold} is
+nonzero, symbols from all shared object libraries will be loaded
+automatically when the inferior begins execution or when the dynamic
+linker informs @value{GDBN} that a new library has been loaded, until
+the symbol table of the program and libraries exceeds this threshold.
+Otherwise, symbols must be loaded manually, using the
+@code{sharedlibrary} command. The default threshold is 100 megabytes.
+
+@kindex show auto-solib-add
+@item show auto-solib-add
+Display the current autoloading size threshold, in megabytes.
+@end table
+@end ifset
+
@end ifclear
-@node Symbol Errors
+@node Symbol Errors, , Files, GDB Files
@section Errors reading symbol files
While reading a symbol file, @value{GDBN} occasionally encounters problems,
@@ -7368,12 +8305,13 @@ for it.
@value{GDBN} could not parse a type specification output by the compiler.
@end table
-@node Targets
+@node Targets, Controlling GDB, GDB Files, Top
@chapter Specifying a Debugging Target
@cindex debugging target
@kindex target
A @dfn{target} is the execution environment occupied by your program.
+@ifclear HPPA
@ifclear BARETARGET
Often, @value{GDBN} runs in the same host environment as your program; in
that case, the debugging target is specified as a side effect when you
@@ -7382,6 +8320,29 @@ flexibility---for example, running @value{GDBN} on a physically separate
host, or controlling a standalone system over a serial port or a
realtime system over a TCP/IP connection---you
@end ifclear
+@end ifclear
+@ifset HPPA
+On HP-UX systems, @value{GDBN} has been configured to support debugging
+of processes running on the PA-RISC architecture. This means that the
+only possible targets are:
+
+@itemize @bullet
+@item
+An executable that has been compiled and linked to run on HP-UX
+
+@item
+A live HP-UX process, either started by @value{GDBN} (with the
+@code{run} command) or started outside of @value{GDBN} and attached to
+(with the @code{attach} command)
+
+@item
+A core file generated by an HP-UX process that previously aborted
+execution
+@end itemize
+
+@value{GDBN} on HP-UX has not been configured to support remote
+debugging, or to support programs running on other platforms. You
+@end ifset
@ifset BARETARGET
You
@end ifset
@@ -7392,10 +8353,14 @@ targets}).
@menu
* Active Targets:: Active targets
* Target Commands:: Commands for managing targets
+@ifset REMOTESTUB
+* Byte Order:: Choosing target byte order
* Remote:: Remote debugging
+@end ifset
+
@end menu
-@node Active Targets
+@node Active Targets, Target Commands, Targets, Targets
@section Active targets
@cindex stacking targets
@cindex active targets
@@ -7441,7 +8406,7 @@ the @code{attach} command (@pxref{Attach, ,Debugging an
already-running process}).
@end ifclear
-@node Target Commands
+@node Target Commands, Byte Order, Active Targets, Targets
@section Commands for managing targets
@table @code
@@ -7475,14 +8440,14 @@ select it.
@kindex set gnutarget
@item set gnutarget @var{args}
-@value{GDBN}uses its own library BFD to read your files. @value{GDBN}
+@value{GDBN} uses its own library BFD to read your files. @value{GDBN}
knows whether it is reading an @dfn{executable},
-a @dfn{core}, or a @dfn{.o} file, however you can specify the file format
+a @dfn{core}, or a @dfn{.o} file; however, you can specify the file format
with the @code{set gnutarget} command. Unlike most @code{target} commands,
with @code{gnutarget} the @code{target} refers to a program, not a machine.
@emph{Warning:} To specify a file format with @code{set gnutarget},
-you must know the actual BFD name.
+you must know the actual BFD name.
@noindent @xref{Files, , Commands to specify files}.
@@ -7490,12 +8455,17 @@ you must know the actual BFD name.
@item show gnutarget
Use the @code{show gnutarget} command to display what file format
@code{gnutarget} is set to read. If you have not set @code{gnutarget},
-@value{GDBN} will determine the file format for each file automatically
-and @code{show gnutarget} displays @code{The current BDF target is "auto"}.
+@value{GDBN} will determine the file format for each file automatically,
+and @code{show gnutarget} displays @samp{The current BDF target is "auto"}.
@end table
+@ifclear HPPA
Here are some common targets (available, or not, depending on the GDB
configuration):
+@end ifclear
+@ifset HPPA
+These are the valid targets on HP-UX systems:
+@end ifset
@table @code
@kindex target exec
@@ -7510,7 +8480,6 @@ A core dump file. @samp{target core @var{filename}} is the same as
@samp{core-file @var{filename}}.
@end ifclear
-@ifset REMOTESTUB
@kindex target remote
@item target remote @var{dev}
Remote serial target in GDB-specific protocol. The argument @var{dev}
@@ -7519,20 +8488,27 @@ specifies what serial device to use for the connection (e.g.
now supports the @code{load} command. This is only useful if you have
some other way of getting the stub to the target system, and you can put
it somewhere in memory where it won't get clobbered by the download.
-@end ifset
-@ifset SIMS
+@ifclear HPPA
@kindex target sim
@item target sim
CPU simulator. @xref{Simulator,,Simulated CPU Target}.
-@end ifset
+@end ifclear
+@end table
-@ifset AMD29K
-@kindex target udi
-@item target udi @var{keyword}
-Remote AMD29K target, using the AMD UDI protocol. The @var{keyword}
-argument specifies which 29K board or simulator to use. @xref{UDI29K
-Remote,,The UDI protocol for AMD29K}.
+The following targets are all CPU-specific, and only available for
+specific configurations.
+@c should organize by CPU
+
+@table @code
+
+@kindex target abug
+@item target abug @var{dev}
+ABug ROM monitor for M68K.
+
+@kindex target adapt
+@item target adapt @var{dev}
+Adapt monitor for A29K.
@kindex target amd-eb
@item target amd-eb @var{dev} @var{speed} @var{PROG}
@@ -7543,27 +8519,127 @@ Remote PC-resident AMD EB29K board, attached over serial lines.
name of the program to be debugged, as it appears to DOS on the PC.
@xref{EB29K Remote, ,The EBMON protocol for AMD29K}.
-@end ifset
-@ifset H8
+@kindex target array
+@item target array @var{dev}
+Array Tech LSI33K RAID controller board.
+
+@kindex target bug
+@item target bug @var{dev}
+BUG monitor, running on a MVME187 (m88k) board.
+
+@kindex target cpu32bug
+@item target cpu32bug @var{dev}
+CPU32BUG monitor, running on a CPU32 (M68K) board.
+
+@kindex target dbug
+@item target dbug @var{dev}
+dBUG ROM monitor for Motorola ColdFire.
+
+@kindex target ddb
+@item target ddb @var{dev}
+NEC's DDB monitor for Mips Vr4300.
+
+@kindex target dink32
+@item target dink32 @var{dev}
+DINK32 ROM monitor for PowerPC.
+
+@kindex target e7000
+@item target e7000 @var{dev}
+E7000 emulator for Hitachi H8 and SH.
+
+@kindex target es1800
+@item target es1800 @var{dev}
+ES-1800 emulator for M68K.
+
+@kindex target est
+@item target est @var{dev}
+EST-300 ICE monitor, running on a CPU32 (M68K) board.
+
@kindex target hms
@item target hms @var{dev}
A Hitachi SH, H8/300, or H8/500 board, attached via serial line to your host.
@ifclear H8EXCLUSIVE
Use special commands @code{device} and @code{speed} to control the serial
line and the communications speed used.
-@end ifclear
@xref{Hitachi Remote,,@value{GDBN} and Hitachi Microprocessors}.
-@end ifset
-@ifset I960
+@kindex target lsi
+@item target lsi @var{dev}
+LSI ROM monitor for Mips.
+
+@kindex target m32r
+@item target m32r @var{dev}
+Mitsubishi M32R/D ROM monitor.
+
+@kindex target mips
+@item target mips @var{dev}
+IDT/SIM ROM monitor for Mips.
+
+@kindex target mon960
+@item target mon960 @var{dev}
+MON960 monitor for Intel i960.
+
@kindex target nindy
@item target nindy @var{devicename}
An Intel 960 board controlled by a Nindy Monitor. @var{devicename} is
the name of the serial device to use for the connection, e.g.
@file{/dev/ttya}. @xref{i960-Nindy Remote, ,@value{GDBN} with a remote i960 (Nindy)}.
-@end ifset
-@ifset ST2000
+@kindex target nrom
+@item target nrom @var{dev}
+NetROM ROM emulator. This target only supports downloading.
+
+@kindex target op50n
+@item target op50n @var{dev}
+OP50N monitor, running on an OKI HPPA board.
+
+@kindex target pmon
+@item target pmon @var{dev}
+PMON ROM monitor for Mips.
+
+@kindex target ppcbug
+@item target ppcbug @var{dev}
+@kindex target ppcbug1
+@item target ppcbug1 @var{dev}
+PPCBUG ROM monitor for PowerPC.
+
+@kindex target r3900
+@item target r3900 @var{dev}
+Densan DVE-R3900 ROM monitor for Toshiba R3900 Mips.
+
+@kindex target rdi
+@item target rdi @var{dev}
+ARM Angel monitor, via RDI library interface.
+
+@kindex target rdp
+@item target rdp @var{dev}
+ARM Demon monitor.
+
+@kindex target rom68k
+@item target rom68k @var{dev}
+ROM 68K monitor, running on an M68K IDP board.
+
+@kindex target rombug
+@item target rombug @var{dev}
+ROMBUG ROM monitor for OS/9000.
+
+@kindex target sds
+@item target sds @var{dev}
+SDS monitor, running on a PowerPC board (such as Motorola's ADS).
+
+@kindex target sparclite
+@item target sparclite @var{dev}
+Fujitsu sparclite boards, used only for the purpose of loading.
+You must use an additional command to debug the program.
+For example: target remote @var{dev} using @value{GDBN} standard
+remote protocol.
+
+@kindex target sh3
+@kindex target sh3e
+@item target sh3 @var{dev}
+@item target sh3e @var{dev}
+Hitachi SH-3 and SH-3E target systems.
+
@kindex target st2000
@item target st2000 @var{dev} @var{speed}
A Tandem ST2000 phone switch, running Tandem's STDBUG protocol. @var{dev}
@@ -7571,46 +8647,24 @@ is the name of the device attached to the ST2000 serial line;
@var{speed} is the communication line speed. The arguments are not used
if @value{GDBN} is configured to connect to the ST2000 using TCP or Telnet.
@xref{ST2000 Remote,,@value{GDBN} with a Tandem ST2000}.
-@end ifset
-@ifset VXWORKS
+@kindex target udi
+@item target udi @var{keyword}
+Remote AMD29K target, using the AMD UDI protocol. The @var{keyword}
+argument specifies which 29K board or simulator to use. @xref{UDI29K
+Remote,,The UDI protocol for AMD29K}.
+
@kindex target vxworks
@item target vxworks @var{machinename}
A VxWorks system, attached via TCP/IP. The argument @var{machinename}
is the target system's machine name or IP address.
@xref{VxWorks Remote, ,@value{GDBN} and VxWorks}.
-@end ifset
-
-@kindex target cpu32bug
-@item target cpu32bug @var{dev}
-CPU32BUG monitor, running on a CPU32 (M68K) board.
-
-@kindex target op50n
-@item target op50n @var{dev}
-OP50N monitor, running on an OKI HPPA board.
@kindex target w89k
@item target w89k @var{dev}
W89K monitor, running on a Winbond HPPA board.
-@kindex target est
-@item target est @var{dev}
-EST-300 ICE monitor, running on a CPU32 (M68K) board.
-
-@kindex target rom68k
-@item target rom68k @var{dev}
-ROM 68K monitor, running on an IDP board.
-
-@kindex target array
-@item target array @var{dev}
-Array Tech LSI33K RAID controller board.
-
-@kindex target sparclite
-@item target sparclite @var{dev}
-Fujitsu sparclite boards, used only for the purpose of loading.
-You must use an additional command to debug the program.
-For example: target remote @var{dev} using @value{GDBN} standard
-remote protocol.
+@end ifclear
@end table
@ifset GENERIC
@@ -7618,6 +8672,61 @@ Different targets are available on different configurations of @value{GDBN};
your configuration may have more or fewer targets.
@end ifset
+Many remote targets require you to download the executable's code
+once you've successfully established a connection.
+
+@table @code
+
+@kindex load @var{filename}
+@item load @var{filename}
+@ifset GENERIC
+Depending on what remote debugging facilities are configured into
+@value{GDBN}, the @code{load} command may be available. Where it exists, it
+is meant to make @var{filename} (an executable) available for debugging
+on the remote system---by downloading, or dynamic linking, for example.
+@code{load} also records the @var{filename} symbol table in @value{GDBN}, like
+the @code{add-symbol-file} command.
+
+If your @value{GDBN} does not have a @code{load} command, attempting to
+execute it gets the error message ``@code{You can't do that when your
+target is @dots{}}''
+@end ifset
+
+The file is loaded at whatever address is specified in the executable.
+For some object file formats, you can specify the load address when you
+link the program; for other formats, like a.out, the object file format
+specifies a fixed address.
+@c FIXME! This would be a good place for an xref to the GNU linker doc.
+
+@ifset VXWORKS
+On VxWorks, @code{load} links @var{filename} dynamically on the
+current target system as well as adding its symbols in @value{GDBN}.
+@end ifset
+
+@ifset I960
+@cindex download to Nindy-960
+With the Nindy interface to an Intel 960 board, @code{load}
+downloads @var{filename} to the 960 as well as adding its symbols in
+@value{GDBN}.
+@end ifset
+
+@ifset H8
+@cindex download to H8/300 or H8/500
+@cindex H8/300 or H8/500 download
+@cindex download to Hitachi SH
+@cindex Hitachi SH download
+When you select remote debugging to a Hitachi SH, H8/300, or H8/500 board
+(@pxref{Hitachi Remote,,@value{GDBN} and Hitachi Microprocessors}),
+the @code{load} command downloads your program to the Hitachi board and also
+opens it as the current executable target for @value{GDBN} on your host
+(like the @code{file} command).
+@end ifset
+
+@code{load} does not repeat if you press @key{RET} again after using it.
+@end table
+
+@ifset REMOTESTUB
+@node Byte Order, Remote, Target Commands, Targets
@section Choosing target byte order
@cindex choosing target byte order
@cindex target byte order
@@ -7626,17 +8735,37 @@ your configuration may have more or fewer targets.
@kindex set endian auto
@kindex show endian
-You can now choose which byte order to use with a target system.
-Use the @code{set endian big} and @code{set endian little} commands.
-Use the @code{set endian auto} command to instruct
-@value{GDBN} to use the byte order associated with the executable.
-You can see the current setting for byte order with the @code{show endian}
-command.
-
-@emph{Warning:} Currently, only embedded MIPS configurations support
-dynamic selection of target byte order.
+Some types of processors, such as the MIPS, PowerPC, and Hitachi SH,
+offer the ability to run either big-endian or little-endian byte
+orders. Usually the executable or symbol will include a bit to
+designate the endian-ness, and you will not need to worry about
+which to use. However, you may still find it useful to adjust
+GDB's idea of processor endian-ness manually.
+
+@table @code
+@kindex set endian big
+@item set endian big
+Instruct @value{GDBN} to assume the target is big-endian.
+
+@kindex set endian little
+@item set endian little
+Instruct @value{GDBN} to assume the target is little-endian.
+
+@kindex set endian auto
+@item set endian auto
+Instruct @value{GDBN} to use the byte order associated with the
+executable.
+
+@item show endian
+Display @value{GDBN}'s current idea of the target byte order.
+
+@end table
+
+Note that these commands merely adjust interpretation of symbolic
+data on the host, and that they have absolutely no effect on the
+target system.
-@node Remote
+@node Remote, , Byte Order, Targets
@section Remote debugging
@cindex remote debugging
@@ -7655,6 +8784,7 @@ communicate with @value{GDBN}.
Other remote targets may be available in your
configuration of @value{GDBN}; use @code{help target} to list them.
+@end ifset
@ifset GENERIC
@c Text on starting up GDB in various specific cases; it goes up front
@@ -7683,6 +8813,9 @@ configuration of @value{GDBN}; use @code{help target} to list them.
@ifset MIPS
* MIPS Remote:: @value{GDBN} and MIPS boards
@end ifset
+@ifset SPARCLET
+* Sparclet Remote:: @value{GDBN} and Sparclet boards
+@end ifset
@ifset SIMS
* Simulator:: Simulated CPU target
@end ifset
@@ -7708,7 +8841,7 @@ here.
* Messages/Warnings:: Optional warnings and messages
@end menu
-@node Prompt
+@node Prompt, Editing, Controlling GDB, Controlling GDB
@section Prompt
@cindex prompt
@@ -7734,7 +8867,7 @@ Directs @value{GDBN} to use @var{newprompt} as its prompt string henceforth.
Prints a line of the form: @samp{Gdb's prompt is: @var{your-prompt}}
@end table
-@node Editing
+@node Editing, History, Prompt, Controlling GDB
@section Command editing
@cindex readline
@cindex command line editing
@@ -7764,7 +8897,7 @@ Disable command line editing.
Show whether command line editing is enabled.
@end table
-@node History
+@node History, Screen Size, Editing, Controlling GDB
@section Command history
@value{GDBN} can keep track of the commands you type during your
@@ -7860,7 +8993,7 @@ Print ten commands centered on command number @var{n}.
Print ten commands just after the commands last printed.
@end table
-@node Screen Size
+@node Screen Size, Numbers, History, Controlling GDB
@section Screen size
@cindex size of screen
@cindex pauses in output
@@ -7901,7 +9034,7 @@ Likewise, you can specify @samp{set width 0} to prevent @value{GDBN}
from wrapping its output.
@end table
-@node Numbers
+@node Numbers, Messages/Warnings, Screen Size, Controlling GDB
@section Numbers
@cindex number representation
@cindex entering numbers
@@ -7947,7 +9080,7 @@ Display the current default base for numeric input.
Display the current default base for numeric display.
@end table
-@node Messages/Warnings
+@node Messages/Warnings, , Numbers, Controlling GDB
@section Optional warnings and messages
By default, @value{GDBN} is silent about its inner workings. If you are running
@@ -8018,7 +9151,7 @@ Enables confirmation requests (the default).
Displays state of confirmation requests.
@end table
-@node Sequences
+@node Sequences, Emacs, Controlling GDB, Top
@chapter Canned Sequences of Commands
Aside from breakpoint commands (@pxref{Break Commands, ,Breakpoint
@@ -8027,12 +9160,12 @@ for execution as a unit: user-defined commands and command files.
@menu
* Define:: User-defined commands
-* Hooks:: User-defined command hooks
+* Hooks:: User-defined command hooks
* Command Files:: Command files
* Output:: Commands for controlled output
@end menu
-@node Define
+@node Define, Hooks, Sequences, Sequences
@section User-defined commands
@cindex user-defined command
@@ -8121,7 +9254,7 @@ without asking when used inside a user-defined command. Many @value{GDBN}
commands that normally print messages to say what they are doing omit the
messages when used in a user-defined command.
-@node Hooks
+@node Hooks, Command Files, Define, Sequences
@section User-defined command hooks
@cindex command files
@@ -8167,7 +9300,7 @@ If an error occurs during the execution of your hook, execution of
If you try to define a hook which does not match any known command, you
get a warning from the @code{define} command.
-@node Command Files
+@node Command Files, Output, Hooks, Sequences
@section Command files
@cindex command files
@@ -8177,25 +9310,24 @@ An empty line in a command file does nothing; it does not mean to repeat
the last command, as it would from the terminal.
@cindex init file
-@cindex @file{@value{GDBINIT}}
+@cindex @file{.gdbinit}
When you start @value{GDBN}, it automatically executes commands from its
-@dfn{init files}. These are files named @file{@value{GDBINIT}}.
-@value{GDBN} reads the init file (if any) in your home directory, then
-processes command line options and operands, and then reads the init
-file (if any) in the current working directory. This is so the init
-file in your home directory can set options (such as @code{set
-complaints}) which affect the processing of the command line options and
-operands. The init files are not executed if you use the @samp{-nx}
-option; @pxref{Mode Options, ,Choosing modes}.
+@dfn{init files}. These are files named @file{.gdbinit} on Unix, or
+@file{gdb.ini} on DOS/Windows. @value{GDBN} reads the init file (if
+any) in your home directory, then processes command line options and
+operands, and then reads the init file (if any) in the current working
+directory. This is so the init file in your home directory can set
+options (such as @code{set complaints}) which affect the processing of
+the command line options and operands. The init files are not executed
+if you use the @samp{-nx} option; @pxref{Mode Options, ,Choosing modes}.
@ifset GENERIC
@cindex init file name
On some configurations of @value{GDBN}, the init file is known by a
different name (these are typically environments where a specialized
-form of @value{GDBN} may need to coexist with other forms,
-hence a different name
-for the specialized version's init file). These are the environments
-with special init file names:
+form of @value{GDBN} may need to coexist with other forms, hence a
+different name for the specialized version's init file). These are the
+environments with special init file names:
@kindex .vxgdbinit
@itemize @bullet
@@ -8230,7 +9362,7 @@ without asking when used in a command file. Many @value{GDBN} commands that
normally print messages to say what they are doing omit the messages
when called from command files.
-@node Output
+@node Output, , Command Files, Sequences
@section Commands for controlled output
During the execution of a command file or a user-defined command, normal
@@ -8307,7 +9439,7 @@ letter.
@end table
@ifclear DOSHOST
-@node Emacs
+@node Emacs, GDB Bugs, Sequences, Top
@chapter Using @value{GDBN} under @sc{gnu} Emacs
@cindex Emacs
@@ -8320,6 +9452,9 @@ To use this interface, use the command @kbd{M-x gdb} in Emacs. Give the
executable file you want to debug as an argument. This command starts
@value{GDBN} as a subprocess of Emacs, with input and output through a newly
created Emacs buffer.
+@ifset HPPA
+(Do not use the @code{-tui} option to run @value{GDBN} from Emacs.)
+@end ifset
Using @value{GDBN} under Emacs is just like using @value{GDBN} normally except for two
things:
@@ -8481,36 +9616,9 @@ each value is printed in its own window.
@end ignore
@end ifclear
-@ifset LUCID
-@node Energize
-@chapter Using @value{GDBN} with Energize
-
-@cindex Energize
-The Energize Programming System is an integrated development environment
-that includes a point-and-click interface to many programming tools.
-When you use @value{GDBN} in this environment, you can use the standard
-Energize graphical interface to drive @value{GDBN}; you can also, if you
-choose, type @value{GDBN} commands as usual in a debugging window. Even if
-you use the graphical interface, the debugging window (which uses Emacs,
-and resembles the standard @sc{gnu} Emacs interface to
-@value{GDBN}) displays the
-equivalent commands, so that the history of your debugging session is
-properly reflected.
-
-When Energize starts up a @value{GDBN} session, it uses one of the
-command-line options @samp{-energize} or @samp{-cadillac} (``cadillac''
-is the name of the communications protocol used by the Energize system).
-This option makes @value{GDBN} run as one of the tools in the Energize Tool
-Set: it sends all output to the Energize kernel, and accept input from
-it as well.
-
-See the user manual for the Energize Programming System for
-information on how to use the Energize graphical interface and the other
-development tools that Energize integrates with @value{GDBN}.
-
-@end ifset
-
@node GDB Bugs
+@c links whacked to pacify makeinfo
+@c , Command Line Editing, Emacs, Top
@chapter Reporting Bugs in @value{GDBN}
@cindex bugs in @value{GDBN}
@cindex reporting bugs in @value{GDBN}
@@ -8530,7 +9638,7 @@ information that enables us to fix the bug.
* Bug Reporting:: How to report bugs
@end menu
-@node Bug Criteria
+@node Bug Criteria, Bug Reporting, GDB Bugs, GDB Bugs
@section Have you found a bug?
@cindex bug criteria
@@ -8546,7 +9654,9 @@ If the debugger gets a fatal signal, for any input whatever, that is a
@cindex error on valid input
@item
-If @value{GDBN} produces an error message for valid input, that is a bug.
+If @value{GDBN} produces an error message for valid input, that is a
+bug. (Note that if you're cross debugging, the problem may also be
+somewhere in the connection to the target.)
@cindex invalid input
@item
@@ -8560,11 +9670,12 @@ If you are an experienced user of debugging tools, your suggestions
for improvement of @value{GDBN} are welcome in any case.
@end itemize
-@node Bug Reporting
+@node Bug Reporting, , Bug Criteria, GDB Bugs
@section How to report bugs
@cindex bug reports
@cindex @value{GDBN} bugs, reporting
+@ifclear HPPA
A number of companies and individuals offer support for @sc{gnu} products.
If you obtained @value{GDBN} from a support organization, we recommend you
contact that organization first.
@@ -8572,18 +9683,19 @@ contact that organization first.
You can find contact information for many support companies and
individuals in the file @file{etc/SERVICE} in the @sc{gnu} Emacs
distribution.
+@c should add a web page ref...
-In any event, we also recommend that you send bug reports for @value{GDBN} to one
-of these addresses:
+In any event, we also recommend that you send bug reports for
+@value{GDBN} to this addresses:
@example
bug-gdb@@prep.ai.mit.edu
-@{ucbvax|mit-eddie|uunet@}!prep.ai.mit.edu!bug-gdb
@end example
@strong{Do not send bug reports to @samp{info-gdb}, or to
-@samp{help-gdb}, or to any newsgroups.} Most users of @value{GDBN} do not want to
-receive bug reports. Those that do have arranged to receive @samp{bug-gdb}.
+@samp{help-gdb}, or to any newsgroups.} Most users of @value{GDBN} do
+not want to receive bug reports. Those that do have arranged to receive
+@samp{bug-gdb}.
The mailing list @samp{bug-gdb} has a newsgroup @samp{gnu.gdb.bug} which
serves as a repeater. The mailing list and the newsgroup carry exactly
@@ -8603,6 +9715,15 @@ Free Software Foundation Inc.
Boston, MA 02111-1307
USA
@end example
+@end ifclear
+
+@ifset HPPA
+If you obtained HP GDB as part of your HP ANSI C or HP ANSI C++ compiler
+kit, report problems to your HP Support Representative.
+
+If you obtained HP GDB from the Hewlett-Packard Web site, report
+problems by electronic mail to @code{wdb-www@@ch.hp.com}.
+@end ifset
The fundamental principle of reporting bugs usefully is this:
@strong{report all the facts}. If you are not sure whether to state a
@@ -8618,16 +9739,10 @@ of that location would fool the debugger into doing the right thing despite
the bug. Play it safe and give a specific, complete example. That is the
easiest thing for you to do, and the most helpful.
-Keep in mind that the purpose of a bug report is to enable us to fix
-the bug if it is new to us.
-@c
-@c FIX ME!!--What the heck does the following sentence mean,
-@c in the context of the one above?
-@c
-@c It is not as important as what happens if the bug is already known.
-@c
-Therefore, always write your bug reports on
-the assumption that the bug has not been reported previously.
+Keep in mind that the purpose of a bug report is to enable us to fix the
+bug. It may be that the bug has been reported previously, but neither
+you nor we can know that unless your bug report is complete and
+self-contained.
Sometimes people give a few sketchy facts and ask, ``Does this ring a
bell?'' Those bug reports are useless, and we urge everyone to
@@ -8638,8 +9753,9 @@ To enable us to fix the bug, you should include all these things:
@itemize @bullet
@item
-The version of @value{GDBN}. @value{GDBN} announces it if you start with no
-arguments; you can also print it at any time using @code{show version}.
+The version of @value{GDBN}. @value{GDBN} announces it if you start
+with no arguments; you can also print it at any time using @code{show
+version}.
Without this, we will not know whether there is any point in looking for
the bug in the current version of @value{GDBN}.
@@ -8648,13 +9764,18 @@ the bug in the current version of @value{GDBN}.
The type of machine you are using, and the operating system name and
version number.
+@ifclear HPPA
@item
What compiler (and its version) was used to compile @value{GDBN}---e.g.
-``@value{GCC}--2.0''.
+``@value{GCC}--2.8.1''.
+@end ifclear
@item
-What compiler (and its version) was used to compile the program you
-are debugging---e.g. ``@value{GCC}--2.0''.
+What compiler (and its version) was used to compile the program you are
+debugging---e.g. ``@value{GCC}--2.8.1'', or ``HP92453-01 A.10.32.03 HP
+C Compiler''. For GCC, you can say @code{gcc --version} to get this
+information; for other compilers, see the documentation for those
+compilers.
@item
The command arguments you gave the compiler to compile your example and
@@ -8673,20 +9794,21 @@ reproduce the bug.
A description of what behavior you observe that you believe is
incorrect. For example, ``It gets a fatal signal.''
-Of course, if the bug is that @value{GDBN} gets a fatal signal, then we will
-certainly notice it. But if the bug is incorrect output, we might not
-notice unless it is glaringly wrong. You might as well not give us a
-chance to make a mistake.
+Of course, if the bug is that @value{GDBN} gets a fatal signal, then we
+will certainly notice it. But if the bug is incorrect output, we might
+not notice unless it is glaringly wrong. You might as well not give us
+a chance to make a mistake.
Even if the problem you experience is a fatal signal, you should still
-say so explicitly. Suppose something strange is going on, such as,
-your copy of @value{GDBN} is out of synch, or you have encountered a
-bug in the C library on your system. (This has happened!) Your copy
-might crash and ours would not. If you told us to expect a crash,
-then when ours fails to crash, we would know that the bug was not
-happening for us. If you had not told us to expect a crash, then we
-would not be able to draw any conclusion from our observations.
-
+say so explicitly. Suppose something strange is going on, such as, your
+copy of @value{GDBN} is out of synch, or you have encountered a bug in
+the C library on your system. (This has happened!) Your copy might
+crash and ours would not. If you told us to expect a crash, then when
+ours fails to crash, we would know that the bug was not happening for
+us. If you had not told us to expect a crash, then we would not be able
+to draw any conclusion from our observations.
+
+@ifclear HPPA
@item
If you wish to suggest changes to the @value{GDBN} source, send us context
diffs. If you even discuss something in the @value{GDBN} source, refer to
@@ -8694,6 +9816,7 @@ it by context, not by line number.
The line numbers in our development sources will not match those in your
sources. Your line numbers would convey no useful information to us.
+@end ifclear
@end itemize
Here are some things that are not necessary:
@@ -8752,129 +9875,12 @@ things without first using the debugger to find the facts.
@include rluser.texinfo
@include inc-hist.texi
-@ifset NOVEL
-@ifset RENAMED
-@node Renamed Commands
-@appendix Renamed Commands
-
-The following commands were renamed in @value{GDBN} 4, in order to make the
-command set as a whole more consistent and easier to use and remember:
-
-@kindex add-syms
-@kindex delete environment
-@kindex info copying
-@kindex info convenience
-@kindex info directories
-@kindex info editing
-@kindex info history
-@kindex info targets
-@kindex info values
-@kindex info version
-@kindex info warranty
-@kindex set addressprint
-@kindex set arrayprint
-@kindex set prettyprint
-@kindex set screen-height
-@kindex set screen-width
-@kindex set unionprint
-@kindex set vtblprint
-@kindex set demangle
-@kindex set asm-demangle
-@kindex set sevenbit-strings
-@kindex set array-max
-@kindex set caution
-@kindex set history write
-@kindex show addressprint
-@kindex show arrayprint
-@kindex show prettyprint
-@kindex show screen-height
-@kindex show screen-width
-@kindex show unionprint
-@kindex show vtblprint
-@kindex show demangle
-@kindex show asm-demangle
-@kindex show sevenbit-strings
-@kindex show array-max
-@kindex show caution
-@kindex show history write
-@kindex unset
-
-@c TEXI2ROFF-KILL
-@ifinfo
-@c END TEXI2ROFF-KILL
-@example
-OLD COMMAND NEW COMMAND
-@c TEXI2ROFF-KILL
---------------- -------------------------------
-@c END TEXI2ROFF-KILL
-add-syms add-symbol-file
-delete environment unset environment
-info convenience show convenience
-info copying show copying
-info directories show directories
-info editing show commands
-info history show values
-info targets help target
-info values show values
-info version show version
-info warranty show warranty
-set/show addressprint set/show print address
-set/show array-max set/show print elements
-set/show arrayprint set/show print array
-set/show asm-demangle set/show print asm-demangle
-set/show caution set/show confirm
-set/show demangle set/show print demangle
-set/show history write set/show history save
-set/show prettyprint set/show print pretty
-set/show screen-height set/show height
-set/show screen-width set/show width
-set/show sevenbit-strings set/show print sevenbit-strings
-set/show unionprint set/show print union
-set/show vtblprint set/show print vtbl
-
-unset [No longer an alias for delete]
-@end example
-@c TEXI2ROFF-KILL
-@end ifinfo
-
-@tex
-\vskip \parskip\vskip \baselineskip
-\halign{\tt #\hfil &\qquad#&\tt #\hfil\cr
-{\bf Old Command} &&{\bf New Command}\cr
-add-syms &&add-symbol-file\cr
-delete environment &&unset environment\cr
-info convenience &&show convenience\cr
-info copying &&show copying\cr
-info directories &&show directories \cr
-info editing &&show commands\cr
-info history &&show values\cr
-info targets &&help target\cr
-info values &&show values\cr
-info version &&show version\cr
-info warranty &&show warranty\cr
-set{\rm / }show addressprint &&set{\rm / }show print address\cr
-set{\rm / }show array-max &&set{\rm / }show print elements\cr
-set{\rm / }show arrayprint &&set{\rm / }show print array\cr
-set{\rm / }show asm-demangle &&set{\rm / }show print asm-demangle\cr
-set{\rm / }show caution &&set{\rm / }show confirm\cr
-set{\rm / }show demangle &&set{\rm / }show print demangle\cr
-set{\rm / }show history write &&set{\rm / }show history save\cr
-set{\rm / }show prettyprint &&set{\rm / }show print pretty\cr
-set{\rm / }show screen-height &&set{\rm / }show height\cr
-set{\rm / }show screen-width &&set{\rm / }show width\cr
-set{\rm / }show sevenbit-strings &&set{\rm / }show print sevenbit-strings\cr
-set{\rm / }show unionprint &&set{\rm / }show print union\cr
-set{\rm / }show vtblprint &&set{\rm / }show print vtbl\cr
-\cr
-unset &&\rm(No longer an alias for delete)\cr
-}
-@end tex
-@c END TEXI2ROFF-KILL
-@end ifset
-@end ifset
@ifclear PRECONFIGURED
+@ifclear HPPA
@node Formatting Documentation
+@c links whacked to pacify makeinfo
+@c , Installing GDB, Renamed Commands, Top
@appendix Formatting Documentation
@cindex @value{GDBN} reference card
@@ -8908,22 +9914,22 @@ on-line information and a printed manual. You can use one of the Info
formatting commands to create the on-line version of the documentation
and @TeX{} (or @code{texi2roff}) to typeset the printed version.
-@value{GDBN} includes an already formatted copy of the on-line Info version of
-this manual in the @file{gdb} subdirectory. The main Info file is
-@file{gdb-@r{version-number}/gdb/gdb.info}, and it refers to
+@value{GDBN} includes an already formatted copy of the on-line Info
+version of this manual in the @file{gdb} subdirectory. The main Info
+file is @file{gdb-@value{GDBVN}/gdb/gdb.info}, and it refers to
subordinate files matching @samp{gdb.info*} in the same directory. If
necessary, you can print out these files, or read them with any editor;
-but they are easier to read using the @code{info} subsystem in @sc{gnu} Emacs
-or the standalone @code{info} program, available as part of the @sc{gnu}
-Texinfo distribution.
+but they are easier to read using the @code{info} subsystem in @sc{gnu}
+Emacs or the standalone @code{info} program, available as part of the
+@sc{gnu} Texinfo distribution.
If you want to format these Info files yourself, you need one of the
Info formatting programs, such as @code{texinfo-format-buffer} or
@code{makeinfo}.
-If you have @code{makeinfo} installed, and are in the top level @value{GDBN}
-source directory (@file{gdb-@value{GDBVN}}, in the case of version @value{GDBVN}), you can
-make the Info file by typing:
+If you have @code{makeinfo} installed, and are in the top level
+@value{GDBN} source directory (@file{gdb-@value{GDBVN}}, in the case of
+version @value{GDBVN}), you can make the Info file by typing:
@example
cd gdb
@@ -8952,17 +9958,50 @@ directory.
If you have @TeX{} and a @sc{dvi} printer program installed, you can
typeset and print this manual. First switch to the the @file{gdb}
subdirectory of the main source directory (for example, to
-@file{gdb-@value{GDBVN}/gdb}) and then type:
+@file{gdb-@value{GDBVN}/gdb}) and type:
@example
make gdb.dvi
@end example
-@node Installing GDB
+Then give @file{gdb.dvi} to your @sc{dvi} printing program.
+@end ifclear
+
+@node Installing GDB, Index, Using History Interactively, Top
@appendix Installing @value{GDBN}
@cindex configuring @value{GDBN}
@cindex installation
+@ifset HPPA
+If you obtain @value{GDBN} (HP WDB 0.75) as part of your HP ANSI C or
+HP ANSI C++ Developer's Kit at HP-UX Release 11.0, you do not have to
+take any special action to build or install @value{GDBN}.
+
+If you obtain @value{GDBN} (HP WDB 0.75) from an HP web site, you may
+download either a @code{swinstall}-able package or a source tree, or
+both.
+
+Most customers will want to install the @value{GDBN} binary that is part
+of the @code{swinstall}-able package. To do so, use a command of the
+form
+
+@smallexample
+/usr/sbin/swinstall -s @var{package-name} WDB
+@end smallexample
+
+Alternatively, it is possible to build @value{GDBN} from the source
+distribution. Sophisticated customers who want to modify the debugger
+sources to tailor @value{GDBN} to their their needs may wish to do this.
+The source distribution consists of a @code{tar}'ed source tree rooted
+at @file{gdb-4.16/...}. The instructions that follow describe how to
+build a @file{gdb} executable from this source tree. HP believes that
+these instructions apply to the WDB source tree that it distributes.
+However, HP does not explicitly support building a @file{gdb} for any
+non-HP platform from the WDB source tree. It may work, but HP has not
+tested it for any platforms other than those described in the WDB 0.75
+Release Notes.
+@end ifset
+
@value{GDBN} comes with a @code{configure} script that automates the process
of preparing @value{GDBN} for installation; you can then use @code{make} to
build the @code{gdb} program.
@@ -9075,10 +10114,10 @@ let @value{GDBN} debug child processes whose programs are not readable.
@menu
* Separate Objdir:: Compiling @value{GDBN} in another directory
* Config Names:: Specifying names for hosts and targets
-* configure Options:: Summary of options for configure
+* Configure Options:: Summary of options for configure
@end menu
-@node Separate Objdir
+@node Separate Objdir, Config Names, Installing GDB, Installing GDB
@section Compiling @value{GDBN} in another directory
If you want to run @value{GDBN} versions for several host or target machines,
@@ -9139,7 +10178,7 @@ directories, you can run @code{make} on them in parallel (for example,
if they are NFS-mounted on each of the hosts); they will not interfere
with each other.
-@node Config Names
+@node Config Names, Configure Options, Separate Objdir, Installing GDB
@section Specifying names for hosts and targets
The specifications used for hosts and targets in the @code{configure}
@@ -9163,25 +10202,25 @@ script, if you wish, or you can use it to test your guesses on
abbreviations---for example:
@smallexample
+% sh config.sub i386-linux
+i386-pc-linux-gnu
+% sh config.sub alpha-linux
+alpha-unknown-linux-gnu
+% sh config.sub hp9k700
+hppa1.1-hp-hpux
% sh config.sub sun4
sparc-sun-sunos4.1.1
% sh config.sub sun3
m68k-sun-sunos4.1.1
-% sh config.sub decstation
-mips-dec-ultrix4.2
-% sh config.sub hp300bsd
-m68k-hp-bsd
-% sh config.sub i386v
-i386-unknown-sysv
-% sh config.sub i786v
-Invalid configuration `i786v': machine `i786v' not recognized
+% sh config.sub i986v
+Invalid configuration `i986v': machine `i986v' not recognized
@end smallexample
@noindent
@code{config.sub} is also distributed in the @value{GDBN} source
directory (@file{gdb-@value{GDBVN}}, for version @value{GDBVN}).
-@node configure Options
+@node Configure Options, , Config Names, Installing GDB
@section @code{configure} options
Here is a summary of the @code{configure} options and arguments that
@@ -9192,9 +10231,11 @@ Does,,configure.info}, for a full explanation of @code{configure}.
@example
configure @r{[}--help@r{]}
@r{[}--prefix=@var{dir}@r{]}
+ @r{[}--exec-prefix=@var{dir}@r{]}
@r{[}--srcdir=@var{dirname}@r{]}
@r{[}--norecursion@r{]} @r{[}--rm@r{]}
- @r{[}--target=@var{target}@r{]} @var{host}
+ @r{[}--target=@var{target}@r{]}
+ @var{host}
@end example
@noindent
@@ -9206,10 +10247,14 @@ You may introduce options with a single @samp{-} rather than
@item --help
Display a quick summary of how to invoke @code{configure}.
-@item -prefix=@var{dir}
+@item --prefix=@var{dir}
Configure the source to install programs and files under directory
@file{@var{dir}}.
+@item --exec-prefix=@var{dir}
+Configure the source to install programs under directory
+@file{@var{dir}}.
+
@c avoid splitting the warning from the explanation:
@need 2000
@item --srcdir=@var{dirname}
@@ -9228,16 +10273,6 @@ the working directory in parallel to the source directories below
Configure only the directory level where @code{configure} is executed; do not
propagate configuration to subdirectories.
-@item --rm
-@emph{Remove} files otherwise built during configuration.
-
-@c This does not work (yet if ever). FIXME.
-@c @item --parse=@var{lang} @dots{}
-@c Configure the @value{GDBN} expression parser to parse the listed languages.
-@c @samp{all} configures @value{GDBN} for all supported languages. To get a
-@c list of all supported languages, omit the argument. Without this
-@c option, @value{GDBN} is configured to parse all supported languages.
-
@item --target=@var{target}
Configure @value{GDBN} for cross-debugging programs running on the specified
@var{target}. Without this option, @value{GDBN} is configured to debug
@@ -9251,13 +10286,12 @@ Configure @value{GDBN} to run on the specified @var{host}.
There is no convenient way to generate a list of all available hosts.
@end table
-@noindent
-@code{configure} accepts other options, for compatibility with
-configuring other @sc{gnu} tools recursively; but these are the only
-options that affect @value{GDBN} or its supporting libraries.
+There are many other options available as well, but they are generally
+needed for special purposes only.
@end ifclear
-@node Index
+
+@node Index, , Installing GDB, Top
@unnumbered Index
@printindex cp
diff --git a/contrib/gdb/gdb/doc/stabs.texinfo b/contrib/gdb/gdb/doc/stabs.texinfo
index b51d611..7e74917 100644
--- a/contrib/gdb/gdb/doc/stabs.texinfo
+++ b/contrib/gdb/gdb/doc/stabs.texinfo
@@ -14,7 +14,7 @@ END-INFO-DIR-ENTRY
@ifinfo
This document describes the stabs debugging symbol tables.
-Copyright 1992, 1993 Free Software Foundation, Inc.
+Copyright 1992, 93, 94, 95, 97, 1998 Free Software Foundation, Inc.
Contributed by Cygnus Support. Written by Julia Menapace, Jim Kingdon,
and David MacKenzie.
@@ -43,7 +43,7 @@ regarded as a program in the language TeX).
@page
@tex
\def\$#1${{#1}} % Kluge: collect RCS revision info without $...$
-\xdef\manvers{\$Revision: 2.125 $} % For use in headers, footers too
+\xdef\manvers{\$Revision: 2.128 $} % For use in headers, footers too
{\parskip=0pt
\hfill Cygnus Support\par
\hfill \manvers\par
@@ -52,7 +52,7 @@ regarded as a program in the language TeX).
@end tex
@vskip 0pt plus 1filll
-Copyright @copyright{} 1992, 1993 Free Software Foundation, Inc.
+Copyright @copyright{} 1992, 93, 94, 95, 97, 1998 Free Software Foundation, Inc.
Contributed by Cygnus Support.
Permission is granted to make and distribute verbatim copies of
@@ -80,8 +80,6 @@ This document describes the stabs debugging format.
* Type Descriptors:: Table of type descriptors
* Expanded Reference:: Reference information by stab type
* Questions:: Questions and anomolies
-* Sun Differences:: Differences between GNU stabs and Sun
- native stabs
* Stab Sections:: In some object file formats, stabs are
in sections.
* Symbol Types Index:: Index of symbolic stab symbol type names.
@@ -240,6 +238,18 @@ type is about to be defined. Any other values following the
a number follows the @samp{=} then the number is a @var{type-reference}.
For a full description of types, @ref{Types}.
+A @var{type-number} is often a single number. The GNU and Sun tools
+additionally permit a @var{type-number} to be a pair
+(@var{file-number},@var{filetype-number}) (the parentheses appear in the
+string, and serve to distinguish the two cases). The @var{file-number}
+is a number starting with 1 which is incremented for each seperate
+source file in the compilation (e.g., in C, each header file gets a
+different number). The @var{filetype-number} is a number starting with
+1 which is incremented for each new type defined in the file.
+(Separating the file number and the type number permits the
+@code{N_BINCL} optimization to succeed more often; see @ref{Include
+Files}).
+
There is an AIX extension for type attributes. Following the @samp{=}
are any number of type attributes. Each one starts with @samp{@@} and
ends with @samp{;}. Debuggers, including AIX's dbx and GDB 4.10, skip
@@ -463,7 +473,7 @@ the start of this one. To specify the main source file again, use an
@findex N_EXCL
The @code{N_BINCL} approach works as follows. An @code{N_BINCL} symbol
specifies the start of an include file. In an object file, only the
-string is significant; the Sun linker puts data into some of the other
+string is significant; the linker puts data into some of the other
fields. The end of the include file is marked by an @code{N_EINCL}
symbol (which has no string field). In an object file, there is no
significant data in the @code{N_EINCL} symbol. @code{N_BINCL} and
@@ -473,16 +483,17 @@ If the linker detects that two source files have identical stabs between
an @code{N_BINCL} and @code{N_EINCL} pair (as will generally be the case
for a header file), then it only puts out the stabs once. Each
additional occurance is replaced by an @code{N_EXCL} symbol. I believe
-the Sun (SunOS4, not sure about Solaris) linker is the only one which
-supports this feature.
-
-The SunOS4 linker sets the value of a @code{N_BINCL} symbol to the total
-of all the characters in the stabs strings included in the header file,
-omitting the file number. The value of an @code{N_EXCL} symbol is the
-same as the value of the @code{N_BINCL} symbol it replaces. I do not
-know if this information is used by anything. The @code{N_EINCL} value,
-and the values of the other and description fields for all three, appear
-to always be zero.
+the GNU linker and the Sun (both SunOS4 and Solaris) linker are the only
+ones which supports this feature.
+
+A linker which supports this feature will set the value of a
+@code{N_BINCL} symbol to the total of all the characters in the stabs
+strings included in the header file, omitting any file numbers. The
+value of an @code{N_EXCL} symbol is the same as the value of the
+@code{N_BINCL} symbol it replaces. This information can be used to
+match up @code{N_EXCL} and @code{N_BINCL} symbols which have the same
+filename. The @code{N_EINCL} value, and the values of the other and
+description fields for all three, appear to always be zero.
@findex C_BINCL
@findex C_EINCL
@@ -632,6 +643,15 @@ group of other stabs describing elements of the procedure. These other
stabs describe the procedure's parameters, its block local variables, and
its block structure.
+If functions can appear in different sections, then the debugger may not
+be able to find the end of a function. Recent versions of GCC will mark
+the end of a function with an @code{N_FUN} symbol with an empty string
+for the name. The value is the address of the end of the current
+function. Without such a symbol, there is no indication of the address
+of the end of a function, and you must assume that it ended at the
+starting address of the next function or at the end of the text section
+for the program.
+
@node Nested Procedures
@section Nested Procedures
@@ -2060,7 +2080,8 @@ For example,
@end example
specifies that @code{s_typedef} refers to type number 16. Such stabs
-have symbol type @code{N_LSYM} (or @code{C_DECL} for XCOFF).
+have symbol type @code{N_LSYM} (or @code{C_DECL} for XCOFF). (The Sun
+documentation mentions using @code{N_GSYM} in some cases).
If you are specifying the tag name for a structure, union, or
enumeration, use the @samp{T} symbol descriptor instead. I believe C is
@@ -2669,16 +2690,21 @@ pointer.
@node Method Type Descriptor
@section The @samp{#} Type Descriptor
-This is like the @samp{f} type descriptor for functions (@pxref{Function
-Types}), except that a function which uses the @samp{#} type descriptor
-takes an extra argument as its first argument, for the @code{this}
-pointer. The @samp{#} type descriptor is optionally followed by the
-types of the arguments, then another @samp{#}. If the types of the
-arguments are omitted, so that the second @samp{#} immediately follows
-the @samp{#} which is the type descriptor, the arguments are being
-omitted (to save space) and can be deduced from the mangled name of the
-method. After the second @samp{#} there is type information for the
-return type of the method and a semicolon.
+This is used to describe a class method. This is a function which takes
+an extra argument as its first argument, for the @code{this} pointer.
+
+If the @samp{#} is immediately followed by another @samp{#}, the second
+one will be followed by the return type and a semicolon. The class and
+argument types are not specified, and must be determined by demangling
+the name of the method if it is available.
+
+Otherwise, the single @samp{#} is followed by the class type, a comma,
+the return type, a comma, and zero or more parameter types separated by
+commas. The list of arguments is terminated by a semicolon. In the
+debugging output generated by gcc, a final argument type of @code{void}
+indicates a method which does not take a variable number of arguments.
+If the final argument type of @code{void} does not appear, the method
+was declared with an ellipsis.
Note that although such a type will normally be used to describe fields
in structures, unions, or classes, for at least some versions of the
@@ -3841,25 +3867,6 @@ What ends the procedure scope? Is it the proc block's @code{N_RBRAC} or the
next @code{N_FUN}? (I believe its the first.)
@end itemize
-@node Sun Differences
-@appendix Differences Between GNU Stabs and Sun Native Stabs
-
-@c FIXME: Merge all this stuff into the main body of the document.
-
-@itemize @bullet
-@item
-GNU C stabs define @emph{all} types, file or procedure scope, as
-@code{N_LSYM}. Sun doc talks about using @code{N_GSYM} too.
-
-@item
-Sun C stabs use type number pairs in the format
-(@var{file-number},@var{type-number}) where @var{file-number} is a
-number starting with 1 and incremented for each sub-source file in the
-compilation. @var{type-number} is a number starting with 1 and
-incremented for each new type defined in the compilation. GNU C stabs
-use the type number alone, with no source file number.
-@end itemize
-
@node Stab Sections
@appendix Using Stabs in Their Own Sections
@@ -3928,17 +3935,25 @@ header @code{sh_type} member set to @code{SHT_STRTAB} to mark it as a
string table. SOM and COFF have no way of linking the sections together
or marking them as string tables.
-For COFF, the @code{.stab} and @code{.stabstr} sections are simply
+For COFF, the @code{.stab} and @code{.stabstr} sections may be simply
concatenated by the linker. GDB then uses the @code{n_desc} fields to
figure out the extent of the original sections. Similarly, the
@code{n_value} fields of the header symbols are added together in order
to get the actual position of the strings in a desired @code{.stabstr}
-section. Although this design obviates any need for the linker to relocate
-or otherwise manipulate @code{.stab} and @code{.stabstr} sections, it also
-requires some care to ensure that the offsets are calculated correctly.
-For instance, if the linker were to pad in between the @code{.stabstr}
-sections before concatenating, then the offsets to strings in the middle
-of the executable's @code{.stabstr} section would be wrong.
+section. Although this design obviates any need for the linker to
+relocate or otherwise manipulate @code{.stab} and @code{.stabstr}
+sections, it also requires some care to ensure that the offsets are
+calculated correctly. For instance, if the linker were to pad in
+between the @code{.stabstr} sections before concatenating, then the
+offsets to strings in the middle of the executable's @code{.stabstr}
+section would be wrong.
+
+The GNU linker is able to optimize stabs information by merging
+duplicate strings and removing duplicate header file information
+(@pxref{Include Files}). When some versions of the GNU linker optimize
+stabs in sections, they remove the leading @code{N_UNDF} symbol and
+arranges for all the @code{n_strx} fields to be relative to the start of
+the @code{.stabstr} section.
@node ELF Linker Relocation
@appendixsec Having the Linker Relocate Stabs in ELF
diff --git a/contrib/gdb/gdb/exec.c b/contrib/gdb/gdb/exec.c
index 4d3a307..6cb9e59 100644
--- a/contrib/gdb/gdb/exec.c
+++ b/contrib/gdb/gdb/exec.c
@@ -1,5 +1,6 @@
/* Work with executable files, for GDB.
- Copyright 1988, 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+ Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1997, 1998
+ Free Software Foundation, Inc.
This file is part of GDB.
@@ -30,7 +31,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <sys/types.h>
#endif
-#include <sys/param.h>
#include <fcntl.h>
#include "gdb_string.h"
@@ -46,6 +46,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
struct vmap *map_vmap PARAMS ((bfd *, bfd *));
+void (*file_changed_hook) PARAMS ((char *));
+
/* Prototypes for local functions */
static void add_to_section_table PARAMS ((bfd *, sec_ptr, PTR));
@@ -58,8 +60,20 @@ static void set_section_command PARAMS ((char *, int));
static void exec_files_info PARAMS ((struct target_ops *));
+static void bfdsec_to_vmap PARAMS ((bfd *, sec_ptr, PTR));
+
+static int ignore PARAMS ((CORE_ADDR, char *));
+
+static void init_exec_ops PARAMS ((void));
+
+void _initialize_exec PARAMS ((void));
+
extern int info_verbose;
+/* The target vector for executable files. */
+
+struct target_ops exec_ops;
+
/* The Binary File Descriptor handle for the executable file. */
bfd *exec_bfd = NULL;
@@ -70,17 +84,14 @@ int write_files = 0;
/* Text start and end addresses (KLUDGE) if needed */
-#ifdef NEED_TEXT_START_END
+#ifndef NEED_TEXT_START_END
+#define NEED_TEXT_START_END (0)
+#endif
CORE_ADDR text_start = 0;
CORE_ADDR text_end = 0;
-#endif
struct vmap *vmap;
-/* Forward decl */
-
-extern struct target_ops exec_ops;
-
/* ARGSUSED */
static void
exec_close (quitting)
@@ -140,20 +151,29 @@ exec_close (quitting)
/* Process the first arg in ARGS as the new exec file.
- Note that we have to explicitly ignore additional args, since we can
- be called from file_command(), which also calls symbol_file_command()
- which can take multiple args. */
+ This function is intended to be behave essentially the same
+ as exec_file_command, except that the latter will detect when
+ a target is being debugged, and will ask the user whether it
+ should be shut down first. (If the answer is "no", then the
+ new file is ignored.)
+
+ This file is used by exec_file_command, to do the work of opening
+ and processing the exec file after any prompting has happened.
+
+ And, it is used by child_attach, when the attach command was
+ given a pid but not a exec pathname, and the attach command could
+ figure out the pathname from the pid. (In this case, we shouldn't
+ ask the user whether the current target should be shut down --
+ we're supplying the exec pathname late for good reason.) */
void
-exec_file_command (args, from_tty)
+exec_file_attach (args, from_tty)
char *args;
int from_tty;
{
char **argv;
char *filename;
- target_preopen (from_tty);
-
/* Remove any previous exec file. */
unpush_target (&exec_ops);
@@ -171,7 +191,7 @@ exec_file_command (args, from_tty)
if (argv == NULL)
nomem (0);
- make_cleanup (freeargv, (char *) argv);
+ make_cleanup ((make_cleanup_func) freeargv, (char *) argv);
for (; (*argv != NULL) && (**argv == '-'); argv++) {;}
if (*argv == NULL)
@@ -183,6 +203,15 @@ exec_file_command (args, from_tty)
scratch_chan = openp (getenv ("PATH"), 1, filename,
write_files? O_RDWR|O_BINARY: O_RDONLY|O_BINARY, 0,
&scratch_pathname);
+#if defined(__GO32__) || defined(_WIN32)
+ if (scratch_chan < 0)
+ {
+ char *exename = alloca (strlen (filename) + 5);
+ strcat (strcpy (exename, filename), ".exe");
+ scratch_chan = openp (getenv ("PATH"), 1, exename, write_files ?
+ O_RDWR|O_BINARY : O_RDONLY|O_BINARY, 0, &scratch_pathname);
+ }
+#endif
if (scratch_chan < 0)
perror_with_name (filename);
fcntl (scratch_chan, F_SETFD, 1);
@@ -234,37 +263,34 @@ exec_file_command (args, from_tty)
scratch_pathname, bfd_errmsg (bfd_get_error ()));
}
-#ifdef NEED_TEXT_START_END
-
/* text_end is sometimes used for where to put call dummies. A
few ports use these for other purposes too. */
-
- {
- struct section_table *p;
-
- /* Set text_start to the lowest address of the start of any
- readonly code section and set text_end to the highest
- address of the end of any readonly code section. */
- /* FIXME: The comment above does not match the code. The code
- checks for sections with are either code *or* readonly. */
-
- text_start = ~(CORE_ADDR)0;
- text_end = (CORE_ADDR)0;
- for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++)
- if (bfd_get_section_flags (p->bfd, p->the_bfd_section)
- & (SEC_CODE | SEC_READONLY))
- {
- if (text_start > p->addr)
- text_start = p->addr;
- if (text_end < p->endaddr)
- text_end = p->endaddr;
- }
- }
-#endif
+ if (NEED_TEXT_START_END)
+ {
+ struct section_table *p;
+
+ /* Set text_start to the lowest address of the start of any
+ readonly code section and set text_end to the highest
+ address of the end of any readonly code section. */
+ /* FIXME: The comment above does not match the code. The
+ code checks for sections with are either code *or*
+ readonly. */
+ text_start = ~(CORE_ADDR)0;
+ text_end = (CORE_ADDR)0;
+ for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++)
+ if (bfd_get_section_flags (p->bfd, p->the_bfd_section)
+ & (SEC_CODE | SEC_READONLY))
+ {
+ if (text_start > p->addr)
+ text_start = p->addr;
+ if (text_end < p->endaddr)
+ text_end = p->endaddr;
+ }
+ }
validate_files ();
- set_endian_from_file (exec_bfd);
+ set_gdbarch_from_file (exec_bfd);
push_target (&exec_ops);
@@ -273,7 +299,26 @@ exec_file_command (args, from_tty)
(*exec_file_display_hook) (filename);
}
else if (from_tty)
- printf_unfiltered ("No exec file now.\n");
+ printf_unfiltered ("No executable file now.\n");
+}
+
+/* Process the first arg in ARGS as the new exec file.
+
+ Note that we have to explicitly ignore additional args, since we can
+ be called from file_command(), which also calls symbol_file_command()
+ which can take multiple args. */
+
+void
+exec_file_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ char **argv;
+ char *filename;
+
+ target_preopen (from_tty);
+
+ exec_file_attach (args, from_tty);
}
/* Set both the exec file and the symbol file, in one command.
@@ -289,6 +334,8 @@ file_command (arg, from_tty)
the exec file, but that's rough. */
exec_file_command (arg, from_tty);
symbol_file_command (arg, from_tty);
+ if (file_changed_hook)
+ file_changed_hook (arg);
}
@@ -355,20 +402,16 @@ bfdsec_to_vmap(abfd, sect, arg3)
if (STREQ (bfd_section_name (abfd, sect), ".text"))
{
- vp->tstart = 0;
+ vp->tstart = bfd_section_vma (abfd, sect);
vp->tend = vp->tstart + bfd_section_size (abfd, sect);
-
- /* When it comes to this adjustment value, in contrast to our previous
- belief shared objects should behave the same as the main load segment.
- This is the offset from the beginning of text section to the first
- real instruction. */
-
- vp->tadj = sect->filepos - bfd_section_vma (abfd, sect);
+ vp->tvma = bfd_section_vma (abfd, sect);
+ vp->toffs = sect->filepos;
}
else if (STREQ (bfd_section_name (abfd, sect), ".data"))
{
- vp->dstart = 0;
+ vp->dstart = bfd_section_vma (abfd, sect);
vp->dend = vp->dstart + bfd_section_size (abfd, sect);
+ vp->dvma = bfd_section_vma (abfd, sect);
}
/* Silently ignore other types of sections. (FIXME?) */
}
@@ -433,25 +476,79 @@ xfer_memory (memaddr, myaddr, len, write, target)
struct section_table *p;
CORE_ADDR nextsectaddr, memend;
boolean (*xfer_fn) PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type));
+ asection *section;
if (len <= 0)
abort();
+ if (overlay_debugging)
+ {
+ section = find_pc_overlay (memaddr);
+ if (pc_in_unmapped_range (memaddr, section))
+ memaddr = overlay_mapped_address (memaddr, section);
+ }
+
memend = memaddr + len;
xfer_fn = write ? bfd_set_section_contents : bfd_get_section_contents;
nextsectaddr = memend;
+#if 0 /* Stu's implementation */
+/* If a section has been specified, try to use it. Note that we cannot use the
+ specified section directly. This is because it usually comes from the
+ symbol file, which may be different from the exec or core file. Instead, we
+ have to lookup the specified section by name in the bfd associated with
+ to_sections. */
+
+ if (target_memory_bfd_section)
+ {
+ asection *s;
+ bfd *abfd;
+ asection *target_section;
+ bfd *target_bfd;
+
+ s = target_memory_bfd_section;
+ abfd = s->owner;
+
+ target_bfd = target->to_sections->bfd;
+ target_section = bfd_get_section_by_name (target_bfd, bfd_section_name (abfd, s));
+
+ if (target_section)
+ {
+ bfd_vma sec_addr;
+ bfd_size_type sec_size;
+
+ sec_addr = bfd_section_vma (target_bfd, target_section);
+ sec_size = target_section->_raw_size;
+
+ /* Make sure the requested memory starts inside the section. */
+
+ if (memaddr >= sec_addr
+ && memaddr < sec_addr + sec_size)
+ {
+ /* Cut back length in case request overflows the end of the section. */
+ len = min (len, sec_addr + sec_size - memaddr);
+
+ res = xfer_fn (target_bfd, target_section, myaddr, memaddr - sec_addr, len);
+
+ return res ? len : 0;
+ }
+ }
+ }
+#endif /* 0, Stu's implementation */
for (p = target->to_sections; p < target->to_sections_end; p++)
{
- if (p->addr <= memaddr)
- if (p->endaddr >= memend)
+ if (overlay_debugging && section && p->the_bfd_section &&
+ strcmp (section->name, p->the_bfd_section->name) != 0)
+ continue; /* not the section we need */
+ if (memaddr >= p->addr)
+ if (memend <= p->endaddr)
{
/* Entire transfer is within this section. */
res = xfer_fn (p->bfd, p->the_bfd_section, myaddr,
memaddr - p->addr, len);
return (res != 0) ? len : 0;
}
- else if (p->endaddr <= memaddr)
+ else if (memaddr >= p->endaddr)
{
/* This section ends before the transfer starts. */
continue;
@@ -464,8 +561,8 @@ xfer_memory (memaddr, myaddr, len, write, target)
memaddr - p->addr, len);
return (res != 0) ? len : 0;
}
- else if (p->addr < nextsectaddr)
- nextsectaddr = p->addr;
+ else
+ nextsectaddr = min (nextsectaddr, p->addr);
}
if (nextsectaddr >= memend)
@@ -586,7 +683,8 @@ set_section_command (args, from_tty)
}
/* If mourn is being called in all the right places, this could be say
- `gdb internal error' (since generic_mourn calls breakpoint_init_inferior). */
+ `gdb internal error' (since generic_mourn calls
+ breakpoint_init_inferior). */
static int
ignore (addr, contents)
@@ -596,63 +694,50 @@ ignore (addr, contents)
return 0;
}
-struct target_ops exec_ops = {
- "exec", /* to_shortname */
- "Local exec file", /* to_longname */
- "Use an executable file as a target.\n\
-Specify the filename of the executable file.", /* to_doc */
- exec_file_command, /* to_open */
- exec_close, /* to_close */
- find_default_attach, /* to_attach */
- 0, /* to_detach */
- 0, /* to_resume */
- 0, /* to_wait */
- 0, /* to_fetch_registers */
- 0, /* to_store_registers */
- 0, /* to_prepare_to_store */
- xfer_memory, /* to_xfer_memory */
- exec_files_info, /* to_files_info */
- ignore, /* to_insert_breakpoint */
- ignore, /* to_remove_breakpoint */
- 0, /* to_terminal_init */
- 0, /* to_terminal_inferior */
- 0, /* to_terminal_ours_for_output */
- 0, /* to_terminal_ours */
- 0, /* to_terminal_info */
- 0, /* to_kill */
- 0, /* to_load */
- 0, /* to_lookup_symbol */
- find_default_create_inferior, /* to_create_inferior */
- 0, /* to_mourn_inferior */
- 0, /* to_can_run */
- 0, /* to_notice_signals */
- 0, /* to_thread_alive */
- 0, /* to_stop */
- file_stratum, /* to_stratum */
- 0, /* to_next */
- 0, /* to_has_all_memory */
- 1, /* to_has_memory */
- 0, /* to_has_stack */
- 0, /* to_has_registers */
- 0, /* to_has_execution */
- 0, /* to_sections */
- 0, /* to_sections_end */
- OPS_MAGIC, /* to_magic */
-};
+/* Fill in the exec file target vector. Very few entries need to be
+ defined. */
+
+void
+init_exec_ops ()
+{
+ exec_ops.to_shortname = "exec";
+ exec_ops.to_longname = "Local exec file";
+ exec_ops.to_doc = "Use an executable file as a target.\n\
+Specify the filename of the executable file.";
+ exec_ops.to_open = exec_file_command;
+ exec_ops.to_close = exec_close;
+ exec_ops.to_attach = find_default_attach;
+ exec_ops.to_require_attach = find_default_require_attach;
+ exec_ops.to_require_detach = find_default_require_detach;
+ exec_ops.to_xfer_memory = xfer_memory;
+ exec_ops.to_files_info = exec_files_info;
+ exec_ops.to_insert_breakpoint = ignore;
+ exec_ops.to_remove_breakpoint = ignore;
+ exec_ops.to_create_inferior = find_default_create_inferior;
+ exec_ops.to_clone_and_follow_inferior = find_default_clone_and_follow_inferior;
+ exec_ops.to_stratum = file_stratum;
+ exec_ops.to_has_memory = 1;
+ exec_ops.to_magic = OPS_MAGIC;
+}
void
-_initialize_exec()
+_initialize_exec ()
{
struct cmd_list_element *c;
- c = add_cmd ("file", class_files, file_command,
- "Use FILE as program to be debugged.\n\
+ init_exec_ops ();
+
+ if (!dbx_commands)
+ {
+ c = add_cmd ("file", class_files, file_command,
+ "Use FILE as program to be debugged.\n\
It is read for its symbols, for getting the contents of pure memory,\n\
and it is the program executed when you use the `run' command.\n\
If FILE cannot be found as specified, your execution directory path\n\
($PATH) is searched for a command of that name.\n\
No arg means to have no executable file and no symbols.", &cmdlist);
- c->completer = filename_completer;
+ c->completer = filename_completer;
+ }
c = add_cmd ("exec-file", class_files, exec_file_command,
"Use FILE as program for getting contents of pure memory.\n\
diff --git a/contrib/gdb/gdb/gdbserver/gdbreplay.c b/contrib/gdb/gdb/gdbserver/gdbreplay.c
index 39258a2..4f70a94 100644
--- a/contrib/gdb/gdb/gdbserver/gdbreplay.c
+++ b/contrib/gdb/gdb/gdbserver/gdbreplay.c
@@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <ctype.h>
#include <errno.h>
#include <string.h>
+#include <fcntl.h>
/* Sort of a hack... */
#define EOL (EOF - 1)
diff --git a/contrib/gdb/gdb/gdbserver/utils.c b/contrib/gdb/gdb/gdbserver/utils.c
index 1e4aabe..75a6a34 100644
--- a/contrib/gdb/gdb/gdbserver/utils.c
+++ b/contrib/gdb/gdb/gdbserver/utils.c
@@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "server.h"
#include <stdio.h>
+#include <string.h>
/* Generally useful subroutines used throughout the program. */
@@ -52,7 +53,7 @@ perror_with_name (string)
#ifdef ANSI_PROTOTYPES
NORETURN void
-error (char *string, ...)
+error (const char *string, ...)
#else
void
error (va_alist)
diff --git a/contrib/gdb/gdb/i386-tdep.c b/contrib/gdb/gdb/i386-tdep.c
index 1daa81d..fbbb879 100644
--- a/contrib/gdb/gdb/i386-tdep.c
+++ b/contrib/gdb/gdb/i386-tdep.c
@@ -768,10 +768,15 @@ gdb_print_insn_i386 (memaddr, info)
bfd_vma memaddr;
disassemble_info * info;
{
+ /* XXX remove when binutils 2.9.2 is imported */
+#if 0
if (disassembly_flavor == att_flavor)
return print_insn_i386_att (memaddr, info);
else if (disassembly_flavor == intel_flavor)
return print_insn_i386_intel (memaddr, info);
+#else
+ return print_insn_i386 (memaddr, info);
+#endif
}
void
diff --git a/contrib/gdb/gdb/i386b-nat.c b/contrib/gdb/gdb/i386b-nat.c
index 2645302..8749e81 100644
--- a/contrib/gdb/gdb/i386b-nat.c
+++ b/contrib/gdb/gdb/i386b-nat.c
@@ -57,7 +57,7 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, ignore)
char *core_reg_sect;
unsigned core_reg_size;
int which;
- unsigned int ignore;
+ CORE_ADDR ignore;
{
struct md_core *core_reg = (struct md_core *)core_reg_sect;
diff --git a/contrib/gdb/gdb/infptrace.c b/contrib/gdb/gdb/infptrace.c
index d266f00..b2eabbb 100644
--- a/contrib/gdb/gdb/infptrace.c
+++ b/contrib/gdb/gdb/infptrace.c
@@ -1,5 +1,6 @@
/* Low level Unix child interface to ptrace, for GDB when running under Unix.
- Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright 1988, 89, 90, 91, 92, 93, 94, 95, 96, 1998
+ Free Software Foundation, Inc.
This file is part of GDB.
@@ -33,13 +34,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <signal.h>
#include <sys/ioctl.h>
-#ifndef NO_PTRACE_H
-#ifdef PTRACE_IN_WRONG_PLACE
-#include <ptrace.h>
+#ifdef HAVE_PTRACE_H
+# include <ptrace.h>
#else
-#include <sys/ptrace.h>
+# ifdef HAVE_SYS_PTRACE_H
+# include <sys/ptrace.h>
+# endif
#endif
-#endif /* NO_PTRACE_H */
#if !defined (PT_READ_I)
#define PT_READ_I 1 /* Read word from text space */
@@ -94,6 +95,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#endif /* KERNEL_U_ADDR_BSD. */
#endif /* !FETCH_INFERIOR_REGISTERS */
+#if !defined (CHILD_XFER_MEMORY)
+static void udot_info PARAMS ((char *, int));
+#endif
+
+#if !defined (FETCH_INFERIOR_REGISTERS)
+static void fetch_register PARAMS ((int));
+static void store_register PARAMS ((int));
+#endif
+
+void _initialize_kernel_u_addr PARAMS ((void));
+void _initialize_infptrace PARAMS ((void));
+
/* This function simply calls ptrace with the given arguments.
It exists so that all calls to ptrace are isolated in this
@@ -104,34 +117,112 @@ call_ptrace (request, pid, addr, data)
PTRACE_ARG3_TYPE addr;
int data;
{
- return ptrace (request, pid, addr, data
+ int pt_status = 0;
+
+#if 0
+ int saved_errno;
+
+ printf ("call_ptrace(request=%d, pid=%d, addr=0x%x, data=0x%x)",
+ request, pid, addr, data);
+#endif
+#if defined(PT_SETTRC)
+ /* If the parent can be told to attach to us, try to do it. */
+ if (request == PT_SETTRC) {
+ errno = 0;
+ pt_status = ptrace (PT_SETTRC, pid, addr, data
+#if defined (FIVE_ARG_PTRACE)
+ /* Deal with HPUX 8.0 braindamage. We never use the
+ calls which require the fifth argument. */
+ , 0
+#endif
+ );
+
+ if (errno) perror_with_name ("ptrace");
+#if 0
+ printf (" = %d\n", pt_status);
+#endif
+ if (pt_status < 0)
+ return pt_status;
+ else
+ return parent_attach_all (pid, addr, data);
+ }
+#endif
+
+#if defined(PT_CONTIN1)
+ /* On HPUX, PT_CONTIN1 is a form of continue that preserves pending
+ signals. If it's available, use it. */
+ if (request == PT_CONTINUE)
+ request = PT_CONTIN1;
+#endif
+
+#if defined(PT_SINGLE1)
+ /* On HPUX, PT_SINGLE1 is a form of step that preserves pending
+ signals. If it's available, use it. */
+ if (request == PT_STEP)
+ request = PT_SINGLE1;
+#endif
+
+#if 0
+ saved_errno = errno;
+ errno = 0;
+#endif
+ pt_status = ptrace (request, pid, addr, data
#if defined (FIVE_ARG_PTRACE)
/* Deal with HPUX 8.0 braindamage. We never use the
calls which require the fifth argument. */
, 0
#endif
);
+#if 0
+ if (errno)
+ printf (" [errno = %d]", errno);
+
+ errno = saved_errno;
+ printf (" = 0x%x\n", pt_status);
+#endif
+ return pt_status;
}
+
#if defined (DEBUG_PTRACE) || defined (FIVE_ARG_PTRACE)
/* For the rest of the file, use an extra level of indirection */
/* This lets us breakpoint usefully on call_ptrace. */
#define ptrace call_ptrace
#endif
+/* Wait for a process to finish, possibly running a target-specific
+ hook before returning. */
+
+int
+ptrace_wait (pid, status)
+ int pid;
+ int *status;
+{
+ int wstate;
+
+ wstate = wait (status);
+ target_post_wait (wstate, *status);
+ return wstate;
+}
+
void
kill_inferior ()
{
+ int status;
+
if (inferior_pid == 0)
return;
- /* ptrace PT_KILL only works if process is stopped!!! So stop it with
- a real signal first, if we can. FIXME: This is bogus. When the inferior
- is not stopped, GDB should just be waiting for it. Either the following
- line is unecessary, or there is some problem elsewhere in GDB which
- causes us to get here when the inferior is not stopped. */
- kill (inferior_pid, SIGKILL);
+
+ /* This once used to call "kill" to kill the inferior just in case
+ the inferior was still running. As others have noted in the past
+ (kingdon) there shouldn't be any way to get here if the inferior
+ is still running -- else there's a major problem elsewere in gdb
+ and it needs to be fixed.
+
+ The kill call causes problems under hpux10, so it's been removed;
+ if this causes problems we'll deal with them as they arise. */
ptrace (PT_KILL, inferior_pid, (PTRACE_ARG3_TYPE) 0, 0);
- wait ((int *)0);
+ ptrace_wait (0, &status);
target_mourn_inferior ();
}
@@ -165,8 +256,13 @@ child_resume (pid, step, signal)
instructions), so we don't have to worry about that here. */
if (step)
- ptrace (PT_STEP, pid, (PTRACE_ARG3_TYPE) 1,
- target_signal_to_host (signal));
+ {
+ if (SOFTWARE_SINGLE_STEP_P)
+ abort(); /* Make sure this doesn't happen. */
+ else
+ ptrace (PT_STEP, pid, (PTRACE_ARG3_TYPE) 1,
+ target_signal_to_host (signal));
+ }
else
ptrace (PT_CONTINUE, pid, (PTRACE_ARG3_TYPE) 1,
target_signal_to_host (signal));
@@ -261,12 +357,10 @@ fetch_register (regno)
{
/* This isn't really an address. But ptrace thinks of it as one. */
CORE_ADDR regaddr;
- char buf[MAX_REGISTER_RAW_SIZE];
char mess[128]; /* For messages */
register int i;
-
- /* Offset of registers within the u area. */
- unsigned int offset;
+ unsigned int offset; /* Offset of registers within the u area. */
+ char buf[MAX_REGISTER_RAW_SIZE];
if (CANNOT_FETCH_REGISTER (regno))
{
@@ -286,7 +380,7 @@ fetch_register (regno)
regaddr += sizeof (PTRACE_XFER_TYPE);
if (errno != 0)
{
- sprintf (mess, "reading register %s (#%d)", reg_names[regno], regno);
+ sprintf (mess, "reading register %s (#%d)", REGISTER_NAME (regno), regno);
perror_with_name (mess);
}
}
@@ -294,22 +388,25 @@ fetch_register (regno)
}
-/* Fetch all registers, or just one, from the child process. */
+/* Fetch register values from the inferior.
+ If REGNO is negative, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
void
fetch_inferior_registers (regno)
int regno;
{
- int numregs;
-
- if (regno == -1)
+ if (regno >= 0)
{
- numregs = ARCH_NUM_REGS;
- for (regno = 0; regno < numregs; regno++)
- fetch_register (regno);
+ fetch_register (regno);
}
else
- fetch_register (regno);
+ {
+ for (regno = 0; regno < ARCH_NUM_REGS; regno++)
+ {
+ fetch_register (regno);
+ }
+ }
}
/* Registers we shouldn't try to store. */
@@ -317,57 +414,57 @@ fetch_inferior_registers (regno)
#define CANNOT_STORE_REGISTER(regno) 0
#endif
-/* Store our register values back into the inferior.
- If REGNO is -1, do this for all registers.
- Otherwise, REGNO specifies which register (so we can save time). */
+/* Store one register. */
-void
-store_inferior_registers (regno)
+static void
+store_register (regno)
int regno;
{
/* This isn't really an address. But ptrace thinks of it as one. */
CORE_ADDR regaddr;
- char buf[80];
- register int i, numregs;
+ char mess[128]; /* For messages */
+ register int i;
+ unsigned int offset; /* Offset of registers within the u area. */
- unsigned int offset = U_REGS_OFFSET;
+ if (CANNOT_STORE_REGISTER (regno))
+ {
+ return;
+ }
- if (regno >= 0)
+ offset = U_REGS_OFFSET;
+
+ regaddr = register_addr (regno, offset);
+ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(PTRACE_XFER_TYPE))
{
- regaddr = register_addr (regno, offset);
- for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(PTRACE_XFER_TYPE))
+ errno = 0;
+ ptrace (PT_WRITE_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
+ *(PTRACE_XFER_TYPE *) &registers[REGISTER_BYTE (regno) + i]);
+ regaddr += sizeof (PTRACE_XFER_TYPE);
+ if (errno != 0)
{
- errno = 0;
- ptrace (PT_WRITE_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
- *(PTRACE_XFER_TYPE *) &registers[REGISTER_BYTE (regno) + i]);
- if (errno != 0)
- {
- sprintf (buf, "writing register number %d(%d)", regno, i);
- perror_with_name (buf);
- }
- regaddr += sizeof(PTRACE_XFER_TYPE);
+ sprintf (mess, "writing register %s (#%d)", REGISTER_NAME (regno), regno);
+ perror_with_name (mess);
}
}
+}
+
+/* Store our register values back into the inferior.
+ If REGNO is negative, do this for all registers.
+ Otherwise, REGNO specifies which register (so we can save time). */
+
+void
+store_inferior_registers (regno)
+ int regno;
+{
+ if (regno >= 0)
+ {
+ store_register (regno);
+ }
else
{
- numregs = ARCH_NUM_REGS;
- for (regno = 0; regno < numregs; regno++)
+ for (regno = 0; regno < ARCH_NUM_REGS; regno++)
{
- if (CANNOT_STORE_REGISTER (regno))
- continue;
- regaddr = register_addr (regno, offset);
- for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(PTRACE_XFER_TYPE))
- {
- errno = 0;
- ptrace (PT_WRITE_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
- *(PTRACE_XFER_TYPE *) &registers[REGISTER_BYTE (regno) + i]);
- if (errno != 0)
- {
- sprintf (buf, "writing register number %d(%d)", regno, i);
- perror_with_name (buf);
- }
- regaddr += sizeof(PTRACE_XFER_TYPE);
- }
+ store_register (regno);
}
}
}
@@ -442,7 +539,7 @@ child_xfer_memory (memaddr, myaddr, len, write, target)
ptrace (PT_WRITE_D, inferior_pid, (PTRACE_ARG3_TYPE) addr,
buffer[i]);
if (errno)
- {
+ {
/* Using the appropriate one (I or D) is necessary for
Gould NP1, at least. */
errno = 0;
@@ -452,6 +549,9 @@ child_xfer_memory (memaddr, myaddr, len, write, target)
if (errno)
return 0;
}
+#ifdef CLEAR_INSN_CACHE
+ CLEAR_INSN_CACHE();
+#endif
}
else
{
@@ -476,11 +576,15 @@ child_xfer_memory (memaddr, myaddr, len, write, target)
static void
-udot_info ()
+udot_info (dummy1, dummy2)
+ char *dummy1;
+ int dummy2;
{
+#if defined (KERNEL_U_SIZE)
int udot_off; /* Offset into user struct */
int udot_val; /* Value from user struct at udot_off */
char mess[128]; /* For messages */
+#endif
if (!target_has_execution)
{
diff --git a/contrib/gdb/gdb/main.c b/contrib/gdb/gdb/main.c
index 18c2445..1733e10 100644
--- a/contrib/gdb/gdb/main.c
+++ b/contrib/gdb/gdb/main.c
@@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include <setjmp.h>
+#include <unistd.h>
#include "top.h"
#include "target.h"
#include "inferior.h"
diff --git a/contrib/gdb/gdb/objfiles.c b/contrib/gdb/gdb/objfiles.c
index 97b05dc..971a7d4 100644
--- a/contrib/gdb/gdb/objfiles.c
+++ b/contrib/gdb/gdb/objfiles.c
@@ -37,7 +37,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Prototypes for local functions */
-#if !defined(NO_MMALLOC) && defined(HAVE_MMAP)
+#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
static int
open_existing_mapped_file PARAMS ((char *, long, int));
@@ -45,10 +45,13 @@ open_existing_mapped_file PARAMS ((char *, long, int));
static int
open_mapped_file PARAMS ((char *filename, long mtime, int mapped));
-static CORE_ADDR
-map_to_address PARAMS ((void));
+static PTR
+map_to_file PARAMS ((int));
-#endif /* !defined(NO_MMALLOC) && defined(HAVE_MMAP) */
+#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */
+
+static void
+add_to_objfile_sections PARAMS ((bfd *, sec_ptr, PTR));
/* Externally visible variables that are owned by this module.
See declarations in objfile.h for more info. */
@@ -64,6 +67,10 @@ int mapped_symbol_files; /* Try to use mapped symbol files */
objfile_p_char is a char * to get it through
bfd_map_over_sections; we cast it back to its proper type. */
+#ifndef TARGET_KEEP_SECTION
+#define TARGET_KEEP_SECTION(ASECT) 0
+#endif
+
static void
add_to_objfile_sections (abfd, asect, objfile_p_char)
bfd *abfd;
@@ -75,13 +82,16 @@ add_to_objfile_sections (abfd, asect, objfile_p_char)
flagword aflag;
aflag = bfd_get_section_flags (abfd, asect);
- if (!(aflag & SEC_ALLOC))
+
+ if (!(aflag & SEC_ALLOC) && !(TARGET_KEEP_SECTION(asect)))
return;
+
if (0 == bfd_section_size (abfd, asect))
return;
section.offset = 0;
section.objfile = objfile;
section.the_bfd_section = asect;
+ section.ovly_mapped = 0;
section.addr = bfd_section_vma (abfd, asect);
section.endaddr = section.addr + bfd_section_size (abfd, asect);
obstack_grow (&objfile->psymbol_obstack, (char *) &section, sizeof(section));
@@ -113,19 +123,29 @@ build_objfile_section_table (objfile)
/* Given a pointer to an initialized bfd (ABFD) and a flag that indicates
whether or not an objfile is to be mapped (MAPPED), allocate a new objfile
struct, fill it in as best we can, link it into the list of all known
- objfiles, and return a pointer to the new objfile struct. */
+ objfiles, and return a pointer to the new objfile struct.
+
+ USER_LOADED is simply recorded in the objfile. This record offers a way for
+ run_command to remove old objfile entries which are no longer valid (i.e.,
+ are associated with an old inferior), but to preserve ones that the user
+ explicitly loaded via the add-symbol-file command.
+
+ IS_SOLIB is also simply recorded in the objfile. */
struct objfile *
-allocate_objfile (abfd, mapped)
+allocate_objfile (abfd, mapped, user_loaded, is_solib)
bfd *abfd;
int mapped;
+ int user_loaded;
+ int is_solib;
{
struct objfile *objfile = NULL;
struct objfile *last_one = NULL;
mapped |= mapped_symbol_files;
-#if !defined(NO_MMALLOC) && defined(HAVE_MMAP)
+#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
+ if (abfd != NULL)
{
/* If we can support mapped symbol files, try to open/reopen the
@@ -144,11 +164,9 @@ allocate_objfile (abfd, mapped)
mapped);
if (fd >= 0)
{
- CORE_ADDR mapto;
PTR md;
- if (((mapto = map_to_address ()) == 0) ||
- ((md = mmalloc_attach (fd, (PTR) mapto)) == NULL))
+ if ((md = map_to_file (fd)) == NULL)
{
close (fd);
}
@@ -209,7 +227,7 @@ allocate_objfile (abfd, mapped)
bfd_get_filename (abfd));
}
}
-#else /* defined(NO_MMALLOC) || !defined(HAVE_MMAP) */
+#else /* !defined(USE_MMALLOC) || !defined(HAVE_MMAP) */
if (mapped)
{
@@ -222,7 +240,7 @@ allocate_objfile (abfd, mapped)
mapped_symbol_files = 0;
}
-#endif /* !defined(NO_MMALLOC) && defined(HAVE_MMAP) */
+#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */
/* If we don't support mapped symbol files, didn't ask for the file to be
mapped, or failed to open the mapped file for some reason, then revert
@@ -252,15 +270,18 @@ allocate_objfile (abfd, mapped)
{
mfree (objfile -> md, objfile -> name);
}
- objfile -> name = mstrsave (objfile -> md, bfd_get_filename (abfd));
- objfile -> mtime = bfd_get_mtime (abfd);
+ if (abfd != NULL)
+ {
+ objfile -> name = mstrsave (objfile -> md, bfd_get_filename (abfd));
+ objfile -> mtime = bfd_get_mtime (abfd);
- /* Build section table. */
+ /* Build section table. */
- if (build_objfile_section_table (objfile))
- {
- error ("Can't find the file sections in `%s': %s",
- objfile -> name, bfd_errmsg (bfd_get_error ()));
+ if (build_objfile_section_table (objfile))
+ {
+ error ("Can't find the file sections in `%s': %s",
+ objfile -> name, bfd_errmsg (bfd_get_error ()));
+ }
}
/* Add this file onto the tail of the linked list of other such files. */
@@ -275,6 +296,15 @@ allocate_objfile (abfd, mapped)
last_one = last_one -> next);
last_one -> next = objfile;
}
+
+ /* Record whether this objfile was created because the user explicitly
+ caused it (e.g., used the add-symbol-file command).
+ */
+ objfile -> user_loaded = user_loaded;
+
+ /* Record whether this objfile definitely represents a solib. */
+ objfile -> is_solib = is_solib;
+
return (objfile);
}
@@ -410,7 +440,7 @@ free_objfile (objfile)
case. Note that the mmalloc_detach or the mfree is the last thing
we can do with this objfile. */
-#if !defined(NO_MMALLOC) && defined(HAVE_MMAP)
+#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
if (objfile -> flags & OBJF_MAPPED)
{
@@ -424,7 +454,7 @@ free_objfile (objfile)
close (mmfd);
}
-#endif /* !defined(NO_MMALLOC) && defined(HAVE_MMAP) */
+#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */
/* If we still have an objfile, then either we don't support reusable
objfiles or this one was not reusable. So free it normally. */
@@ -471,9 +501,9 @@ objfile_relocate (objfile, new_offsets)
struct objfile *objfile;
struct section_offsets *new_offsets;
{
- struct section_offsets *delta = (struct section_offsets *) alloca
- (sizeof (struct section_offsets)
- + objfile->num_sections * sizeof (delta->offsets));
+ struct section_offsets *delta = (struct section_offsets *)
+ alloca (sizeof (struct section_offsets)
+ + objfile->num_sections * sizeof (delta->offsets));
{
int i;
@@ -519,7 +549,7 @@ objfile_relocate (objfile, new_offsets)
b = BLOCKVECTOR_BLOCK (bv, i);
BLOCK_START (b) += ANOFFSET (delta, s->block_line_section);
- BLOCK_END (b) += ANOFFSET (delta, s->block_line_section);
+ BLOCK_END (b) += ANOFFSET (delta, s->block_line_section);
for (j = 0; j < BLOCK_NSYMS (b); ++j)
{
@@ -529,10 +559,11 @@ objfile_relocate (objfile, new_offsets)
But I'm leaving out that test, on the theory that
they can't possibly pass the tests below. */
if ((SYMBOL_CLASS (sym) == LOC_LABEL
- || SYMBOL_CLASS (sym) == LOC_STATIC)
+ || SYMBOL_CLASS (sym) == LOC_STATIC
+ || SYMBOL_CLASS (sym) == LOC_INDIRECT)
&& SYMBOL_SECTION (sym) >= 0)
{
- SYMBOL_VALUE_ADDRESS (sym) +=
+ SYMBOL_VALUE_ADDRESS (sym) +=
ANOFFSET (delta, SYMBOL_SECTION (sym));
}
#ifdef MIPS_EFI_SYMBOL_NAME
@@ -542,7 +573,8 @@ objfile_relocate (objfile, new_offsets)
if (SYMBOL_CLASS (sym) == LOC_CONST
&& SYMBOL_NAMESPACE (sym) == LABEL_NAMESPACE
&& STRCMP (SYMBOL_NAME (sym), MIPS_EFI_SYMBOL_NAME) == 0)
- ecoff_relocate_efi (sym, ANOFFSET (delta, s->block_line_section));
+ ecoff_relocate_efi (sym, ANOFFSET (delta,
+ s->block_line_section));
#endif
}
}
@@ -566,12 +598,14 @@ objfile_relocate (objfile, new_offsets)
psym < objfile->global_psymbols.next;
psym++)
if (SYMBOL_SECTION (*psym) >= 0)
- SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta, SYMBOL_SECTION (*psym));
+ SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
+ SYMBOL_SECTION (*psym));
for (psym = objfile->static_psymbols.list;
psym < objfile->static_psymbols.next;
psym++)
if (SYMBOL_SECTION (*psym) >= 0)
- SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta, SYMBOL_SECTION (*psym));
+ SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
+ SYMBOL_SECTION (*psym));
}
{
@@ -605,42 +639,45 @@ objfile_relocate (objfile, new_offsets)
if (flags & SEC_CODE)
{
- s->addr += ANOFFSET (delta, SECT_OFF_TEXT);
+ s->addr += ANOFFSET (delta, SECT_OFF_TEXT);
s->endaddr += ANOFFSET (delta, SECT_OFF_TEXT);
}
else if (flags & (SEC_DATA | SEC_LOAD))
{
- s->addr += ANOFFSET (delta, SECT_OFF_DATA);
+ s->addr += ANOFFSET (delta, SECT_OFF_DATA);
s->endaddr += ANOFFSET (delta, SECT_OFF_DATA);
}
else if (flags & SEC_ALLOC)
{
- s->addr += ANOFFSET (delta, SECT_OFF_BSS);
+ s->addr += ANOFFSET (delta, SECT_OFF_BSS);
s->endaddr += ANOFFSET (delta, SECT_OFF_BSS);
}
}
}
- if (objfile->ei.entry_point != ~0)
+ if (objfile->ei.entry_point != ~(CORE_ADDR)0)
objfile->ei.entry_point += ANOFFSET (delta, SECT_OFF_TEXT);
if (objfile->ei.entry_func_lowpc != INVALID_ENTRY_LOWPC)
{
- objfile->ei.entry_func_lowpc += ANOFFSET (delta, SECT_OFF_TEXT);
+ objfile->ei.entry_func_lowpc += ANOFFSET (delta, SECT_OFF_TEXT);
objfile->ei.entry_func_highpc += ANOFFSET (delta, SECT_OFF_TEXT);
}
if (objfile->ei.entry_file_lowpc != INVALID_ENTRY_LOWPC)
{
- objfile->ei.entry_file_lowpc += ANOFFSET (delta, SECT_OFF_TEXT);
+ objfile->ei.entry_file_lowpc += ANOFFSET (delta, SECT_OFF_TEXT);
objfile->ei.entry_file_highpc += ANOFFSET (delta, SECT_OFF_TEXT);
}
if (objfile->ei.main_func_lowpc != INVALID_ENTRY_LOWPC)
{
- objfile->ei.main_func_lowpc += ANOFFSET (delta, SECT_OFF_TEXT);
+ objfile->ei.main_func_lowpc += ANOFFSET (delta, SECT_OFF_TEXT);
objfile->ei.main_func_highpc += ANOFFSET (delta, SECT_OFF_TEXT);
}
+
+ /* Relocate breakpoints as necessary, after things are relocated. */
+ breakpoint_re_set ();
}
/* Many places in gdb want to test just to see if we have any partial
@@ -681,6 +718,28 @@ have_full_symbols ()
return 0;
}
+
+/* This operations deletes all objfile entries that represent solibs that
+ weren't explicitly loaded by the user, via e.g., the add-symbol-file
+ command.
+ */
+void
+objfile_purge_solibs ()
+{
+ struct objfile * objf;
+ struct objfile * temp;
+
+ ALL_OBJFILES_SAFE (objf, temp)
+ {
+ /* We assume that the solib package has been purged already, or will
+ be soon.
+ */
+ if (! objf->user_loaded && objf->is_solib)
+ free_objfile (objf);
+ }
+}
+
+
/* Many places in gdb want to test just to see if we have any minimal
symbols available. This function returns zero if none are currently
available, nonzero otherwise. */
@@ -700,7 +759,7 @@ have_minimal_symbols ()
return 0;
}
-#if !defined(NO_MMALLOC) && defined(HAVE_MMAP)
+#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
/* Given the name of a mapped symbol file in SYMSFILENAME, and the timestamp
of the corresponding symbol file in MTIME, try to open an existing file
@@ -824,72 +883,90 @@ open_mapped_file (filename, mtime, mapped)
return (fd);
}
-/* Return the base address at which we would like the next objfile's
- mapped data to start.
-
- For now, we use the kludge that the configuration specifies a base
- address to which it is safe to map the first mmalloc heap, and an
- increment to add to this address for each successive heap. There are
- a lot of issues to deal with here to make this work reasonably, including:
-
- Avoid memory collisions with existing mapped address spaces
-
- Reclaim address spaces when their mmalloc heaps are unmapped
-
- When mmalloc heaps are shared between processes they have to be
- mapped at the same addresses in each
-
- Once created, a mmalloc heap that is to be mapped back in must be
- mapped at the original address. I.E. each objfile will expect to
- be remapped at it's original address. This becomes a problem if
- the desired address is already in use.
-
- etc, etc, etc.
-
- */
-
-
-static CORE_ADDR
-map_to_address ()
+static PTR
+map_to_file (fd)
+ int fd;
{
+ PTR md;
+ CORE_ADDR mapto;
-#if defined(MMAP_BASE_ADDRESS) && defined (MMAP_INCREMENT)
-
- static CORE_ADDR next = MMAP_BASE_ADDRESS;
- CORE_ADDR mapto = next;
-
- next += MMAP_INCREMENT;
- return (mapto);
-
-#else
-
- warning ("need to recompile gdb with MMAP_BASE_ADDRESS and MMAP_INCREMENT defined");
- return (0);
-
-#endif
-
+ md = mmalloc_attach (fd, (PTR) 0);
+ if (md != NULL)
+ {
+ mapto = (CORE_ADDR) mmalloc_getkey (md, 1);
+ md = mmalloc_detach (md);
+ if (md != NULL)
+ {
+ /* FIXME: should figure out why detach failed */
+ md = NULL;
+ }
+ else if (mapto != (CORE_ADDR) NULL)
+ {
+ /* This mapping file needs to be remapped at "mapto" */
+ md = mmalloc_attach (fd, (PTR) mapto);
+ }
+ else
+ {
+ /* This is a freshly created mapping file. */
+ mapto = (CORE_ADDR) mmalloc_findbase (20 * 1024 * 1024);
+ if (mapto != 0)
+ {
+ /* To avoid reusing the freshly created mapping file, at the
+ address selected by mmap, we must truncate it before trying
+ to do an attach at the address we want. */
+ ftruncate (fd, 0);
+ md = mmalloc_attach (fd, (PTR) mapto);
+ if (md != NULL)
+ {
+ mmalloc_setkey (md, 1, (PTR) mapto);
+ }
+ }
+ }
+ }
+ return (md);
}
-#endif /* !defined(NO_MMALLOC) && defined(HAVE_MMAP) */
+#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */
-/* Returns a section whose range includes PC or NULL if none found. */
+/* Returns a section whose range includes PC and SECTION,
+ or NULL if none found. Note the distinction between the return type,
+ struct obj_section (which is defined in gdb), and the input type
+ struct sec (which is a bfd-defined data type). The obj_section
+ contains a pointer to the bfd struct sec section. */
struct obj_section *
-find_pc_section(pc)
+find_pc_sect_section (pc, section)
CORE_ADDR pc;
+ struct sec *section;
{
struct obj_section *s;
struct objfile *objfile;
ALL_OBJFILES (objfile)
for (s = objfile->sections; s < objfile->sections_end; ++s)
- if (s->addr <= pc
- && pc < s->endaddr)
+#if defined(HPUXHPPA)
+ if ((section == 0 || section == s->the_bfd_section) &&
+ s->addr <= pc && pc <= s->endaddr)
+#else
+ if ((section == 0 || section == s->the_bfd_section) &&
+ s->addr <= pc && pc < s->endaddr)
+#endif
return(s);
return(NULL);
}
+/* Returns a section whose range includes PC or NULL if none found.
+ Backward compatibility, no section. */
+
+struct obj_section *
+find_pc_section(pc)
+ CORE_ADDR pc;
+{
+ return find_pc_sect_section (pc, find_pc_mapped_section (pc));
+}
+
+
/* In SVR4, we recognize a trampoline by it's section name.
That is, if the pc is in a section named ".plt" then we are in
a trampoline. */
diff --git a/contrib/gdb/gdb/partial-stab.h b/contrib/gdb/gdb/partial-stab.h
index d74c1c9..acff4c6 100644
--- a/contrib/gdb/gdb/partial-stab.h
+++ b/contrib/gdb/gdb/partial-stab.h
@@ -795,7 +795,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
case N_LBRAC:
case N_NSYMS: /* Ultrix 4.0: symbol count */
case N_DEFD: /* GNU Modula-2 */
+#if 0 /* XXX remove when binutils 2.9.2 is imported */
case N_ALIAS: /* SunPro F77: alias name, ignore for now. */
+#endif
case N_OBJ: /* useless types from Solaris */
case N_OPT:
diff --git a/contrib/gdb/gdb/remote.c b/contrib/gdb/gdb/remote.c
index ab4ccf2..81c23fc 100644
--- a/contrib/gdb/gdb/remote.c
+++ b/contrib/gdb/gdb/remote.c
@@ -1,5 +1,6 @@
/* Remote target communications for serial-line targets in custom GDB protocol
- Copyright 1988, 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright 1988, 91, 92, 93, 94, 95, 96, 97, 1998
+ Free Software Foundation, Inc.
This file is part of GDB.
@@ -89,6 +90,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
where only part of the data was
written).
+ write mem XAA..AA,LLLL:XX..XX
+ (binary) AA..AA is address,
+ LLLL is number of bytes,
+ XX..XX is binary data
+ reply OK for success
+ ENN for an error
+
continue cAA..AA AA..AA is address to resume
If AA..AA is omitted,
resume at same address.
@@ -97,10 +105,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
If AA..AA is omitted,
resume at same address.
- continue with Csig;AA Continue with signal sig (hex signal
- signal number).
+ continue with Csig;AA..AA Continue with signal sig (hex signal
+ signal number). If ;AA..AA is omitted,
+ resume at same address.
- step with Ssig;AA Like 'C' but step not continue.
+ step with Ssig;AA..AA Like 'C' but step not continue.
signal
last signal ? Reply the current reason for stopping.
@@ -133,9 +142,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
or... XAA The process terminated with signal
AA.
or... OXX..XX XX..XX is hex encoding of ASCII data. This
- can happen at any time while the program is
- running and the debugger should
- continue to wait for 'W', 'T', etc.
+ can happen at any time while the
+ program is running and the debugger
+ should continue to wait for
+ 'W', 'T', etc.
thread alive TXX Find out if the thread XX is alive.
reply OK thread is still alive
@@ -177,6 +187,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "gdb_string.h"
+#include <ctype.h>
#include <fcntl.h>
#include "frame.h"
#include "inferior.h"
@@ -188,7 +199,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "gdbcmd.h"
#include "objfiles.h"
#include "gdb-stabs.h"
-#include "thread.h"
+#include "gdbthread.h"
#include "dcache.h"
@@ -209,9 +220,9 @@ static int remote_read_bytes PARAMS ((CORE_ADDR memaddr,
static void remote_files_info PARAMS ((struct target_ops *ignore));
-static int remote_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
+static int remote_xfer_memory PARAMS ((CORE_ADDR memaddr, char * myaddr,
int len, int should_write,
- struct target_ops *target));
+ struct target_ops * target));
static void remote_prepare_to_store PARAMS ((void));
@@ -220,13 +231,14 @@ static void remote_fetch_registers PARAMS ((int regno));
static void remote_resume PARAMS ((int pid, int step,
enum target_signal siggnal));
-static int remote_start_remote PARAMS ((char *dummy));
+static int remote_start_remote PARAMS ((PTR));
static void remote_open PARAMS ((char *name, int from_tty));
static void extended_remote_open PARAMS ((char *name, int from_tty));
-static void remote_open_1 PARAMS ((char *, int, struct target_ops *));
+static void remote_open_1 PARAMS ((char *, int, struct target_ops *,
+ int extended_p));
static void remote_close PARAMS ((int quitting));
@@ -242,39 +254,174 @@ static void extended_remote_create_inferior PARAMS ((char *, char *, char **));
static void remote_mourn_1 PARAMS ((struct target_ops *));
-static void getpkt PARAMS ((char *buf, int forever));
-
-static int putpkt PARAMS ((char *buf));
-
static void remote_send PARAMS ((char *buf));
static int readchar PARAMS ((int timeout));
-static int remote_wait PARAMS ((int pid, struct target_waitstatus *status));
+static int remote_wait PARAMS ((int pid, struct target_waitstatus * status));
static void remote_kill PARAMS ((void));
static int tohex PARAMS ((int nib));
-static int fromhex PARAMS ((int a));
-
static void remote_detach PARAMS ((char *args, int from_tty));
static void remote_interrupt PARAMS ((int signo));
-static void remote_interrupt_twice PARAMS ((int signo));
-
static void interrupt_query PARAMS ((void));
-extern struct target_ops remote_ops; /* Forward decl */
-extern struct target_ops extended_remote_ops; /* Forward decl */
+static void set_thread PARAMS ((int, int));
+
+static int remote_thread_alive PARAMS ((int));
+
+static void get_offsets PARAMS ((void));
+
+static int read_frame PARAMS ((char *));
+
+static int remote_insert_breakpoint PARAMS ((CORE_ADDR, char *));
+
+static int remote_remove_breakpoint PARAMS ((CORE_ADDR, char *));
+
+static int hexnumlen PARAMS ((ULONGEST num));
+
+static void init_remote_ops PARAMS ((void));
+
+static void init_extended_remote_ops PARAMS ((void));
+
+static void remote_stop PARAMS ((void));
+
+static int ishex PARAMS ((int ch, int *val));
+
+static int stubhex PARAMS ((int ch));
+
+static int remote_query PARAMS ((int/*char*/, char *, char *, int *));
+
+static int hexnumstr PARAMS ((char *, ULONGEST));
+
+static CORE_ADDR remote_address_masked PARAMS ((CORE_ADDR));
+
+static void print_packet PARAMS ((char *));
+
+static unsigned long crc32 PARAMS ((unsigned char *, int, unsigned int));
+
+static void compare_sections_command PARAMS ((char *, int));
+
+static void packet_command PARAMS ((char *, int));
+
+static int stub_unpack_int PARAMS ((char *buff, int fieldlength));
+
+char *unpack_varlen_hex PARAMS ((char *buff, int *result));
+
+static char *unpack_nibble PARAMS ((char *buf, int *val));
+
+static char *pack_nibble PARAMS ((char *buf, int nibble));
+
+static char *pack_hex_byte PARAMS ((char *pkt, int/*unsigned char*/ byte));
+
+static char *unpack_byte PARAMS ((char *buf, int *value));
+
+static char *pack_int PARAMS ((char *buf, int value));
+
+static char *unpack_int PARAMS ((char *buf, int *value));
+
+static char *unpack_string PARAMS ((char *src, char *dest, int length));
+
+static char *pack_threadid PARAMS ((char *pkt, threadref *id));
+
+static char *unpack_threadid PARAMS ((char *inbuf, threadref *id));
+
+void int_to_threadref PARAMS ((threadref *id, int value));
+
+static int threadref_to_int PARAMS ((threadref *ref));
+
+static void copy_threadref PARAMS ((threadref *dest, threadref *src));
+
+static int threadmatch PARAMS ((threadref *dest, threadref *src));
+
+static char *pack_threadinfo_request PARAMS ((char *pkt, int mode,
+ threadref *id));
+
+static int remote_unpack_thread_info_response PARAMS ((char *pkt,
+ threadref *expectedref,
+ struct gdb_ext_thread_info *info));
+
+
+static int remote_get_threadinfo PARAMS ((threadref *threadid,
+ int fieldset, /*TAG mask */
+ struct gdb_ext_thread_info *info));
+
+static int adapt_remote_get_threadinfo PARAMS ((gdb_threadref *ref,
+ int selection,
+ struct gdb_ext_thread_info *info));
+
+static char *pack_threadlist_request PARAMS ((char *pkt, int startflag,
+ int threadcount,
+ threadref *nextthread));
+
+static int parse_threadlist_response PARAMS ((char *pkt,
+ int result_limit,
+ threadref *original_echo,
+ threadref *resultlist,
+ int *doneflag));
+
+static int remote_get_threadlist PARAMS ((int startflag,
+ threadref *nextthread,
+ int result_limit,
+ int *done,
+ int *result_count,
+ threadref *threadlist));
+
+typedef int (*rmt_thread_action) (threadref *ref, void *context);
+
+static int remote_threadlist_iterator PARAMS ((rmt_thread_action stepfunction,
+ void *context, int looplimit));
+
+static int remote_newthread_step PARAMS ((threadref *ref, void *context));
+
+static int remote_current_thread PARAMS ((int oldpid));
+
+int remote_find_new_threads PARAMS ((void));
+
+static void record_currthread PARAMS ((int currthread));
+
+static void init_remote_threads PARAMS ((void));
+
+/* exported functions */
+
+extern int fromhex PARAMS ((int a));
+
+extern void getpkt PARAMS ((char *buf, int forever));
+
+extern int putpkt PARAMS ((char *buf));
+
+static int putpkt_binary PARAMS ((char *buf, int cnt));
+
+void remote_console_output PARAMS ((char *));
+
+static void check_binary_download PARAMS ((CORE_ADDR addr));
+
+/* Define the target subroutine names */
+
+void open_remote_target PARAMS ((char *, int, struct target_ops *, int));
+
+void _initialize_remote PARAMS ((void));
+
+/* */
+
+static struct target_ops remote_ops;
+
+static struct target_ops extended_remote_ops;
+
+static struct target_thread_vector remote_thread_vec;
/* This was 5 seconds, which is a long time to sit and wait.
Unless this is going though some terminal server or multiplexer or
other form of hairy serial connection, I would think 2 seconds would
be plenty. */
-static int remote_timeout = 2;
+/* Changed to allow option to set timeout value.
+ was static int remote_timeout = 2; */
+extern int remote_timeout;
/* This variable chooses whether to send a ^C or a break when the user
requests program interruption. Although ^C is usually what remote
@@ -283,10 +430,26 @@ static int remote_timeout = 2;
static int remote_break;
+/* Has the user attempted to interrupt the target? If so, then offer
+ the user the opportunity to bail out completely if he interrupts
+ again. */
+static int interrupted_already = 0;
+
/* Descriptor for I/O to remote machine. Initialize it to NULL so that
remote_open knows that we don't have a file open when the program
starts. */
-serial_t remote_desc = NULL;
+static serial_t remote_desc = NULL;
+
+/* This variable (available to the user via "set remotebinarydownload")
+ dictates whether downloads are sent in binary (via the 'X' packet).
+ We assume that the stub can, and attempt to do it. This will be cleared if
+ the stub does not understand it. This switch is still needed, though
+ in cases when the packet is supported in the stub, but the connection
+ does not allow it (i.e., 7-bit serial connection only). */
+static int remote_binary_download = 1;
+
+/* Have we already checked whether binary downloads work? */
+static int remote_binary_checked;
/* Having this larger than 400 causes us to be incompatible with m68k-stub.c
and i386-stub.c. Normally, no one would notice because it only matters
@@ -308,10 +471,43 @@ serial_t remote_desc = NULL;
#define PBUFSIZ (REGISTER_BYTES * 2 + 32)
#endif
+/* This variable sets the number of bytes to be written to the target
+ in a single packet. Normally PBUFSIZ is satisfactory, but some
+ targets need smaller values (perhaps because the receiving end
+ is slow). */
+
+static int remote_write_size = PBUFSIZ;
+
+/* This variable sets the number of bits in an address that are to be
+ sent in a memory ("M" or "m") packet. Normally, after stripping
+ leading zeros, the entire address would be sent. This variable
+ restricts the address to REMOTE_ADDRESS_SIZE bits. HISTORY: The
+ initial implementation of remote.c restricted the address sent in
+ memory packets to ``host::sizeof long'' bytes - (typically 32
+ bits). Consequently, for 64 bit targets, the upper 32 bits of an
+ address was never sent. Since fixing this bug may cause a break in
+ some remote targets this variable is principly provided to
+ facilitate backward compatibility. */
+
+static int remote_address_size;
+
+/* This is the size (in chars) of the first response to the `g' command. This
+ is used to limit the size of the memory read and write commands to prevent
+ stub buffers from overflowing. The size does not include headers and
+ trailers, it is only the payload size. */
+
+static int remote_register_buf_size = 0;
+
/* Should we try the 'P' request? If this is set to one when the stub
doesn't support 'P', the only consequence is some unnecessary traffic. */
static int stub_supports_P = 1;
+/* These are pointers to hook functions that may be set in order to
+ modify resume/wait behavior for a particular architecture. */
+
+void (*target_resume_hook) PARAMS ((void));
+void (*target_wait_loop_hook) PARAMS ((void));
+
/*
* Support for quasi-interactive control of device through GDB port.
@@ -490,10 +686,36 @@ remote_talk()
#endif /* REMOTE_CHAT */
-/* These are the threads which we last sent to the remote system. -1 for all
- or -2 for not sent yet. */
-int general_thread;
-int cont_thread;
+/* These are the threads which we last sent to the remote system.
+ -1 for all or -2 for not sent yet. */
+static int general_thread;
+static int cont_thread;
+
+/* Call this function as a result of
+ 1) A halt indication (T packet) containing a thread id
+ 2) A direct query of currthread
+ 3) Successful execution of set thread
+ */
+
+static void
+record_currthread (currthread)
+ int currthread;
+{
+#if 0 /* target_wait must not modify inferior_pid! */
+ inferior_pid = currthread;
+#endif
+ general_thread = currthread;
+#if 0 /* setting cont_thread has a different meaning
+ from having the target report its thread id. */
+ cont_thread = currthread;
+#endif
+ /* If this is a new thread, add it to GDB's thread list.
+ If we leave it up to WFI to do this, bad things will happen. */
+ if (!in_thread_list (currthread))
+ add_thread (currthread);
+}
+
+#define MAGIC_NULL_PID 42000
static void
set_thread (th, gen)
@@ -502,11 +724,13 @@ set_thread (th, gen)
{
char buf[PBUFSIZ];
int state = gen ? general_thread : cont_thread;
+
if (state == th)
return;
+
buf[0] = 'H';
buf[1] = gen ? 'g' : 'c';
- if (th == 42000)
+ if (th == MAGIC_NULL_PID)
{
buf[2] = '0';
buf[3] = '\0';
@@ -533,14 +757,681 @@ remote_thread_alive (th)
buf[0] = 'T';
if (th < 0)
- sprintf (&buf[1], "-%x", -th);
+ sprintf (&buf[1], "-%08x", -th);
else
- sprintf (&buf[1], "%x", th);
+ sprintf (&buf[1], "%08x", th);
putpkt (buf);
getpkt (buf, 0);
return (buf[0] == 'O' && buf[1] == 'K');
}
+/* About these extended threadlist and threadinfo packets. They are
+ variable length packets but, the fields within them are often fixed
+ length. They are redundent enough to send over UDP as is the
+ remote protocol in general. There is a matching unit test module
+ in libstub. */
+
+#define BUF_THREAD_ID_SIZE (OPAQUETHREADBYTES*2)
+
+/* encode 64 bits in 16 chars of hex */
+
+static const char hexchars[] = "0123456789abcdef";
+
+static int
+ishex (ch, val)
+ int ch;
+ int *val;
+{
+ if ((ch >= 'a') && (ch <= 'f'))
+ {
+ *val = ch - 'a' + 10;
+ return 1;
+ }
+ if ((ch >= 'A') && (ch <= 'F'))
+ {
+ *val = ch - 'A' + 10;
+ return 1;
+ }
+ if ((ch >= '0') && (ch <= '9'))
+ {
+ *val = ch - '0';
+ return 1;
+ }
+ return 0;
+}
+
+static int
+stubhex (ch)
+ int ch;
+{
+ if (ch >= 'a' && ch <= 'f')
+ return ch - 'a' + 10;
+ if (ch >= '0' && ch <= '9')
+ return ch - '0';
+ if (ch >= 'A' && ch <= 'F')
+ return ch - 'A' + 10;
+ return -1;
+}
+
+static int
+stub_unpack_int (buff, fieldlength)
+ char *buff;
+ int fieldlength;
+{
+ int nibble;
+ int retval = 0;
+
+ while (fieldlength)
+ {
+ nibble = stubhex (*buff++);
+ retval |= nibble;
+ fieldlength--;
+ if (fieldlength)
+ retval = retval << 4;
+ }
+ return retval;
+}
+
+char *
+unpack_varlen_hex (buff, result)
+ char *buff; /* packet to parse */
+ int *result;
+{
+ int nibble;
+ int retval = 0;
+
+ while (ishex (*buff, &nibble))
+ {
+ buff++;
+ retval = retval << 4;
+ retval |= nibble & 0x0f;
+ }
+ *result = retval;
+ return buff;
+}
+
+static char *
+unpack_nibble (buf, val)
+ char *buf;
+ int *val;
+{
+ ishex (*buf++, val);
+ return buf;
+}
+
+static char *
+pack_nibble (buf, nibble)
+ char *buf;
+ int nibble;
+{
+ *buf++ = hexchars[(nibble & 0x0f)];
+ return buf;
+}
+
+static char *
+pack_hex_byte (pkt, byte)
+ char *pkt;
+ int byte;
+{
+ *pkt++ = hexchars[(byte >> 4) & 0xf];
+ *pkt++ = hexchars[(byte & 0xf)];
+ return pkt;
+}
+
+static char *
+unpack_byte (buf, value)
+ char *buf;
+ int *value;
+{
+ *value = stub_unpack_int (buf, 2);
+ return buf + 2;
+}
+
+static char *
+pack_int (buf, value)
+ char *buf;
+ int value;
+{
+ buf = pack_hex_byte (buf, (value >> 24) & 0xff);
+ buf = pack_hex_byte (buf, (value >> 16) & 0xff);
+ buf = pack_hex_byte (buf, (value >> 8) & 0x0ff);
+ buf = pack_hex_byte (buf, (value & 0xff));
+ return buf;
+}
+
+static char *
+unpack_int (buf, value)
+ char *buf;
+ int *value;
+{
+ *value = stub_unpack_int (buf, 8);
+ return buf + 8;
+}
+
+#if 0 /* currently unused, uncomment when needed */
+static char *pack_string PARAMS ((char *pkt, char *string));
+
+static char *
+pack_string (pkt, string)
+ char *pkt;
+ char *string;
+{
+ char ch;
+ int len;
+
+ len = strlen (string);
+ if (len > 200)
+ len = 200; /* Bigger than most GDB packets, junk??? */
+ pkt = pack_hex_byte (pkt, len);
+ while (len-- > 0)
+ {
+ ch = *string++;
+ if ((ch == '\0') || (ch == '#'))
+ ch = '*'; /* Protect encapsulation */
+ *pkt++ = ch;
+ }
+ return pkt;
+}
+#endif /* 0 (unused) */
+
+static char *
+unpack_string (src, dest, length)
+ char *src;
+ char *dest;
+ int length;
+{
+ while (length--)
+ *dest++ = *src++;
+ *dest = '\0';
+ return src;
+}
+
+static char *
+pack_threadid (pkt, id)
+ char *pkt;
+ threadref *id;
+{
+ char *limit;
+ unsigned char *altid;
+
+ altid = (unsigned char *) id;
+ limit = pkt + BUF_THREAD_ID_SIZE;
+ while (pkt < limit)
+ pkt = pack_hex_byte (pkt, *altid++);
+ return pkt;
+}
+
+
+static char *
+unpack_threadid (inbuf, id)
+ char *inbuf;
+ threadref *id;
+{
+ char *altref;
+ char *limit = inbuf + BUF_THREAD_ID_SIZE;
+ int x, y;
+
+ altref = (char *) id;
+
+ while (inbuf < limit)
+ {
+ x = stubhex (*inbuf++);
+ y = stubhex (*inbuf++);
+ *altref++ = (x << 4) | y;
+ }
+ return inbuf;
+}
+
+/* Externally, threadrefs are 64 bits but internally, they are still
+ ints. This is due to a mismatch of specifications. We would like
+ to use 64bit thread references internally. This is an adapter
+ function. */
+
+void
+int_to_threadref (id, value)
+ threadref *id;
+ int value;
+{
+ unsigned char *scan;
+
+ scan = (unsigned char *) id;
+ {
+ int i = 4;
+ while (i--)
+ *scan++ = 0;
+ }
+ *scan++ = (value >> 24) & 0xff;
+ *scan++ = (value >> 16) & 0xff;
+ *scan++ = (value >> 8) & 0xff;
+ *scan++ = (value & 0xff);
+}
+
+static int
+threadref_to_int (ref)
+ threadref *ref;
+{
+ int i, value = 0;
+ unsigned char *scan;
+
+ scan = (char *) ref;
+ scan += 4;
+ i = 4;
+ while (i-- > 0)
+ value = (value << 8) | ((*scan++) & 0xff);
+ return value;
+}
+
+static void
+copy_threadref (dest, src)
+ threadref *dest;
+ threadref *src;
+{
+ int i;
+ unsigned char *csrc, *cdest;
+
+ csrc = (unsigned char *) src;
+ cdest = (unsigned char *) dest;
+ i = 8;
+ while (i--)
+ *cdest++ = *csrc++;
+}
+
+static int
+threadmatch (dest, src)
+ threadref *dest;
+ threadref *src;
+{
+ /* things are broken right now, so just assume we got a match */
+#if 0
+ unsigned char *srcp, *destp;
+ int i, result;
+ srcp = (char *) src;
+ destp = (char *) dest;
+
+ result = 1;
+ while (i-- > 0)
+ result &= (*srcp++ == *destp++) ? 1 : 0;
+ return result;
+#endif
+ return 1;
+}
+
+/*
+ threadid:1, # always request threadid
+ context_exists:2,
+ display:4,
+ unique_name:8,
+ more_display:16
+*/
+
+/* Encoding: 'Q':8,'P':8,mask:32,threadid:64 */
+
+static char *
+pack_threadinfo_request (pkt, mode, id)
+ char *pkt;
+ int mode;
+ threadref *id;
+{
+ *pkt++ = 'q'; /* Info Query */
+ *pkt++ = 'P'; /* process or thread info */
+ pkt = pack_int (pkt, mode); /* mode */
+ pkt = pack_threadid (pkt, id); /* threadid */
+ *pkt = '\0'; /* terminate */
+ return pkt;
+}
+
+/* These values tag the fields in a thread info response packet */
+/* Tagging the fields allows us to request specific fields and to
+ add more fields as time goes by */
+
+#define TAG_THREADID 1 /* Echo the thread identifier */
+#define TAG_EXISTS 2 /* Is this process defined enough to
+ fetch registers and its stack */
+#define TAG_DISPLAY 4 /* A short thing maybe to put on a window */
+#define TAG_THREADNAME 8 /* string, maps 1-to-1 with a thread is */
+#define TAG_MOREDISPLAY 16 /* Whatever the kernel wants to say about
+ the process*/
+
+static int
+remote_unpack_thread_info_response (pkt, expectedref, info)
+ char *pkt;
+ threadref *expectedref;
+ struct gdb_ext_thread_info *info;
+{
+ int mask, length;
+ unsigned int tag;
+ threadref ref;
+ char *limit = pkt + PBUFSIZ; /* plausable parsing limit */
+ int retval = 1;
+
+ /* info->threadid = 0; FIXME: implement zero_threadref */
+ info->active = 0;
+ info->display[0] = '\0';
+ info->shortname[0] = '\0';
+ info->more_display[0] = '\0';
+
+ /* Assume the characters indicating the packet type have been stripped */
+ pkt = unpack_int (pkt, &mask); /* arg mask */
+ pkt = unpack_threadid (pkt, &ref);
+
+ if (mask == 0)
+ warning ("Incomplete response to threadinfo request\n");
+ if (!threadmatch (&ref, expectedref))
+ { /* This is an answer to a different request */
+ warning ("ERROR RMT Thread info mismatch\n");
+ return 0;
+ }
+ copy_threadref (&info->threadid, &ref);
+
+ /* Loop on tagged fields , try to bail if somthing goes wrong */
+
+ while ((pkt < limit) && mask && *pkt) /* packets are terminated with nulls */
+ {
+ pkt = unpack_int (pkt, &tag); /* tag */
+ pkt = unpack_byte (pkt, &length); /* length */
+ if (!(tag & mask)) /* tags out of synch with mask */
+ {
+ warning ("ERROR RMT: threadinfo tag mismatch\n");
+ retval = 0;
+ break;
+ }
+ if (tag == TAG_THREADID)
+ {
+ if (length != 16)
+ {
+ warning ("ERROR RMT: length of threadid is not 16\n");
+ retval = 0;
+ break;
+ }
+ pkt = unpack_threadid (pkt, &ref);
+ mask = mask & ~TAG_THREADID;
+ continue;
+ }
+ if (tag == TAG_EXISTS)
+ {
+ info->active = stub_unpack_int (pkt, length);
+ pkt += length;
+ mask = mask & ~(TAG_EXISTS);
+ if (length > 8)
+ {
+ warning ("ERROR RMT: 'exists' length too long\n");
+ retval = 0;
+ break;
+ }
+ continue;
+ }
+ if (tag == TAG_THREADNAME)
+ {
+ pkt = unpack_string (pkt, &info->shortname[0], length);
+ mask = mask & ~TAG_THREADNAME;
+ continue;
+ }
+ if (tag == TAG_DISPLAY)
+ {
+ pkt = unpack_string (pkt, &info->display[0], length);
+ mask = mask & ~TAG_DISPLAY;
+ continue;
+ }
+ if (tag == TAG_MOREDISPLAY)
+ {
+ pkt = unpack_string (pkt, &info->more_display[0], length);
+ mask = mask & ~TAG_MOREDISPLAY;
+ continue;
+ }
+ warning ("ERROR RMT: unknown thread info tag\n");
+ break; /* Not a tag we know about */
+ }
+ return retval;
+}
+
+static int
+remote_get_threadinfo (threadid, fieldset, info)
+ threadref *threadid;
+ int fieldset; /* TAG mask */
+ struct gdb_ext_thread_info *info;
+{
+ int result;
+ char threadinfo_pkt[PBUFSIZ];
+
+ pack_threadinfo_request (threadinfo_pkt, fieldset, threadid);
+ putpkt (threadinfo_pkt);
+ getpkt (threadinfo_pkt, 0);
+ result = remote_unpack_thread_info_response (threadinfo_pkt + 2, threadid,
+ info);
+ return result;
+}
+
+/* Unfortunately, 61 bit thread-ids are bigger than the internal
+ representation of a threadid. */
+
+static int
+adapt_remote_get_threadinfo (ref, selection, info)
+ gdb_threadref *ref;
+ int selection;
+ struct gdb_ext_thread_info *info;
+{
+ threadref lclref;
+
+ int_to_threadref (&lclref, *ref);
+ return remote_get_threadinfo (&lclref, selection, info);
+}
+
+/* Format: i'Q':8,i"L":8,initflag:8,batchsize:16,lastthreadid:32 */
+
+static char *
+pack_threadlist_request (pkt, startflag, threadcount, nextthread)
+ char *pkt;
+ int startflag;
+ int threadcount;
+ threadref *nextthread;
+{
+ *pkt++ = 'q'; /* info query packet */
+ *pkt++ = 'L'; /* Process LIST or threadLIST request */
+ pkt = pack_nibble (pkt, startflag); /* initflag 1 bytes */
+ pkt = pack_hex_byte (pkt, threadcount); /* threadcount 2 bytes */
+ pkt = pack_threadid (pkt, nextthread); /* 64 bit thread identifier */
+ *pkt = '\0';
+ return pkt;
+}
+
+/* Encoding: 'q':8,'M':8,count:16,done:8,argthreadid:64,(threadid:64)* */
+
+static int
+parse_threadlist_response (pkt, result_limit, original_echo, resultlist,
+ doneflag)
+ char *pkt;
+ int result_limit;
+ threadref *original_echo;
+ threadref *resultlist;
+ int *doneflag;
+{
+ char *limit;
+ int count, resultcount, done;
+
+ resultcount = 0;
+ /* Assume the 'q' and 'M chars have been stripped. */
+ limit = pkt + (PBUFSIZ - BUF_THREAD_ID_SIZE); /* done parse past here */
+ pkt = unpack_byte (pkt, &count); /* count field */
+ pkt = unpack_nibble (pkt, &done);
+ /* The first threadid is the argument threadid. */
+ pkt = unpack_threadid (pkt, original_echo); /* should match query packet */
+ while ((count-- > 0) && (pkt < limit))
+ {
+ pkt = unpack_threadid (pkt, resultlist++);
+ if (resultcount++ >= result_limit)
+ break;
+ }
+ if (doneflag)
+ *doneflag = done;
+ return resultcount;
+}
+
+static int
+remote_get_threadlist (startflag, nextthread, result_limit,
+ done, result_count, threadlist)
+ int startflag;
+ threadref *nextthread;
+ int result_limit;
+ int *done;
+ int *result_count;
+ threadref *threadlist;
+
+{
+ static threadref echo_nextthread;
+ char threadlist_packet[PBUFSIZ];
+ char t_response[PBUFSIZ];
+ int result = 1;
+
+ /* Trancate result limit to be smaller than the packet size */
+ if ((((result_limit + 1) * BUF_THREAD_ID_SIZE) + 10) >= PBUFSIZ)
+ result_limit = (PBUFSIZ / BUF_THREAD_ID_SIZE) - 2;
+
+ pack_threadlist_request (threadlist_packet,
+ startflag, result_limit, nextthread);
+ putpkt (threadlist_packet);
+ getpkt (t_response, 0);
+
+ *result_count =
+ parse_threadlist_response (t_response + 2, result_limit, &echo_nextthread,
+ threadlist, done);
+
+ if (!threadmatch (&echo_nextthread, nextthread))
+ {
+ /* FIXME: This is a good reason to drop the packet */
+ /* Possably, there is a duplicate response */
+ /* Possabilities :
+ retransmit immediatly - race conditions
+ retransmit after timeout - yes
+ exit
+ wait for packet, then exit
+ */
+ warning ("HMM: threadlist did not echo arg thread, dropping it\n");
+ return 0; /* I choose simply exiting */
+ }
+ if (*result_count <= 0)
+ {
+ if (*done != 1)
+ {
+ warning ("RMT ERROR : failed to get remote thread list\n");
+ result = 0;
+ }
+ return result; /* break; */
+ }
+ if (*result_count > result_limit)
+ {
+ *result_count = 0;
+ warning ("RMT ERROR: threadlist response longer than requested\n");
+ return 0;
+ }
+ return result;
+}
+
+/* This is the interface between remote and threads, remotes upper interface */
+
+/* remote_find_new_threads retrieves the thread list and for each
+ thread in the list, looks up the thread in GDB's internal list,
+ ading the thread if it does not already exist. This involves
+ getting partial thread lists from the remote target so, polling the
+ quit_flag is required. */
+
+
+/* About this many threadisds fit in a packet. */
+
+#define MAXTHREADLISTRESULTS 32
+
+static int
+remote_threadlist_iterator (stepfunction, context, looplimit)
+ rmt_thread_action stepfunction;
+ void *context;
+ int looplimit;
+{
+ int done, i, result_count;
+ int startflag = 1;
+ int result = 1;
+ int loopcount = 0;
+ static threadref nextthread;
+ static threadref resultthreadlist[MAXTHREADLISTRESULTS];
+
+ done = 0;
+ while (!done)
+ {
+ if (loopcount++ > looplimit)
+ {
+ result = 0;
+ warning ("Remote fetch threadlist -infinite loop-\n");
+ break;
+ }
+ if (!remote_get_threadlist (startflag, &nextthread, MAXTHREADLISTRESULTS,
+ &done, &result_count, resultthreadlist))
+ {
+ result = 0;
+ break;
+ }
+ /* clear for later iterations */
+ startflag = 0;
+ /* Setup to resume next batch of thread references, set nextthread. */
+ if (result_count >= 1)
+ copy_threadref (&nextthread, &resultthreadlist[result_count - 1]);
+ i = 0;
+ while (result_count--)
+ if (!(result = (*stepfunction) (&resultthreadlist[i++], context)))
+ break;
+ }
+ return result;
+}
+
+static int
+remote_newthread_step (ref, context)
+ threadref *ref;
+ void *context;
+{
+ int pid;
+
+ pid = threadref_to_int (ref);
+ if (!in_thread_list (pid))
+ add_thread (pid);
+ return 1; /* continue iterator */
+}
+
+#define CRAZY_MAX_THREADS 1000
+
+static int
+remote_current_thread (oldpid)
+ int oldpid;
+{
+ char buf[PBUFSIZ];
+
+ putpkt ("qC");
+ getpkt (buf, 0);
+ if (buf[0] == 'Q' && buf[1] == 'C')
+ return strtol (&buf[2], NULL, 16);
+ else
+ return oldpid;
+}
+
+int
+remote_find_new_threads ()
+{
+ int ret;
+
+ ret = remote_threadlist_iterator (remote_newthread_step, 0,
+ CRAZY_MAX_THREADS);
+ if (inferior_pid == MAGIC_NULL_PID) /* ack ack ack */
+ inferior_pid = remote_current_thread (inferior_pid);
+ return ret;
+}
+
+/* Initialize the thread vector which is used by threads.c */
+/* The thread stub is a package, it has an initializer */
+
+static void
+init_remote_threads ()
+{
+ remote_thread_vec.find_new_threads = remote_find_new_threads;
+ remote_thread_vec.get_thread_info = adapt_remote_get_threadinfo;
+}
+
+
/* Restart the remote side; this is an extended protocol operation. */
static void
@@ -577,8 +1468,8 @@ remote_close (quitting)
static void
get_offsets ()
{
- char buf[PBUFSIZ];
- int nvals;
+ char buf[PBUFSIZ], *ptr;
+ int lose;
CORE_ADDR text_addr, data_addr, bss_addr;
struct section_offsets *offs;
@@ -592,17 +1483,51 @@ get_offsets ()
getpkt (buf, 0);
if (buf[0] == '\000')
- return; /* Return silently. Stub doesn't support this
- command. */
+ return; /* Return silently. Stub doesn't support
+ this command. */
if (buf[0] == 'E')
{
warning ("Remote failure reply: %s", buf);
return;
}
- nvals = sscanf (buf, "Text=%lx;Data=%lx;Bss=%lx", &text_addr, &data_addr,
- &bss_addr);
- if (nvals != 3)
+ /* Pick up each field in turn. This used to be done with scanf, but
+ scanf will make trouble if CORE_ADDR size doesn't match
+ conversion directives correctly. The following code will work
+ with any size of CORE_ADDR. */
+ text_addr = data_addr = bss_addr = 0;
+ ptr = buf;
+ lose = 0;
+
+ if (strncmp (ptr, "Text=", 5) == 0)
+ {
+ ptr += 5;
+ /* Don't use strtol, could lose on big values. */
+ while (*ptr && *ptr != ';')
+ text_addr = (text_addr << 4) + fromhex (*ptr++);
+ }
+ else
+ lose = 1;
+
+ if (!lose && strncmp (ptr, ";Data=", 6) == 0)
+ {
+ ptr += 6;
+ while (*ptr && *ptr != ';')
+ data_addr = (data_addr << 4) + fromhex (*ptr++);
+ }
+ else
+ lose = 1;
+
+ if (!lose && strncmp (ptr, ";Bss=", 5) == 0)
+ {
+ ptr += 5;
+ while (*ptr && *ptr != ';')
+ bss_addr = (bss_addr << 4) + fromhex (*ptr++);
+ }
+ else
+ lose = 1;
+
+ if (lose)
error ("Malformed response to offset query, %s", buf);
if (symfile_objfile == NULL)
@@ -632,7 +1557,7 @@ get_offsets ()
static int
remote_start_remote (dummy)
- char *dummy;
+ PTR dummy;
{
immediate_quit = 1; /* Allow user to interrupt it */
@@ -642,6 +1567,8 @@ remote_start_remote (dummy)
/* Let the stub know that we want it to return the thread. */
set_thread (-1, 0);
+ inferior_pid = remote_current_thread (inferior_pid);
+
get_offsets (); /* Get text, data & bss offsets */
putpkt ("?"); /* initiate a query from remote machine */
@@ -659,7 +1586,7 @@ remote_open (name, from_tty)
char *name;
int from_tty;
{
- remote_open_1 (name, from_tty, &remote_ops);
+ remote_open_1 (name, from_tty, &remote_ops, 0);
}
/* Open a connection to a remote debugger using the extended
@@ -670,29 +1597,23 @@ extended_remote_open (name, from_tty)
char *name;
int from_tty;
{
- char buf[PBUFSIZ];
-
- /* Do the basic remote open stuff. */
- remote_open_1 (name, from_tty, &extended_remote_ops);
-
- /* Now tell the remote that we're using the extended protocol. */
- putpkt ("!");
- getpkt (buf, 0);
-
+ remote_open_1 (name, from_tty, &extended_remote_ops, 1/*extended_p*/);
}
/* Generic code for opening a connection to a remote target. */
+
static DCACHE *remote_dcache;
static void
-remote_open_1 (name, from_tty, target)
+remote_open_1 (name, from_tty, target, extended_p)
char *name;
int from_tty;
struct target_ops *target;
+ int extended_p;
{
if (name == 0)
- error ("To open a remote debug connection, you need to specify what serial\n\
-device is attached to the remote system (e.g. /dev/ttya).");
+ error ("To open a remote debug connection, you need to specify what\n\
+serial device is attached to the remote system (e.g. /dev/ttya).");
target_preopen (from_tty);
@@ -728,28 +1649,50 @@ device is attached to the remote system (e.g. /dev/ttya).");
}
push_target (target); /* Switch to using remote target now */
- /* Start out by trying the 'P' request to set registers. We set this each
- time that we open a new target so that if the user switches from one
- stub to another, we can (if the target is closed and reopened) cope. */
+ /* The target vector does not have the thread functions in it yet,
+ so we use this function to call back into the thread module and
+ register the thread vector and its contained functions. */
+ bind_target_thread_vector (&remote_thread_vec);
+
+ /* Start out by trying the 'P' request to set registers. We set
+ this each time that we open a new target so that if the user
+ switches from one stub to another, we can (if the target is
+ closed and reopened) cope. */
stub_supports_P = 1;
general_thread = -2;
cont_thread = -2;
- /* Without this, some commands which require an active target (such as kill)
- won't work. This variable serves (at least) double duty as both the pid
- of the target process (if it has such), and as a flag indicating that a
- target is active. These functions should be split out into seperate
- variables, especially since GDB will someday have a notion of debugging
- several processes. */
+ /* Force remote_write_bytes to check whether target supports
+ binary downloading. */
+ remote_binary_checked = 0;
+
+ /* Without this, some commands which require an active target (such
+ as kill) won't work. This variable serves (at least) double duty
+ as both the pid of the target process (if it has such), and as a
+ flag indicating that a target is active. These functions should
+ be split out into seperate variables, especially since GDB will
+ someday have a notion of debugging several processes. */
- inferior_pid = 42000;
+ inferior_pid = MAGIC_NULL_PID;
/* Start the remote connection; if error (0), discard this target.
In particular, if the user quits, be sure to discard it
(we'd be in an inconsistent state otherwise). */
- if (!catch_errors (remote_start_remote, (char *)0,
- "Couldn't establish connection to remote target\n", RETURN_MASK_ALL))
- pop_target();
+ if (!catch_errors (remote_start_remote, NULL,
+ "Couldn't establish connection to remote target\n",
+ RETURN_MASK_ALL))
+ {
+ pop_target ();
+ return;
+ }
+
+ if (extended_p)
+ {
+ /* tell the remote that we're using the extended protocol. */
+ char buf[PBUFSIZ];
+ putpkt ("!");
+ getpkt (buf, 0);
+ }
}
/* This takes a program previously attached to and detaches it. After
@@ -778,7 +1721,7 @@ remote_detach (args, from_tty)
/* Convert hex digit A to a number. */
-static int
+int
fromhex (a)
int a;
{
@@ -786,6 +1729,8 @@ fromhex (a)
return a - '0';
else if (a >= 'a' && a <= 'f')
return a - 'a' + 10;
+ else if (a >= 'A' && a <= 'F')
+ return a - 'A' + 10;
else
error ("Reply contains invalid hex digit %d", a);
}
@@ -805,7 +1750,8 @@ tohex (nib)
/* Tell the remote machine to resume. */
static enum target_signal last_sent_signal = TARGET_SIGNAL_0;
-int last_sent_step;
+
+static int last_sent_step;
static void
remote_resume (pid, step, siggnal)
@@ -815,15 +1761,20 @@ remote_resume (pid, step, siggnal)
char buf[PBUFSIZ];
if (pid == -1)
- set_thread (inferior_pid, 0);
+ set_thread (0, 0); /* run any thread */
else
- set_thread (pid, 0);
+ set_thread (pid, 0); /* run this thread */
dcache_flush (remote_dcache);
last_sent_signal = siggnal;
last_sent_step = step;
+ /* A hook for when we need to do something at the last moment before
+ resumption. */
+ if (target_resume_hook)
+ (*target_resume_hook) ();
+
if (siggnal != TARGET_SIGNAL_0)
{
buf[0] = step ? 'S' : 'C';
@@ -840,35 +1791,39 @@ remote_resume (pid, step, siggnal)
/* Send ^C to target to halt it. Target will respond, and send us a
packet. */
+static void (*ofunc) PARAMS ((int));
+
static void
remote_interrupt (signo)
int signo;
{
- /* If this doesn't work, try more severe steps. */
- signal (signo, remote_interrupt_twice);
-
- if (remote_debug)
- printf_unfiltered ("remote_interrupt called\n");
-
- /* Send a break or a ^C, depending on user preference. */
- if (remote_break)
- SERIAL_SEND_BREAK (remote_desc);
- else
- SERIAL_WRITE (remote_desc, "\003", 1);
+ remote_stop ();
+ signal (signo, remote_interrupt);
}
-
-static void (*ofunc)();
-
-/* The user typed ^C twice. */
+
static void
-remote_interrupt_twice (signo)
- int signo;
+remote_stop ()
{
- signal (signo, ofunc);
-
- interrupt_query ();
+ if (!interrupted_already)
+ {
+ /* Send a break or a ^C, depending on user preference. */
+ interrupted_already = 1;
- signal (signo, remote_interrupt);
+ if (remote_debug)
+ printf_unfiltered ("remote_stop called\n");
+
+ if (remote_break)
+ SERIAL_SEND_BREAK (remote_desc);
+ else
+ SERIAL_WRITE (remote_desc, "\003", 1);
+ }
+ else
+ {
+ signal (SIGINT, ofunc);
+ interrupt_query ();
+ signal (SIGINT, remote_interrupt);
+ interrupted_already = 0;
+ }
}
/* Ask the user what to do when an interrupt is received. */
@@ -889,12 +1844,31 @@ Give up (and stop debugging it)? "))
}
/* If nonzero, ignore the next kill. */
+
int kill_kludge;
-/* Wait until the remote machine stops, then return,
- storing status in STATUS just as `wait' would.
- Returns "pid" (though it's not clear what, if anything, that
- means in the case of this target). */
+void
+remote_console_output (msg)
+ char *msg;
+{
+ char *p;
+
+ for (p = msg; *p; p +=2)
+ {
+ char tb[2];
+ char c = fromhex (p[0]) * 16 + fromhex (p[1]);
+ tb[0] = c;
+ tb[1] = 0;
+ if (target_output_hook)
+ target_output_hook (tb);
+ else
+ fputs_filtered (tb, gdb_stdout);
+ }
+}
+
+/* Wait until the remote machine stops, then return, storing status in
+ STATUS just as `wait' would. Returns "pid" (though it's not clear
+ what, if anything, that means in the case of this target). */
static int
remote_wait (pid, status)
@@ -916,10 +1890,16 @@ remote_wait (pid, status)
(void) remote_talk();
#endif /* REMOTE_CHAT */
- ofunc = (void (*)()) signal (SIGINT, remote_interrupt);
+ interrupted_already = 0;
+ ofunc = signal (SIGINT, remote_interrupt);
getpkt ((char *) buf, 1);
signal (SIGINT, ofunc);
+ /* This is a hook for when we need to do something (perhaps the
+ collection of trace data) every time the target stops. */
+ if (target_wait_loop_hook)
+ (*target_wait_loop_hook) ();
+
switch (buf[0])
{
case 'E': /* Error of some sort */
@@ -937,7 +1917,6 @@ remote_wait (pid, status)
n... = register number
r... = register contents
*/
-
p = &buf[3]; /* after Txx */
while (*p)
@@ -945,20 +1924,22 @@ remote_wait (pid, status)
unsigned char *p1;
char *p_temp;
- regno = strtol ((const char *) p, &p_temp, 16); /* Read the register number */
+ /* Read the register number */
+ regno = strtol ((const char *) p, &p_temp, 16);
p1 = (unsigned char *)p_temp;
- if (p1 == p)
+ if (p1 == p) /* No register number present here */
{
p1 = (unsigned char *) strchr ((const char *) p, ':');
if (p1 == NULL)
- warning ("Malformed packet (missing colon): %s\n\
+ warning ("Malformed packet(a) (missing colon): %s\n\
Packet: '%s'\n",
p, buf);
if (strncmp ((const char *) p, "thread", p1 - p) == 0)
{
- thread_num = strtol ((const char *) ++p1, &p_temp, 16);
- p = (unsigned char *)p_temp;
+ p_temp = unpack_varlen_hex (++p1, &thread_num);
+ record_currthread (thread_num);
+ p = (unsigned char *) p_temp;
}
}
else
@@ -966,7 +1947,7 @@ Packet: '%s'\n",
p = p1;
if (*p++ != ':')
- warning ("Malformed packet (missing colon): %s\n\
+ warning ("Malformed packet(b) (missing colon): %s\n\
Packet: '%s'\n",
p, buf);
@@ -986,7 +1967,10 @@ Packet: '%s'\n",
}
if (*p++ != ';')
- warning ("Remote register badly formatted: %s", buf);
+ {
+ warning ("Remote register badly formatted: %s", buf);
+ warning (" here: %s",p);
+ }
}
}
/* fall through */
@@ -1011,17 +1995,7 @@ Packet: '%s'\n",
goto got_status;
case 'O': /* Console output */
- for (p = buf + 1; *p; p +=2)
- {
- char tb[2];
- char c = fromhex (p[0]) * 16 + fromhex (p[1]);
- tb[0] = c;
- tb[1] = 0;
- if (target_output_hook)
- target_output_hook (tb);
- else
- fputs_filtered (tb, gdb_stdout);
- }
+ remote_console_output (buf + 1);
continue;
case '\0':
if (last_sent_signal != TARGET_SIGNAL_0)
@@ -1051,10 +2025,11 @@ Packet: '%s'\n",
/* Initial thread value can only be acquired via wait, so deal with
this marker which is used before the first thread value is
acquired. */
- if (inferior_pid == 42000)
+ if (inferior_pid == MAGIC_NULL_PID)
{
inferior_pid = thread_num;
- add_thread (inferior_pid);
+ if (!in_thread_list (inferior_pid))
+ add_thread (inferior_pid);
}
return thread_num;
}
@@ -1062,10 +2037,12 @@ Packet: '%s'\n",
}
/* Number of bytes of registers this stub implements. */
+
static int register_bytes_found;
/* Read the remote registers into the block REGS. */
/* Currently we just read all the registers, so we don't use regno. */
+
/* ARGSUSED */
static void
remote_fetch_registers (regno)
@@ -1081,6 +2058,9 @@ remote_fetch_registers (regno)
sprintf (buf, "g");
remote_send (buf);
+ if (remote_register_buf_size == 0)
+ remote_register_buf_size = strlen (buf);
+
/* Unimplemented registers read as all bits zero. */
memset (regs, 0, REGISTER_BYTES);
@@ -1088,7 +2068,8 @@ remote_fetch_registers (regno)
in the buffer is not a hex character, assume that has happened
and try to fetch another packet to read. */
while ((buf[0] < '0' || buf[0] > '9')
- && (buf[0] < 'a' || buf[0] > 'f'))
+ && (buf[0] < 'a' || buf[0] > 'f')
+ && buf[0] != 'x') /* New: unavailable register value */
{
if (remote_debug)
printf_unfiltered ("Bad register packet; fetching a new packet\n");
@@ -1111,7 +2092,10 @@ remote_fetch_registers (regno)
print a second warning. */
goto supply_them;
}
- regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
+ if (p[0] == 'x' && p[1] == 'x')
+ regs[i] = 0; /* 'x' */
+ else
+ regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
p += 2;
}
@@ -1123,10 +2107,14 @@ remote_fetch_registers (regno)
warning ("Remote reply is too short: %s", buf);
#endif
}
-
- supply_them:
+
+ supply_them:
for (i = 0; i < NUM_REGS; i++)
+ {
supply_register (i, &regs[REGISTER_BYTE(i)]);
+ if (buf[REGISTER_BYTE(i) * 2] == 'x')
+ register_valid[i] = -1; /* register value not available */
+ }
}
/* Prepare to store registers. Since we may send them all (using a
@@ -1197,9 +2185,8 @@ remote_store_registers (regno)
remote_send (buf);
}
-/*
- Use of the data cache *used* to be disabled because it loses for looking at
- and changing hardware I/O ports and the like. Accepting `volatile'
+/* Use of the data cache *used* to be disabled because it loses for looking
+ at and changing hardware I/O ports and the like. Accepting `volatile'
would perhaps be one way to fix it. Another idea would be to use the
executable file for the text segment (for all SEC_CODE sections?
For all SEC_READONLY sections?). This has problems if you want to
@@ -1207,8 +2194,7 @@ remote_store_registers (regno)
clobbered memory, user downloaded the wrong thing).
Because it speeds so much up, it's now enabled, if you're playing
- with registers you turn it of (set remotecache 0)
-*/
+ with registers you turn it of (set remotecache 0). */
/* Read a word from remote address ADDR and return it.
This goes through the data cache. */
@@ -1234,6 +2220,98 @@ remote_store_word (addr, word)
#endif /* 0 (unused?) */
+
+/* Return the number of hex digits in num. */
+
+static int
+hexnumlen (num)
+ ULONGEST num;
+{
+ int i;
+
+ for (i = 0; num != 0; i++)
+ num >>= 4;
+
+ return max (i, 1);
+}
+
+/* Set BUF to the hex digits representing NUM. */
+
+static int
+hexnumstr (buf, num)
+ char *buf;
+ ULONGEST num;
+{
+ int i;
+ int len = hexnumlen (num);
+
+ buf[len] = '\0';
+
+ for (i = len - 1; i >= 0; i--)
+ {
+ buf[i] = "0123456789abcdef" [(num & 0xf)];
+ num >>= 4;
+ }
+
+ return len;
+}
+
+/* Mask all but the least significant REMOTE_ADDRESS_SIZE bits. */
+
+static CORE_ADDR
+remote_address_masked (addr)
+ CORE_ADDR addr;
+{
+ if (remote_address_size > 0
+ && remote_address_size < (sizeof (ULONGEST) * 8))
+ {
+ /* Only create a mask when that mask can safely be constructed
+ in a ULONGEST variable. */
+ ULONGEST mask = 1;
+ mask = (mask << remote_address_size) - 1;
+ addr &= mask;
+ }
+ return addr;
+}
+
+/* Determine whether the remote target supports binary downloading.
+ This is accomplished by sending a no-op memory write of zero length
+ to the target at the specified address. It does not suffice to send
+ the whole packet, since many stubs strip the eighth bit and subsequently
+ compute a wrong checksum, which causes real havoc with remote_write_bytes. */
+static void
+check_binary_download (addr)
+ CORE_ADDR addr;
+{
+ if (remote_binary_download && !remote_binary_checked)
+ {
+ char buf[PBUFSIZ], *p;
+ remote_binary_checked = 1;
+
+ p = buf;
+ *p++ = 'X';
+ p += hexnumstr (p, (ULONGEST) addr);
+ *p++ = ',';
+ p += hexnumstr (p, (ULONGEST) 0);
+ *p++ = ':';
+ *p = '\0';
+
+ putpkt_binary (buf, (int) (p - buf));
+ getpkt (buf, 0);
+
+ if (buf[0] == '\0')
+ remote_binary_download = 0;
+ }
+
+ if (remote_debug)
+ {
+ if (remote_binary_download)
+ printf_unfiltered ("binary downloading suppported by target\n");
+ else
+ printf_unfiltered ("binary downloading NOT suppported by target\n");
+ }
+}
+
/* Write memory data directly to the remote machine.
This does not inform the data cache; the data cache uses this.
MEMADDR is the address in the remote memory space.
@@ -1248,36 +2326,102 @@ remote_write_bytes (memaddr, myaddr, len)
char *myaddr;
int len;
{
- char buf[PBUFSIZ];
- int i;
- char *p;
- int done;
+ int max_buf_size; /* Max size of packet output buffer */
+ int origlen;
+
+ /* Verify that the target can support a binary download */
+ check_binary_download (memaddr);
+
/* Chop the transfer down if necessary */
- done = 0;
- while (done < len)
+ max_buf_size = min (remote_write_size, PBUFSIZ);
+ if (remote_register_buf_size != 0)
+ max_buf_size = min (max_buf_size, remote_register_buf_size);
+
+ /* Subtract header overhead from max payload size - $M<memaddr>,<len>:#nn */
+ max_buf_size -= 2 + hexnumlen (memaddr + len - 1) + 1 + hexnumlen (len) + 4;
+
+ origlen = len;
+ while (len > 0)
{
- int todo = len - done;
- int cando = PBUFSIZ /2 - 32; /* number of bytes that will fit. */
- if (todo > cando)
- todo = cando;
+ unsigned char buf[PBUFSIZ];
+ unsigned char *p, *plen;
+ int todo;
+ int i;
+
+ /* construct "M"<memaddr>","<len>":" */
+ /* sprintf (buf, "M%lx,%x:", (unsigned long) memaddr, todo); */
+ memaddr = remote_address_masked (memaddr);
+ p = buf;
+ if (remote_binary_download)
+ {
+ *p++ = 'X';
+ todo = min (len, max_buf_size);
+ }
+ else
+ {
+ *p++ = 'M';
+ todo = min (len, max_buf_size / 2); /* num bytes that will fit */
+ }
- /* FIXME-32x64: Need a version of print_address_numeric which puts the
- result in a buffer like sprintf. */
- sprintf (buf, "M%lx,%x:", (unsigned long) memaddr + done, todo);
+ p += hexnumstr (p, (ULONGEST) memaddr);
+ *p++ = ',';
- /* We send target system values byte by byte, in increasing byte addresses,
- each byte encoded as two hex characters. */
+ plen = p; /* remember where len field goes */
+ p += hexnumstr (p, (ULONGEST) todo);
+ *p++ = ':';
+ *p = '\0';
- p = buf + strlen (buf);
- for (i = 0; i < todo; i++)
+ /* We send target system values byte by byte, in increasing byte
+ addresses, each byte encoded as two hex characters (or one
+ binary character). */
+ if (remote_binary_download)
{
- *p++ = tohex ((myaddr[i + done] >> 4) & 0xf);
- *p++ = tohex (myaddr[i + done] & 0xf);
+ int escaped = 0;
+ for (i = 0;
+ (i < todo) && (i + escaped) < (max_buf_size - 2);
+ i++)
+ {
+ switch (myaddr[i] & 0xff)
+ {
+ case '$':
+ case '#':
+ case 0x7d:
+ /* These must be escaped */
+ escaped++;
+ *p++ = 0x7d;
+ *p++ = (myaddr[i] & 0xff) ^ 0x20;
+ break;
+ default:
+ *p++ = myaddr[i] & 0xff;
+ break;
+ }
+ }
+
+ if (i < todo)
+ {
+ /* Escape chars have filled up the buffer prematurely,
+ and we have actually sent fewer bytes than planned.
+ Fix-up the length field of the packet. */
+
+ /* FIXME: will fail if new len is a shorter string than
+ old len. */
+
+ plen += hexnumstr (plen, (ULONGEST) i);
+ *plen++ = ':';
+ }
+ }
+ else
+ {
+ for (i = 0; i < todo; i++)
+ {
+ *p++ = tohex ((myaddr[i] >> 4) & 0xf);
+ *p++ = tohex (myaddr[i] & 0xf);
+ }
+ *p = '\0';
}
- *p = '\0';
- putpkt (buf);
+ putpkt_binary (buf, (int) (p - buf));
getpkt (buf, 0);
if (buf[0] == 'E')
@@ -1289,9 +2433,14 @@ remote_write_bytes (memaddr, myaddr, len)
errno = EIO;
return 0;
}
- done += todo;
+
+ /* Increment by i, not by todo, in case escape chars
+ caused us to send fewer bytes than we'd planned. */
+ myaddr += i;
+ memaddr += i;
+ len -= i;
}
- return len;
+ return origlen;
}
/* Read memory data directly from the remote machine.
@@ -1308,28 +2457,35 @@ remote_read_bytes (memaddr, myaddr, len)
char *myaddr;
int len;
{
- char buf[PBUFSIZ];
- int i;
- char *p;
- int done;
- /* Chop transfer down if neccessary */
+ int max_buf_size; /* Max size of packet output buffer */
+ int origlen;
-#if 0
- /* FIXME: This is wrong for larger packets */
- if (len > PBUFSIZ / 2 - 1)
- abort ();
-#endif
- done = 0;
- while (done < len)
+ /* Chop the transfer down if necessary */
+
+ max_buf_size = min (remote_write_size, PBUFSIZ);
+ if (remote_register_buf_size != 0)
+ max_buf_size = min (max_buf_size, remote_register_buf_size);
+
+ origlen = len;
+ while (len > 0)
{
- int todo = len - done;
- int cando = PBUFSIZ / 2 - 32; /* number of bytes that will fit. */
- if (todo > cando)
- todo = cando;
-
- /* FIXME-32x64: Need a version of print_address_numeric which puts the
- result in a buffer like sprintf. */
- sprintf (buf, "m%lx,%x", (unsigned long) memaddr + done, todo);
+ char buf[PBUFSIZ];
+ char *p;
+ int todo;
+ int i;
+
+ todo = min (len, max_buf_size / 2); /* num bytes that will fit */
+
+ /* construct "m"<memaddr>","<len>" */
+ /* sprintf (buf, "m%lx,%x", (unsigned long) memaddr, todo); */
+ memaddr = remote_address_masked (memaddr);
+ p = buf;
+ *p++ = 'm';
+ p += hexnumstr (p, (ULONGEST) memaddr);
+ *p++ = ',';
+ p += hexnumstr (p, (ULONGEST) todo);
+ *p = '\0';
+
putpkt (buf);
getpkt (buf, 0);
@@ -1350,31 +2506,45 @@ remote_read_bytes (memaddr, myaddr, len)
for (i = 0; i < todo; i++)
{
if (p[0] == 0 || p[1] == 0)
- /* Reply is short. This means that we were able to read only part
- of what we wanted to. */
- return i + done;
- myaddr[i + done] = fromhex (p[0]) * 16 + fromhex (p[1]);
+ /* Reply is short. This means that we were able to read
+ only part of what we wanted to. */
+ return i + (origlen - len);
+ myaddr[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
p += 2;
}
- done += todo;
+ myaddr += todo;
+ memaddr += todo;
+ len -= todo;
}
- return len;
+ return origlen;
}
-/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
- to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
- nonzero. Returns length of data written or read; 0 for error. */
+/* Read or write LEN bytes from inferior memory at MEMADDR,
+ transferring to or from debugger address MYADDR. Write to inferior
+ if SHOULD_WRITE is nonzero. Returns length of data written or
+ read; 0 for error. */
/* ARGSUSED */
static int
-remote_xfer_memory(memaddr, myaddr, len, should_write, target)
+remote_xfer_memory (memaddr, myaddr, len, should_write, target)
CORE_ADDR memaddr;
char *myaddr;
int len;
int should_write;
struct target_ops *target; /* ignored */
{
- return dcache_xfer_memory (remote_dcache, memaddr, myaddr, len, should_write);
+#ifdef REMOTE_TRANSLATE_XFER_ADDRESS
+ CORE_ADDR targaddr;
+ int targlen;
+ REMOTE_TRANSLATE_XFER_ADDRESS (memaddr, len, targaddr, targlen);
+ if (targlen == 0)
+ return 0;
+ memaddr = targaddr;
+ len = targlen;
+#endif
+
+ return dcache_xfer_memory (remote_dcache, memaddr, myaddr,
+ len, should_write);
}
@@ -1485,9 +2655,8 @@ readchar (timeout)
}
}
-/* Send the command in BUF to the remote machine,
- and read the reply into BUF.
- Report an error if we get an error reply. */
+/* Send the command in BUF to the remote machine, and read the reply
+ into BUF. Report an error if we get an error reply. */
static void
remote_send (buf)
@@ -1500,17 +2669,39 @@ remote_send (buf)
error ("Remote failure reply: %s", buf);
}
-/* Send a packet to the remote machine, with error checking.
- The data of the packet is in BUF. */
+/* Display a null-terminated packet on stdout, for debugging, using C
+ string notation. */
-static int
+static void
+print_packet (buf)
+ char *buf;
+{
+ puts_filtered ("\"");
+ while (*buf)
+ gdb_printchar (*buf++, gdb_stdout, '"');
+ puts_filtered ("\"");
+}
+
+int
putpkt (buf)
char *buf;
{
+ return putpkt_binary (buf, strlen (buf));
+}
+
+/* Send a packet to the remote machine, with error checking. The data
+ of the packet is in BUF. The string in BUF can be at most PBUFSIZ - 5
+ to account for the $, # and checksum, and for a possible /0 if we are
+ debugging (remote_debug) and want to print the sent packet as a string */
+
+static int
+putpkt_binary (buf, cnt)
+ char *buf;
+ int cnt;
+{
int i;
unsigned char csum = 0;
char buf2[PBUFSIZ];
- int cnt = strlen (buf);
int ch;
int tcount = 0;
char *p;
@@ -1519,7 +2710,7 @@ putpkt (buf)
and giving it a checksum. */
if (cnt > (int) sizeof (buf2) - 5) /* Prosanity check */
- abort();
+ abort ();
p = buf2;
*p++ = '$';
@@ -1543,7 +2734,7 @@ putpkt (buf)
{
*p = '\0';
printf_unfiltered ("Sending packet: %s...", buf2);
- gdb_flush(gdb_stdout);
+ gdb_flush (gdb_stdout);
}
if (SERIAL_WRITE (remote_desc, buf2, p - buf2))
perror_with_name ("putpkt: write failed");
@@ -1572,7 +2763,7 @@ putpkt (buf)
{
case '+':
if (remote_debug)
- printf_unfiltered("Ack\n");
+ printf_unfiltered ("Ack\n");
return 1;
case SERIAL_TIMEOUT:
tcount ++;
@@ -1583,8 +2774,8 @@ putpkt (buf)
{
char junkbuf[PBUFSIZ];
- /* It's probably an old response, and we're out of sync. Just
- gobble up the packet and ignore it. */
+ /* It's probably an old response, and we're out of sync.
+ Just gobble up the packet and ignore it. */
getpkt (junkbuf, 0);
continue; /* Now, go look for + */
}
@@ -1615,10 +2806,10 @@ putpkt (buf)
#if 0
/* This is wrong. If doing a long backtrace, the user should be
- able to get out next time we call QUIT, without anything as violent
- as interrupt_query. If we want to provide a way out of here
- without getting to the next QUIT, it should be based on hitting
- ^C twice as in remote_wait. */
+ able to get out next time we call QUIT, without anything as
+ violent as interrupt_query. If we want to provide a way out of
+ here without getting to the next QUIT, it should be based on
+ hitting ^C twice as in remote_wait. */
if (quit_flag)
{
quit_flag = 0;
@@ -1628,9 +2819,9 @@ putpkt (buf)
}
}
-/* Come here after finding the start of the frame. Collect the rest into BUF,
- verifying the checksum, length, and handling run-length compression.
- Returns 0 on any error, 1 on success. */
+/* Come here after finding the start of the frame. Collect the rest
+ into BUF, verifying the checksum, length, and handling run-length
+ compression. Returns 0 on any error, 1 on success. */
static int
read_frame (buf)
@@ -1716,12 +2907,12 @@ read_frame (buf)
}
}
-/* Read a packet from the remote machine, with error checking,
- and store it in BUF. BUF is expected to be of size PBUFSIZ.
- If FOREVER, wait forever rather than timing out; this is used
- while the target is executing user code. */
+/* Read a packet from the remote machine, with error checking, and
+ store it in BUF. BUF is expected to be of size PBUFSIZ. If
+ FOREVER, wait forever rather than timing out; this is used while
+ the target is executing user code. */
-static void
+void
getpkt (buf, forever)
char *buf;
int forever;
@@ -1784,7 +2975,7 @@ getpkt (buf, forever)
if (val == 1)
{
if (remote_debug)
- fprintf_unfiltered (gdb_stderr, "Packet received: %s\n", buf);
+ fprintf_unfiltered (gdb_stdout, "Packet received: %s\n", buf);
SERIAL_WRITE (remote_desc, "+", 1);
return;
}
@@ -1814,7 +3005,7 @@ remote_kill ()
/* Use catch_errors so the user can quit from gdb even when we aren't on
speaking terms with the remote system. */
- catch_errors (putpkt, "k", "", RETURN_MASK_ERROR);
+ catch_errors ((catch_errors_ftype *) putpkt, "k", "", RETURN_MASK_ERROR);
/* Don't wait for it to die. I'm not really sure it matters whether
we do or not. For the existing stubs, kill is a noop. */
@@ -1881,19 +3072,33 @@ extended_remote_create_inferior (exec_file, args, env)
}
-#ifdef REMOTE_BREAKPOINT
-
/* On some machines, e.g. 68k, we may use a different breakpoint instruction
- than other targets. */
-static unsigned char break_insn[] = REMOTE_BREAKPOINT;
+ than other targets; in those use REMOTE_BREAKPOINT instead of just
+ BREAKPOINT. Also, bi-endian targets may define LITTLE_REMOTE_BREAKPOINT
+ and BIG_REMOTE_BREAKPOINT. If none of these are defined, we just call
+ the standard routines that are in mem-break.c. */
+
+/* FIXME, these ought to be done in a more dynamic fashion. For instance,
+ the choice of breakpoint instruction affects target program design and
+ vice versa, and by making it user-tweakable, the special code here
+ goes away and we need fewer special GDB configurations. */
+
+#if defined (LITTLE_REMOTE_BREAKPOINT) && defined (BIG_REMOTE_BREAKPOINT) && !defined(REMOTE_BREAKPOINT)
+#define REMOTE_BREAKPOINT
+#endif
+
+#ifdef REMOTE_BREAKPOINT
-#else /* No REMOTE_BREAKPOINT. */
+/* If the target isn't bi-endian, just pretend it is. */
+#if !defined (LITTLE_REMOTE_BREAKPOINT) && !defined (BIG_REMOTE_BREAKPOINT)
+#define LITTLE_REMOTE_BREAKPOINT REMOTE_BREAKPOINT
+#define BIG_REMOTE_BREAKPOINT REMOTE_BREAKPOINT
+#endif
-/* Same old breakpoint instruction. This code does nothing different
- than mem-break.c. */
-static unsigned char break_insn[] = BREAKPOINT;
+static unsigned char big_break_insn[] = BIG_REMOTE_BREAKPOINT;
+static unsigned char little_break_insn[] = LITTLE_REMOTE_BREAKPOINT;
-#endif /* No REMOTE_BREAKPOINT. */
+#endif /* REMOTE_BREAKPOINT */
/* Insert a breakpoint on targets that don't have any better breakpoint
support. We read the contents of the target location and stash it,
@@ -1908,14 +3113,25 @@ remote_insert_breakpoint (addr, contents_cache)
CORE_ADDR addr;
char *contents_cache;
{
+#ifdef REMOTE_BREAKPOINT
int val;
- val = target_read_memory (addr, contents_cache, sizeof break_insn);
+ val = target_read_memory (addr, contents_cache, sizeof big_break_insn);
if (val == 0)
- val = target_write_memory (addr, (char *)break_insn, sizeof break_insn);
+ {
+ if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ val = target_write_memory (addr, (char *) big_break_insn,
+ sizeof big_break_insn);
+ else
+ val = target_write_memory (addr, (char *) little_break_insn,
+ sizeof little_break_insn);
+ }
return val;
+#else
+ return memory_insert_breakpoint (addr, contents_cache);
+#endif /* REMOTE_BREAKPOINT */
}
static int
@@ -1923,122 +3139,540 @@ remote_remove_breakpoint (addr, contents_cache)
CORE_ADDR addr;
char *contents_cache;
{
- return target_write_memory (addr, contents_cache, sizeof break_insn);
+#ifdef REMOTE_BREAKPOINT
+ return target_write_memory (addr, contents_cache, sizeof big_break_insn);
+#else
+ return memory_remove_breakpoint (addr, contents_cache);
+#endif /* REMOTE_BREAKPOINT */
}
-
-/* Define the target subroutine names */
-struct target_ops remote_ops = {
- "remote", /* to_shortname */
- "Remote serial target in gdb-specific protocol", /* to_longname */
- "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
-Specify the serial device it is connected to (e.g. /dev/ttya).", /* to_doc */
- remote_open, /* to_open */
- remote_close, /* to_close */
- NULL, /* to_attach */
- remote_detach, /* to_detach */
- remote_resume, /* to_resume */
- remote_wait, /* to_wait */
- remote_fetch_registers, /* to_fetch_registers */
- remote_store_registers, /* to_store_registers */
- remote_prepare_to_store, /* to_prepare_to_store */
- remote_xfer_memory, /* to_xfer_memory */
- remote_files_info, /* to_files_info */
- remote_insert_breakpoint, /* to_insert_breakpoint */
- remote_remove_breakpoint, /* to_remove_breakpoint */
- NULL, /* to_terminal_init */
- NULL, /* to_terminal_inferior */
- NULL, /* to_terminal_ours_for_output */
- NULL, /* to_terminal_ours */
- NULL, /* to_terminal_info */
- remote_kill, /* to_kill */
- generic_load, /* to_load */
- NULL, /* to_lookup_symbol */
- NULL, /* to_create_inferior */
- remote_mourn, /* to_mourn_inferior */
- 0, /* to_can_run */
- 0, /* to_notice_signals */
- remote_thread_alive, /* to_thread_alive */
- 0, /* to_stop */
- process_stratum, /* to_stratum */
- NULL, /* to_next */
- 1, /* to_has_all_memory */
- 1, /* to_has_memory */
- 1, /* to_has_stack */
- 1, /* to_has_registers */
- 1, /* to_has_execution */
- NULL, /* sections */
- NULL, /* sections_end */
- OPS_MAGIC /* to_magic */
-};
+/* Some targets are only capable of doing downloads, and afterwards
+ they switch to the remote serial protocol. This function provides
+ a clean way to get from the download target to the remote target.
+ It's basically just a wrapper so that we don't have to expose any
+ of the internal workings of remote.c.
-struct target_ops extended_remote_ops = {
- "extended-remote", /* to_shortname */
- "Extended remote serial target in gdb-specific protocol",/* to_longname */
- "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
-Specify the serial device it is connected to (e.g. /dev/ttya).", /* to_doc */
- extended_remote_open, /* to_open */
- remote_close, /* to_close */
- NULL, /* to_attach */
- remote_detach, /* to_detach */
- remote_resume, /* to_resume */
- remote_wait, /* to_wait */
- remote_fetch_registers, /* to_fetch_registers */
- remote_store_registers, /* to_store_registers */
- remote_prepare_to_store, /* to_prepare_to_store */
- remote_xfer_memory, /* to_xfer_memory */
- remote_files_info, /* to_files_info */
-
- remote_insert_breakpoint, /* to_insert_breakpoint */
- remote_remove_breakpoint, /* to_remove_breakpoint */
-
- NULL, /* to_terminal_init */
- NULL, /* to_terminal_inferior */
- NULL, /* to_terminal_ours_for_output */
- NULL, /* to_terminal_ours */
- NULL, /* to_terminal_info */
- remote_kill, /* to_kill */
- generic_load, /* to_load */
- NULL, /* to_lookup_symbol */
- extended_remote_create_inferior,/* to_create_inferior */
- extended_remote_mourn, /* to_mourn_inferior */
- 0, /* to_can_run */
- 0, /* to_notice_signals */
- remote_thread_alive, /* to_thread_alive */
- 0, /* to_stop */
- process_stratum, /* to_stratum */
- NULL, /* to_next */
- 1, /* to_has_all_memory */
- 1, /* to_has_memory */
- 1, /* to_has_stack */
- 1, /* to_has_registers */
- 1, /* to_has_execution */
- NULL, /* sections */
- NULL, /* sections_end */
- OPS_MAGIC /* to_magic */
-};
+ Prior to calling this routine, you should shutdown the current
+ target code, else you will get the "A program is being debugged
+ already..." message. Usually a call to pop_target() suffices. */
+
+void
+push_remote_target (name, from_tty)
+ char *name;
+ int from_tty;
+{
+ printf_filtered ("Switching to remote protocol\n");
+ remote_open (name, from_tty);
+}
+
+/* Other targets want to use the entire remote serial module but with
+ certain remote_ops overridden. */
+
+void
+open_remote_target (name, from_tty, target, extended_p)
+ char *name;
+ int from_tty;
+ struct target_ops *target;
+ int extended_p;
+{
+ printf_filtered ("Selecting the %sremote protocol\n",
+ (extended_p ? "extended-" : ""));
+ remote_open_1 (name, from_tty, target, extended_p);
+}
+
+/* Table used by the crc32 function to calcuate the checksum. */
+
+static unsigned long crc32_table[256] = {0, 0};
+
+static unsigned long
+crc32 (buf, len, crc)
+ unsigned char *buf;
+ int len;
+ unsigned int crc;
+{
+ if (! crc32_table[1])
+ {
+ /* Initialize the CRC table and the decoding table. */
+ int i, j;
+ unsigned int c;
+
+ for (i = 0; i < 256; i++)
+ {
+ for (c = i << 24, j = 8; j > 0; --j)
+ c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
+ crc32_table[i] = c;
+ }
+ }
+
+ while (len--)
+ {
+ crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255];
+ buf++;
+ }
+ return crc;
+}
+
+/* compare-sections command
+
+ With no arguments, compares each loadable section in the exec bfd
+ with the same memory range on the target, and reports mismatches.
+ Useful for verifying the image on the target against the exec file.
+ Depends on the target understanding the new "qCRC:" request. */
+
+static void
+compare_sections_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ asection *s;
+ unsigned long host_crc, target_crc;
+ extern bfd *exec_bfd;
+ struct cleanup *old_chain;
+ char *tmp, *sectdata, *sectname, buf[PBUFSIZ];
+ bfd_size_type size;
+ bfd_vma lma;
+ int matched = 0;
+ int mismatched = 0;
+
+ if (!exec_bfd)
+ error ("command cannot be used without an exec file");
+ if (!current_target.to_shortname ||
+ strcmp (current_target.to_shortname, "remote") != 0)
+ error ("command can only be used with remote target");
+
+ for (s = exec_bfd->sections; s; s = s->next)
+ {
+ if (!(s->flags & SEC_LOAD))
+ continue; /* skip non-loadable section */
+
+ size = bfd_get_section_size_before_reloc (s);
+ if (size == 0)
+ continue; /* skip zero-length section */
+
+ sectname = (char *) bfd_get_section_name (exec_bfd, s);
+ if (args && strcmp (args, sectname) != 0)
+ continue; /* not the section selected by user */
+
+ matched = 1; /* do this section */
+ lma = s->lma;
+ /* FIXME: assumes lma can fit into long */
+ sprintf (buf, "qCRC:%lx,%lx", (long) lma, (long) size);
+ putpkt (buf);
+
+ /* be clever; compute the host_crc before waiting for target reply */
+ sectdata = xmalloc (size);
+ old_chain = make_cleanup (free, sectdata);
+ bfd_get_section_contents (exec_bfd, s, sectdata, 0, size);
+ host_crc = crc32 ((unsigned char *) sectdata, size, 0xffffffff);
+
+ getpkt (buf, 0);
+ if (buf[0] == 'E')
+ error ("target memory fault, section %s, range 0x%08x -- 0x%08x",
+ sectname, lma, lma + size);
+ if (buf[0] != 'C')
+ error ("remote target does not support this operation");
+
+ for (target_crc = 0, tmp = &buf[1]; *tmp; tmp++)
+ target_crc = target_crc * 16 + fromhex (*tmp);
+
+ printf_filtered ("Section %s, range 0x%08x -- 0x%08x: ",
+ sectname, lma, lma + size);
+ if (host_crc == target_crc)
+ printf_filtered ("matched.\n");
+ else
+ {
+ printf_filtered ("MIS-MATCHED!\n");
+ mismatched++;
+ }
+
+ do_cleanups (old_chain);
+ }
+ if (mismatched > 0)
+ warning ("One or more sections of the remote executable does not match\n\
+the loaded file\n");
+ if (args && !matched)
+ printf_filtered ("No loaded section named '%s'.\n", args);
+}
+
+static int
+remote_query (query_type, buf, outbuf, bufsiz)
+ int query_type;
+ char *buf;
+ char *outbuf;
+ int *bufsiz;
+{
+ int i;
+ char buf2[PBUFSIZ];
+ char *p2 = &buf2[0];
+ char *p = buf;
+
+ if (! bufsiz)
+ error ("null pointer to remote bufer size specified");
+
+ /* minimum outbuf size is PBUFSIZE - if bufsiz is not large enough let
+ the caller know and return what the minimum size is */
+ /* Note: a zero bufsiz can be used to query the minimum buffer size */
+ if ( *bufsiz < PBUFSIZ )
+ {
+ *bufsiz = PBUFSIZ;
+ return -1;
+ }
+
+ /* except for querying the minimum buffer size, target must be open */
+ if (! remote_desc)
+ error ("remote query is only available after target open");
+
+ /* we only take uppercase letters as query types, at least for now */
+ if ( (query_type < 'A') || (query_type > 'Z') )
+ error ("invalid remote query type");
+
+ if (! buf)
+ error ("null remote query specified");
+
+ if (! outbuf)
+ error ("remote query requires a buffer to receive data");
+
+ outbuf[0] = '\0';
+
+ *p2++ = 'q';
+ *p2++ = query_type;
+
+ /* we used one buffer char for the remote protocol q command and another
+ for the query type. As the remote protocol encapsulation uses 4 chars
+ plus one extra in case we are debugging (remote_debug),
+ we have PBUFZIZ - 7 left to pack the query string */
+ i = 0;
+ while ( buf[i] && (i < (PBUFSIZ - 8)) )
+ {
+ /* bad caller may have sent forbidden characters */
+ if ( (!isprint(buf[i])) || (buf[i] == '$') || (buf[i] == '#') )
+ error ("illegal characters in query string");
+
+ *p2++ = buf[i];
+ i++;
+ }
+ *p2 = buf[i];
+
+ if ( buf[i] )
+ error ("query larger than available buffer");
+
+ i = putpkt (buf2);
+ if ( i < 0 ) return i;
+
+ getpkt (outbuf, 0);
+
+ return 0;
+}
+
+static void
+packet_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ char buf[PBUFSIZ];
+
+ if (! remote_desc)
+ error ("command can only be used with remote target");
+
+ if (! args)
+ error ("remote-packet command requires packet text as argument");
+
+ puts_filtered ("sending: ");
+ print_packet (args);
+ puts_filtered ("\n");
+ putpkt (args);
+
+ getpkt (buf, 0);
+ puts_filtered ("received: ");
+ print_packet (buf);
+ puts_filtered ("\n");
+}
+
+#if 0
+/* --------- UNIT_TEST for THREAD oriented PACKETS ------------------------- */
+
+static void display_thread_info PARAMS ((struct gdb_ext_thread_info *info));
+
+static void threadset_test_cmd PARAMS ((char *cmd, int tty));
+
+static void threadalive_test PARAMS ((char *cmd, int tty));
+
+static void threadlist_test_cmd PARAMS ((char *cmd, int tty));
+
+int get_and_display_threadinfo PARAMS ((threadref *ref));
+
+static void threadinfo_test_cmd PARAMS ((char *cmd, int tty));
+
+static int thread_display_step PARAMS ((threadref *ref, void *context));
+
+static void threadlist_update_test_cmd PARAMS ((char *cmd, int tty));
+
+static void init_remote_threadtests PARAMS ((void));
+
+#define SAMPLE_THREAD 0x05060708 /* Truncated 64 bit threadid */
+
+static void
+threadset_test_cmd (cmd, tty)
+ char *cmd;
+ int tty;
+{
+ int sample_thread = SAMPLE_THREAD;
+
+ printf_filtered ("Remote threadset test\n");
+ set_thread (sample_thread, 1);
+}
+
+
+static void
+threadalive_test (cmd, tty)
+ char *cmd;
+ int tty;
+{
+ int sample_thread = SAMPLE_THREAD;
+
+ if (remote_thread_alive (sample_thread))
+ printf_filtered ("PASS: Thread alive test\n");
+ else
+ printf_filtered ("FAIL: Thread alive test\n");
+}
+
+void output_threadid PARAMS ((char *title, threadref * ref));
+
+void
+output_threadid (title, ref)
+ char *title;
+ threadref *ref;
+{
+ char hexid[20];
+
+ pack_threadid (&hexid[0], ref); /* Convert threead id into hex */
+ hexid[16] = 0;
+ printf_filtered ("%s %s\n", title, (&hexid[0]));
+}
+
+static void
+threadlist_test_cmd (cmd, tty)
+ char *cmd;
+ int tty;
+{
+ int startflag = 1;
+ threadref nextthread;
+ int done, result_count;
+ threadref threadlist[3];
+
+ printf_filtered ("Remote Threadlist test\n");
+ if (!remote_get_threadlist (startflag, &nextthread, 3, &done,
+ &result_count, &threadlist[0]))
+ printf_filtered ("FAIL: threadlist test\n");
+ else
+ {
+ threadref *scan = threadlist;
+ threadref *limit = scan + result_count;
+
+ while (scan < limit)
+ output_threadid (" thread ", scan++);
+ }
+}
+
+void
+display_thread_info (info)
+ struct gdb_ext_thread_info *info;
+{
+ output_threadid ("Threadid: ", &info->threadid);
+ printf_filtered ("Name: %s\n ", info->shortname);
+ printf_filtered ("State: %s\n", info->display);
+ printf_filtered ("other: %s\n\n", info->more_display);
+}
+
+int
+get_and_display_threadinfo (ref)
+ threadref *ref;
+{
+ int result;
+ int set;
+ struct gdb_ext_thread_info threadinfo;
+
+ set = TAG_THREADID | TAG_EXISTS | TAG_THREADNAME
+ | TAG_MOREDISPLAY | TAG_DISPLAY;
+ if (0 != (result = remote_get_threadinfo (ref, set, &threadinfo)))
+ display_thread_info (&threadinfo);
+ return result;
+}
+
+static void
+threadinfo_test_cmd (cmd, tty)
+ char *cmd;
+ int tty;
+{
+ int athread = SAMPLE_THREAD;
+ threadref thread;
+ int set;
+
+ int_to_threadref (&thread, athread);
+ printf_filtered ("Remote Threadinfo test\n");
+ if (!get_and_display_threadinfo (&thread))
+ printf_filtered ("FAIL cannot get thread info\n");
+}
+
+static int
+thread_display_step (ref, context)
+ threadref *ref;
+ void *context;
+{
+ /* output_threadid(" threadstep ",ref); *//* simple test */
+ return get_and_display_threadinfo (ref);
+}
+
+static void
+threadlist_update_test_cmd (cmd, tty)
+ char *cmd;
+ int tty;
+{
+ printf_filtered ("Remote Threadlist update test\n");
+ remote_threadlist_iterator (thread_display_step, 0, CRAZY_MAX_THREADS);
+}
+
+static void
+init_remote_threadtests (void)
+{
+ add_com ("tlist", class_obscure, threadlist_test_cmd,
+ "Fetch and print the remote list of thread identifiers, one pkt only");
+ add_com ("tinfo", class_obscure, threadinfo_test_cmd,
+ "Fetch and display info about one thread");
+ add_com ("tset", class_obscure, threadset_test_cmd,
+ "Test setting to a different thread");
+ add_com ("tupd", class_obscure, threadlist_update_test_cmd,
+ "Iterate through updating all remote thread info");
+ add_com ("talive", class_obscure, threadalive_test,
+ " Remote thread alive test ");
+}
+
+#endif /* 0 */
+
+static void
+init_remote_ops ()
+{
+ remote_ops.to_shortname = "remote";
+ remote_ops.to_longname = "Remote serial target in gdb-specific protocol";
+ remote_ops.to_doc =
+ "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ remote_ops.to_open = remote_open;
+ remote_ops.to_close = remote_close;
+ remote_ops.to_detach = remote_detach;
+ remote_ops.to_resume = remote_resume;
+ remote_ops.to_wait = remote_wait;
+ remote_ops.to_fetch_registers = remote_fetch_registers;
+ remote_ops.to_store_registers = remote_store_registers;
+ remote_ops.to_prepare_to_store = remote_prepare_to_store;
+ remote_ops.to_xfer_memory = remote_xfer_memory;
+ remote_ops.to_files_info = remote_files_info;
+ remote_ops.to_insert_breakpoint = remote_insert_breakpoint;
+ remote_ops.to_remove_breakpoint = remote_remove_breakpoint;
+ remote_ops.to_kill = remote_kill;
+ remote_ops.to_load = generic_load;
+ remote_ops.to_mourn_inferior = remote_mourn;
+ remote_ops.to_thread_alive = remote_thread_alive;
+ remote_ops.to_stop = remote_stop;
+ remote_ops.to_query = remote_query;
+ remote_ops.to_stratum = process_stratum;
+ remote_ops.to_has_all_memory = 1;
+ remote_ops.to_has_memory = 1;
+ remote_ops.to_has_stack = 1;
+ remote_ops.to_has_registers = 1;
+ remote_ops.to_has_execution = 1;
+ remote_ops.to_has_thread_control = tc_schedlock; /* can lock scheduler */
+ remote_ops.to_magic = OPS_MAGIC;
+}
+
+/* Set up the extended remote vector by making a copy of the standard
+ remote vector and adding to it. */
+
+static void
+init_extended_remote_ops ()
+{
+ extended_remote_ops = remote_ops;
+
+ extended_remote_ops.to_shortname = "extended-remote";
+ extended_remote_ops.to_longname =
+ "Extended remote serial target in gdb-specific protocol";
+ extended_remote_ops.to_doc =
+ "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).",
+ extended_remote_ops.to_open = extended_remote_open;
+ extended_remote_ops.to_create_inferior = extended_remote_create_inferior;
+ extended_remote_ops.to_mourn_inferior = extended_remote_mourn;
+}
void
_initialize_remote ()
{
+ init_remote_ops ();
add_target (&remote_ops);
+
+ init_extended_remote_ops ();
add_target (&extended_remote_ops);
+ init_remote_threads ();
+#if 0
+ init_remote_threadtests ();
+#endif
- add_show_from_set (add_set_cmd ("remotetimeout", no_class,
- var_integer, (char *)&remote_timeout,
- "Set timeout value for remote read.\n", &setlist),
- &showlist);
+ add_cmd ("compare-sections", class_obscure, compare_sections_command,
+ "Compare section data on target to the exec file.\n\
+Argument is a single section name (default: all loaded sections).",
+ &cmdlist);
- add_show_from_set (add_set_cmd ("remotebreak", no_class,
- var_integer, (char *)&remote_break,
- "Set whether to send break if interrupted.\n", &setlist),
- &showlist);
+ add_cmd ("packet", class_maintenance, packet_command,
+ "Send an arbitrary packet to a remote target.\n\
+ maintenance packet TEXT\n\
+If GDB is talking to an inferior via the GDB serial protocol, then\n\
+this command sends the string TEXT to the inferior, and displays the\n\
+response packet. GDB supplies the initial `$' character, and the\n\
+terminating `#' character and checksum.",
+ &maintenancelist);
#ifdef REMOTE_CHAT
- add_show_from_set (add_set_cmd ("remotechat", no_class,
- var_zinteger, (char *)&remote_chat,
- "Set remote port interacts with target.\n", &setlist),
- &showlist);
+ add_show_from_set
+ (add_set_cmd ("remotechat", no_class,
+ var_zinteger, (char *)&remote_chat,
+ "Set remote port interacts with target.\n",
+ &setlist),
+ &showlist);
#endif /* REMOTE_CHAT */
+
+ add_show_from_set
+ (add_set_cmd ("remotetimeout", no_class,
+ var_integer, (char *)&remote_timeout,
+ "Set timeout value for remote read.\n",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ("remotebreak", no_class,
+ var_integer, (char *)&remote_break,
+ "Set whether to send break if interrupted.\n",
+ &setlist),
+ &showlist);
+
+ add_show_from_set
+ (add_set_cmd ("remotewritesize", no_class,
+ var_integer, (char *)&remote_write_size,
+ "Set the maximum number of bytes per memory write packet.\n",
+ &setlist),
+ &showlist);
+
+ remote_address_size = TARGET_PTR_BIT;
+ add_show_from_set
+ (add_set_cmd ("remoteaddresssize", class_obscure,
+ var_integer, (char *)&remote_address_size,
+ "Set the maximum size of the address (in bits) \
+in a memory packet.\n",
+ &setlist),
+ &showlist);
+
+ add_show_from_set (add_set_cmd ("remotebinarydownload", no_class,
+ var_boolean, (char *) &remote_binary_download,
+ "Set binary downloads.\n", &setlist),
+ &showlist);
}
diff --git a/contrib/gdb/gdb/ser-unix.c b/contrib/gdb/gdb/ser-unix.c
index f5dbaa0..d804de1 100644
--- a/contrib/gdb/gdb/ser-unix.c
+++ b/contrib/gdb/gdb/ser-unix.c
@@ -1,5 +1,5 @@
/* Serial interface for local (hardwired) serial ports on Un*x like systems
- Copyright 1992, 1993, 1994 Free Software Foundation, Inc.
+ Copyright 1992, 1993, 1994, 1998 Free Software Foundation, Inc.
This file is part of GDB.
@@ -69,12 +69,25 @@ static int hardwire_readchar PARAMS ((serial_t scb, int timeout));
static int rate_to_code PARAMS ((int rate));
static int hardwire_setbaudrate PARAMS ((serial_t scb, int rate));
static int hardwire_write PARAMS ((serial_t scb, const char *str, int len));
-/* FIXME: static void hardwire_restore PARAMS ((serial_t scb)); */
static void hardwire_close PARAMS ((serial_t scb));
static int get_tty_state PARAMS ((serial_t scb, struct hardwire_ttystate *state));
static int set_tty_state PARAMS ((serial_t scb, struct hardwire_ttystate *state));
static serial_ttystate hardwire_get_tty_state PARAMS ((serial_t scb));
static int hardwire_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
+static int hardwire_noflush_set_tty_state PARAMS ((serial_t, serial_ttystate,
+ serial_ttystate));
+static void hardwire_print_tty_state PARAMS ((serial_t, serial_ttystate));
+static int hardwire_drain_output PARAMS ((serial_t));
+static int hardwire_flush_output PARAMS ((serial_t));
+static int hardwire_flush_input PARAMS ((serial_t));
+static int hardwire_send_break PARAMS ((serial_t));
+static int hardwire_setstopbits PARAMS ((serial_t, int));
+
+void _initialize_ser_hardwire PARAMS ((void));
+
+#ifdef __CYGWIN32__
+extern void (*ui_loop_hook) PARAMS ((int));
+#endif
/* Open up a real live device for serial I/O */
@@ -91,13 +104,11 @@ hardwire_open(scb, name)
}
static int
-get_tty_state(scb, state)
+get_tty_state (scb, state)
serial_t scb;
struct hardwire_ttystate *state;
{
#ifdef HAVE_TERMIOS
- extern int errno;
-
if (tcgetattr(scb->fd, &state->termios) < 0)
return -1;
@@ -269,6 +280,38 @@ hardwire_print_tty_state (scb, ttystate)
#endif
}
+/* Wait for the output to drain away, as opposed to flushing (discarding) it */
+
+static int
+hardwire_drain_output (scb)
+ serial_t scb;
+{
+#ifdef HAVE_TERMIOS
+ return tcdrain (scb->fd);
+#endif
+
+#ifdef HAVE_TERMIO
+ return ioctl (scb->fd, TCSBRK, 1);
+#endif
+
+#ifdef HAVE_SGTTY
+ /* Get the current state and then restore it using TIOCSETP,
+ which should cause the output to drain and pending input
+ to be discarded. */
+ {
+ struct hardwire_ttystate state;
+ if (get_tty_state (scb, &state))
+ {
+ return (-1);
+ }
+ else
+ {
+ return (ioctl (scb->fd, TIOCSETP, &state.sgttyb));
+ }
+ }
+#endif
+}
+
static int
hardwire_flush_output (scb)
serial_t scb;
@@ -391,7 +434,9 @@ wait_for(scb, timeout)
serial_t scb;
int timeout;
{
+#ifndef __CYGWIN32__
scb->timeout_remaining = 0;
+#endif
#ifdef HAVE_SGTTY
{
@@ -500,21 +545,37 @@ wait_for(scb, timeout)
to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
char if successful. Returns SERIAL_TIMEOUT if timeout expired, EOF if line
dropped dead, or SERIAL_ERROR for any other error (see errno in that case). */
-
static int
-hardwire_readchar(scb, timeout)
+hardwire_readchar (scb, timeout)
serial_t scb;
int timeout;
{
int status;
+#ifdef __CYGWIN32__
+ int t;
+#endif
if (scb->bufcnt-- > 0)
return *scb->bufp++;
+#ifdef __CYGWIN32__
+ if (timeout > 0)
+ timeout++;
+#endif
+
while (1)
{
+#ifdef __CYGWIN32__
+ t = timeout == 0 ? 0 : 1;
+ scb->timeout_remaining = timeout < 0 ? timeout : timeout - t;
+ status = wait_for (scb, t);
+
+ /* -2 means disable timer */
+ if (ui_loop_hook)
+ ui_loop_hook (-2);
+#else
status = wait_for (scb, timeout);
-
+#endif
if (status < 0)
return status;
@@ -531,6 +592,10 @@ hardwire_readchar(scb, timeout)
timeout = scb->timeout_remaining;
continue;
}
+#ifdef __CYGWIN32__
+ else if (scb->timeout_remaining < 0)
+ continue;
+#endif
else
return SERIAL_TIMEOUT;
}
@@ -591,6 +656,9 @@ baudtab[] =
#ifdef B230400
{230400, B230400},
#endif
+#ifdef B460800
+ {460800, B460800},
+#endif
{-1, -1},
};
@@ -733,6 +801,7 @@ static struct serial_ops hardwire_ops =
hardwire_noflush_set_tty_state,
hardwire_setbaudrate,
hardwire_setstopbits,
+ hardwire_drain_output, /* wait for output to drain */
};
void
diff --git a/contrib/gdb/gdb/solib.c b/contrib/gdb/gdb/solib.c
index 4fd3344..5ca5f28 100644
--- a/contrib/gdb/gdb/solib.c
+++ b/contrib/gdb/gdb/solib.c
@@ -1,5 +1,5 @@
/* Handle SunOS and SVR4 shared libraries for GDB, the GNU Debugger.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 98, 1999
Free Software Foundation, Inc.
This file is part of GDB.
@@ -71,6 +71,7 @@ static char *solib_break_names[] = {
"r_debug_state",
"_r_debug_state",
"_dl_debug_state",
+ "rtld_db_dlactivity",
NULL
};
#endif
@@ -149,12 +150,20 @@ static struct so_list *so_list_head; /* List of known shared objects */
static CORE_ADDR debug_base; /* Base of dynamic linker structures */
static CORE_ADDR breakpoint_addr; /* Address where end bkpt is set */
+static int solib_cleanup_queued = 0; /* make_run_cleanup called */
+
extern int
fdmatch PARAMS ((int, int)); /* In libiberty */
/* Local function prototypes */
static void
+do_clear_solib PARAMS ((PTR));
+
+static int
+match_main PARAMS ((char *));
+
+static void
special_symbol_handling PARAMS ((struct so_list *));
static void
@@ -166,8 +175,7 @@ enable_break PARAMS ((void));
static void
info_sharedlibrary_command PARAMS ((char *, int));
-static int
-symbol_add_stub PARAMS ((char *));
+static int symbol_add_stub PARAMS ((PTR));
static struct so_list *
alloc_solib PARAMS ((struct link_map *));
@@ -184,8 +192,7 @@ first_link_map_member PARAMS ((void));
static CORE_ADDR
locate_base PARAMS ((void));
-static void
-solib_map_sections PARAMS ((struct so_list *));
+static int solib_map_sections PARAMS ((PTR));
#ifdef SVR4_SHARED_LIBS
@@ -205,6 +212,17 @@ solib_add_common_symbols PARAMS ((struct rtc_symb *));
#endif
+void _initialize_solib PARAMS ((void));
+
+/* If non-zero, this is a prefix that will be added to the front of the name
+ shared libraries with an absolute filename for loading. */
+static char *solib_absolute_prefix = NULL;
+
+/* If non-empty, this is a search path for loading non-absolute shared library
+ symbol files. This takes precedence over the environment variables PATH
+ and LD_LIBRARY_PATH. */
+static char *solib_search_path = NULL;
+
/*
LOCAL FUNCTION
@@ -213,7 +231,7 @@ LOCAL FUNCTION
SYNOPSIS
- static void solib_map_sections (struct so_list *so)
+ static int solib_map_sections (struct so_list *so)
DESCRIPTION
@@ -232,10 +250,11 @@ FIXMES
expansion stuff?).
*/
-static void
-solib_map_sections (so)
- struct so_list *so;
+static int
+solib_map_sections (arg)
+ PTR arg;
{
+ struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */
char *filename;
char *scratch_pathname;
int scratch_chan;
@@ -244,10 +263,38 @@ solib_map_sections (so)
bfd *abfd;
filename = tilde_expand (so -> so_name);
- old_chain = make_cleanup (free, filename);
- scratch_chan = openp (get_in_environ (inferior_environ, "PATH"),
- 1, filename, O_RDONLY, 0, &scratch_pathname);
+ if (solib_absolute_prefix && ROOTED_P (filename))
+ /* Prefix shared libraries with absolute filenames with
+ SOLIB_ABSOLUTE_PREFIX. */
+ {
+ char *pfxed_fn;
+ int pfx_len;
+
+ pfx_len = strlen (solib_absolute_prefix);
+
+ /* Remove trailing slashes. */
+ while (pfx_len > 0 && SLASH_P (solib_absolute_prefix[pfx_len - 1]))
+ pfx_len--;
+
+ pfxed_fn = xmalloc (pfx_len + strlen (filename) + 1);
+ strcpy (pfxed_fn, solib_absolute_prefix);
+ strcat (pfxed_fn, filename);
+ free (filename);
+
+ filename = pfxed_fn;
+ }
+
+ old_chain = make_cleanup (free, filename);
+
+ scratch_chan = -1;
+
+ if (solib_search_path)
+ scratch_chan = openp (solib_search_path,
+ 1, filename, O_RDONLY, 0, &scratch_pathname);
+ if (scratch_chan < 0)
+ scratch_chan = openp (get_in_environ (inferior_environ, "PATH"),
+ 1, filename, O_RDONLY, 0, &scratch_pathname);
if (scratch_chan < 0)
{
scratch_chan = openp (get_in_environ
@@ -304,6 +351,8 @@ solib_map_sections (so)
/* Free the file names, close the file now. */
do_cleanups (old_chain);
+
+ return (1);
}
#ifndef SVR4_SHARED_LIBS
@@ -357,7 +406,6 @@ solib_add_common_symbols (rtc_symp)
struct nlist inferior_rtc_nlist;
int len;
char *name;
- char *origname;
/* Remove any runtime common symbols from previous runs. */
@@ -371,7 +419,7 @@ solib_add_common_symbols (rtc_symp)
}
init_minimal_symbol_collection ();
- make_cleanup (discard_minimal_symbols, 0);
+ make_cleanup ((make_cleanup_func) discard_minimal_symbols, 0);
while (rtc_symp)
{
@@ -388,18 +436,16 @@ solib_add_common_symbols (rtc_symp)
behind the name of the symbol. */
len = inferior_rtc_nlist.n_value - inferior_rtc_nlist.n_un.n_strx;
- origname = name = xmalloc (len);
+ name = xmalloc (len);
read_memory ((CORE_ADDR) inferior_rtc_nlist.n_un.n_name, name, len);
/* Allocate the runtime common objfile if necessary. */
if (rt_common_objfile == NULL)
allocate_rt_common_objfile ();
- name = obsavestring (name, strlen (name),
- &rt_common_objfile -> symbol_obstack);
prim_record_minimal_symbol (name, inferior_rtc_nlist.n_value,
mst_bss, rt_common_objfile);
- free (origname);
+ free (name);
}
rtc_symp = inferior_rtc_symb.rtc_next;
}
@@ -567,7 +613,7 @@ look_for_base (fd, baseaddr)
if (fd == -1
|| (exec_bfd != NULL
- && fdmatch (fileno ((GDB_FILE *)(exec_bfd -> iostream)), fd)))
+ && fdmatch (fileno ((FILE *)(exec_bfd -> iostream)), fd)))
{
return (0);
}
@@ -675,8 +721,7 @@ elf_locate_base ()
/* Find the DT_DEBUG entry in the the .dynamic section.
For mips elf we look for DT_MIPS_RLD_MAP, mips elf apparently has
no DT_DEBUG entries. */
- /* FIXME: In lack of a 64 bit ELF ABI the following code assumes
- a 32 bit ELF ABI target. */
+#ifndef TARGET_ELF64
for (bufend = buf + dyninfo_sect_size;
buf < bufend;
buf += sizeof (Elf32_External_Dyn))
@@ -707,6 +752,25 @@ elf_locate_base ()
}
#endif
}
+#else /* ELF64 */
+ for (bufend = buf + dyninfo_sect_size;
+ buf < bufend;
+ buf += sizeof (Elf64_External_Dyn))
+ {
+ Elf64_External_Dyn *x_dynp = (Elf64_External_Dyn *)buf;
+ long dyn_tag;
+ CORE_ADDR dyn_ptr;
+
+ dyn_tag = bfd_h_get_64 (exec_bfd, (bfd_byte *) x_dynp->d_tag);
+ if (dyn_tag == DT_NULL)
+ break;
+ else if (dyn_tag == DT_DEBUG)
+ {
+ dyn_ptr = bfd_h_get_64 (exec_bfd, (bfd_byte *) x_dynp->d_un.d_ptr);
+ return dyn_ptr;
+ }
+ }
+#endif
/* DT_DEBUG entry not found. */
return 0;
@@ -790,7 +854,7 @@ locate_base ()
debug_base = elf_locate_base ();
#ifdef HANDLE_SVR4_EXEC_EMULATORS
/* Try it the hard way for emulated executables. */
- else if (inferior_pid != 0)
+ else if (inferior_pid != 0 && target_has_execution)
proc_iterate_over_mappings (look_for_base);
#endif
}
@@ -976,6 +1040,7 @@ find_solib (so_list_ptr, maybe_changed)
{
struct link_map *lm = NULL;
struct so_list *new;
+ struct so_list *so_list_next;
struct so_list *p, **prev;
if (so_list_ptr == NULL)
@@ -1068,14 +1133,43 @@ find_solib (so_list_ptr, maybe_changed)
{
if (so_list_ptr != NULL)
{
- /* Libs have been deleted from the end of the list */
- while (so_list_ptr != NULL)
+ so_list_head = new;
+
+ if (! solib_cleanup_queued)
{
- *prev = so_list_ptr -> next;
- free_solib (so_list_ptr);
- so_list_ptr = *prev;
+ make_run_cleanup (do_clear_solib, NULL);
+ solib_cleanup_queued = 1;
}
- }
+
+ }
+ so_list_next = new;
+ if (lm)
+ target_read_memory ((CORE_ADDR) lm, (char *) &(new -> lm),
+ sizeof (struct link_map));
+ /* For SVR4 versions, the first entry in the link map is for the
+ inferior executable, so we must ignore it. For some versions of
+ SVR4, it has no name. For others (Solaris 2.3 for example), it
+ does have a name, so we can no longer use a missing name to
+ decide when to ignore it. */
+ if (!IGNORE_FIRST_LINK_MAP_ENTRY (new -> lm))
+ {
+ int errcode;
+ char *buffer;
+ target_read_string ((CORE_ADDR) LM_NAME (new), &buffer,
+ MAX_PATH_SIZE - 1, &errcode);
+ if (errcode != 0)
+ {
+ warning ("find_solib: Can't read pathname for load map: %s\n",
+ safe_strerror (errcode));
+ return (so_list_next);
+ }
+ strncpy (new -> so_name, buffer, MAX_PATH_SIZE - 1);
+ new -> so_name[MAX_PATH_SIZE - 1] = '\0';
+ free (buffer);
+ catch_errors (solib_map_sections, new,
+ "Error while mapping shared library sections:\n",
+ RETURN_MASK_ALL);
+ }
}
return (so_list_ptr);
@@ -1085,16 +1179,38 @@ find_solib (so_list_ptr, maybe_changed)
static int
symbol_add_stub (arg)
- char *arg;
+ PTR arg;
{
register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */
+ CORE_ADDR text_addr = 0;
+
+ if (so -> textsection)
+ text_addr = so -> textsection -> addr;
+ else if (so -> abfd != NULL)
+ {
+ asection *lowest_sect;
+
+ /* If we didn't find a mapped non zero sized .text section, set up
+ text_addr so that the relocation in symbol_file_add does no harm. */
+
+ lowest_sect = bfd_get_section_by_name (so -> abfd, ".text");
+ if (lowest_sect == NULL)
+ bfd_map_over_sections (so -> abfd, find_lowest_section,
+ (PTR) &lowest_sect);
+ if (lowest_sect)
+ text_addr = bfd_section_vma (so -> abfd, lowest_sect)
+ + (CORE_ADDR) LM_ADDR (so);
+ }
+ ALL_OBJFILES (so -> objfile)
+ {
+ if (strcmp (so -> objfile -> name, so -> so_name) == 0)
+ return 1;
+ }
so -> objfile =
symbol_file_add (so -> so_name, so -> from_tty,
- (so->textsection == NULL
- ? 0
- : (unsigned int) so -> textsection -> addr),
- 0, 0, 0);
+ text_addr,
+ 0, 0, 0, 0, 1);
return (1);
}
@@ -1173,7 +1289,7 @@ solib_add (arg_string, from_tty, target)
here, otherwise we dereference a potential dangling pointer
for each call to target_read/write_memory within this routine. */
update_coreops = core_ops.to_sections == target->to_sections;
-
+
/* Reallocate the target's section table including the new size. */
if (target -> to_sections)
{
@@ -1228,7 +1344,7 @@ solib_add (arg_string, from_tty, target)
}
}
else if (catch_errors
- (symbol_add_stub, (char *) so,
+ (symbol_add_stub, so,
"Error while reading shared library symbols:\n",
RETURN_MASK_ALL))
{
@@ -1270,30 +1386,41 @@ info_sharedlibrary_command (ignore, from_tty)
{
register struct so_list *so = NULL; /* link map state variable */
int header_done = 0;
-
+ int addr_width;
+ char *addr_fmt;
+
if (exec_bfd == NULL)
{
printf_unfiltered ("No exec file.\n");
return;
}
+
+#ifndef TARGET_ELF64
+ addr_width = 8+4;
+ addr_fmt = "08l";
+#else
+ addr_width = 16+4;
+ addr_fmt = "016l";
+#endif
+
while ((so = find_solib (so, 0)) != NULL)
{
if (so -> so_name[0])
{
if (!header_done)
{
- printf_unfiltered("%-12s%-12s%-12s%s\n", "From", "To", "Syms Read",
- "Shared Object Library");
+ printf_unfiltered("%-*s%-*s%-12s%s\n", addr_width, "From",
+ addr_width, "To", "Syms Read",
+ "Shared Object Library");
header_done++;
}
- /* FIXME-32x64: need print_address_numeric with field width or
- some such. */
- printf_unfiltered ("%-12s",
+
+ printf_unfiltered ("%-*s", addr_width,
local_hex_string_custom ((unsigned long) LM_ADDR (so),
- "08l"));
- printf_unfiltered ("%-12s",
+ addr_fmt));
+ printf_unfiltered ("%-*s", addr_width,
local_hex_string_custom ((unsigned long) so -> lmend,
- "08l"));
+ addr_fmt));
printf_unfiltered ("%-12s", so -> symbols_loaded ? "Yes" : "No");
printf_unfiltered ("%s\n", so -> so_name);
}
@@ -1352,6 +1479,7 @@ void
clear_solib()
{
struct so_list *next;
+ char *bfd_filename;
while (so_list_head)
{
@@ -1362,6 +1490,34 @@ clear_solib()
debug_base = 0;
}
+static void
+do_clear_solib (dummy)
+ PTR dummy;
+{
+ solib_cleanup_queued = 0;
+ clear_solib ();
+}
+
+#ifdef SVR4_SHARED_LIBS
+
+/* Return 1 if PC lies in the dynamic symbol resolution code of the
+ SVR4 run time loader. */
+
+static CORE_ADDR interp_text_sect_low;
+static CORE_ADDR interp_text_sect_high;
+static CORE_ADDR interp_plt_sect_low;
+static CORE_ADDR interp_plt_sect_high;
+
+int
+in_svr4_dynsym_resolve_code (pc)
+ CORE_ADDR pc;
+{
+ return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
+ || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
+ || in_plt_section (pc, NULL));
+}
+#endif
+
/*
LOCAL FUNCTION
@@ -1522,6 +1678,9 @@ enable_break ()
remove_solib_event_breakpoints ();
#ifdef SVR4_SHARED_LIBS
+ interp_text_sect_low = interp_text_sect_high = 0;
+ interp_plt_sect_low = interp_plt_sect_high = 0;
+
/* Find the .interp section; if not found, warn the user and drop
into the old breakpoint at symbol code. */
interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
@@ -1546,7 +1705,7 @@ enable_break ()
This address is stored on the stack. However, I've been unable
to find any magic formula to find it for Solaris (appears to
- be trivial on Linux). Therefore, we have to try an alternate
+ be trivial on GNU/Linux). Therefore, we have to try an alternate
mechanism to find the dynamic linker's base address. */
tmp_bfd = bfd_openr (buf, gnutarget);
if (tmp_bfd == NULL)
@@ -1565,6 +1724,25 @@ enable_break ()
linker) and subtracting the offset of the entry point. */
load_addr = read_pc () - tmp_bfd->start_address;
+ /* Record the relocated start and end address of the dynamic linker
+ text and plt section for in_svr4_dynsym_resolve_code. */
+ interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
+ if (interp_sect)
+ {
+ interp_text_sect_low =
+ bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
+ interp_text_sect_high =
+ interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect);
+ }
+ interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
+ if (interp_sect)
+ {
+ interp_plt_sect_low =
+ bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
+ interp_plt_sect_high =
+ interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect);
+ }
+
/* Now try to set a breakpoint in the dynamic linker. */
for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++)
{
@@ -1585,9 +1763,7 @@ enable_break ()
/* For whatever reason we couldn't set a breakpoint in the dynamic
linker. Warn and drop into the old code. */
bkpt_at_symbol:
- warning ("Unable to find dynamic linker breakpoint function.");
- warning ("GDB will be unable to debug shared library initializers");
- warning ("and track explicitly loaded dynamic code.");
+ warning ("Unable to find dynamic linker breakpoint function.\nGDB will be unable to debug shared library initializers\nand track explicitly loaded dynamic code.");
}
#endif
@@ -1606,7 +1782,7 @@ bkpt_at_symbol:
}
/* Nothing good happened. */
- return 0;
+ success = 0;
#endif /* BKPT_AT_SYMBOL */
@@ -1688,8 +1864,8 @@ solib_create_inferior_hook()
return;
}
-#ifndef SVR4_SHARED_LIBS
- /* Only SunOS needs the loop below, other systems should be using the
+#if !defined(SVR4_SHARED_LIBS) || defined(_SCO_DS)
+ /* SCO and SunOS need the loop below, other systems should be using the
special shared library breakpoints and the shared library breakpoint
service routine.
@@ -1708,7 +1884,8 @@ solib_create_inferior_hook()
}
while (stop_signal != TARGET_SIGNAL_TRAP);
stop_soon_quietly = 0;
-
+
+#if !defined(_SCO_DS)
/* We are now either at the "mapping complete" breakpoint (or somewhere
else, a condition we aren't prepared to deal with anyway), so adjust
the PC as necessary after a breakpoint, disable the breakpoint, and
@@ -1727,6 +1904,7 @@ solib_create_inferior_hook()
if (auto_solib_add)
solib_add ((char *) 0, 0, (struct target_ops *) 0);
+#endif /* ! _SCO_DS */
#endif
}
@@ -1844,5 +2022,20 @@ must be loaded manually, using `sharedlibrary'.",
&setlist),
&showlist);
+ add_show_from_set
+ (add_set_cmd ("solib-absolute-prefix", class_support, var_filename,
+ (char *) &solib_absolute_prefix,
+ "Set prefix for loading absolute shared library symbol files.\n\
+For other (relative) files, you can add values using `set solib-search-path'.",
+ &setlist),
+ &showlist);
+ add_show_from_set
+ (add_set_cmd ("solib-search-path", class_support, var_string,
+ (char *) &solib_search_path,
+ "Set the search path for loading non-absolute shared library symbol files.\n\
+This takes precedence over the environment variables PATH and LD_LIBRARY_PATH.",
+ &setlist),
+ &showlist);
+
#endif /* HAVE_LINK_H */
}
diff --git a/contrib/gdb/gdb/symfile.c b/contrib/gdb/gdb/symfile.c
index 4604678..7b26625 100644
--- a/contrib/gdb/gdb/symfile.c
+++ b/contrib/gdb/gdb/symfile.c
@@ -1,5 +1,5 @@
/* Generic symbol file reading for the GNU debugger, GDB.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998
Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
@@ -34,10 +34,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "complaints.h"
#include "demangle.h"
#include "inferior.h" /* for write_pc */
-
+#include "gdb-stabs.h"
#include "obstack.h"
-#include <assert.h>
+#include <assert.h>
#include <sys/types.h>
#include <fcntl.h>
#include "gdb_string.h"
@@ -52,6 +52,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define O_BINARY 0
#endif
+#ifdef HPUXHPPA
+
+/* Some HP-UX related globals to clear when a new "main"
+ symbol file is loaded. HP-specific. */
+
+extern int hp_som_som_object_present;
+extern int hp_cxx_exception_support_initialized;
+#define RESET_HP_UX_GLOBALS() do {\
+ hp_som_som_object_present = 0; /* indicates HP-compiled code */ \
+ hp_cxx_exception_support_initialized = 0; /* must reinitialize exception stuff */ \
+ } while (0)
+#endif
+
+int (*ui_load_progress_hook) PARAMS ((char *, unsigned long));
+void (*pre_add_symbol_hook) PARAMS ((char *));
+void (*post_add_symbol_hook) PARAMS ((void));
+
/* Global variables owned by this file */
int readnow_symbol_files; /* Read full symbols immediately */
@@ -67,34 +84,65 @@ struct complaint empty_symtab_complaint = {
extern int info_verbose;
+extern void report_transfer_performance PARAMS ((unsigned long,
+ time_t, time_t));
+
/* Functions this file defines */
-static void
-set_initial_language PARAMS ((void));
+#if 0
+static int simple_read_overlay_region_table PARAMS ((void));
+static void simple_free_overlay_region_table PARAMS ((void));
+#endif
-static void
-load_command PARAMS ((char *, int));
+static void set_initial_language PARAMS ((void));
-static void
-add_symbol_file_command PARAMS ((char *, int));
+static void load_command PARAMS ((char *, int));
-static void
-add_shared_symbol_files_command PARAMS ((char *, int));
+static void add_symbol_file_command PARAMS ((char *, int));
-static void
-cashier_psymtab PARAMS ((struct partial_symtab *));
+static void add_shared_symbol_files_command PARAMS ((char *, int));
-static int
-compare_psymbols PARAMS ((const void *, const void *));
+static void cashier_psymtab PARAMS ((struct partial_symtab *));
-static int
-compare_symbols PARAMS ((const void *, const void *));
+static int compare_psymbols PARAMS ((const void *, const void *));
-static bfd *
-symfile_bfd_open PARAMS ((char *));
+static int compare_symbols PARAMS ((const void *, const void *));
-static void
-find_sym_fns PARAMS ((struct objfile *));
+bfd *symfile_bfd_open PARAMS ((char *));
+
+static void find_sym_fns PARAMS ((struct objfile *));
+
+static void decrement_reading_symtab PARAMS ((void *));
+
+static void overlay_invalidate_all PARAMS ((void));
+
+static int overlay_is_mapped PARAMS ((struct obj_section *));
+
+void list_overlays_command PARAMS ((char *, int));
+
+void map_overlay_command PARAMS ((char *, int));
+
+void unmap_overlay_command PARAMS ((char *, int));
+
+static void overlay_auto_command PARAMS ((char *, int));
+
+static void overlay_manual_command PARAMS ((char *, int));
+
+static void overlay_off_command PARAMS ((char *, int));
+
+static void overlay_load_command PARAMS ((char *, int));
+
+static void overlay_command PARAMS ((char *, int));
+
+static void simple_free_overlay_table PARAMS ((void));
+
+static void read_target_long_array PARAMS ((CORE_ADDR, unsigned int *, int));
+
+static int simple_read_overlay_table PARAMS ((void));
+
+static int simple_overlay_update_1 PARAMS ((struct obj_section *));
+
+void _initialize_symfile PARAMS ((void));
/* List of all available sym_fns. On gdb startup, each object file reader
calls add_symtab_fns() to register information on each format it is
@@ -111,15 +159,25 @@ int symbol_reloading = SYMBOL_RELOADING_DEFAULT;
int symbol_reloading = 0;
#endif
-/* If true, then shared library symbols will be added automatically
- when the inferior is created, new libraries are loaded, or when
- attaching to the inferior. This is almost always what users
+/* If non-zero, then on HP-UX (i.e., platforms that use somsolib.c),
+ this variable is interpreted as a threshhold. If adding a new
+ library's symbol table to those already known to the debugger would
+ exceed this threshhold, then the shlib's symbols are not added.
+
+ If non-zero on other platforms, shared library symbols will be added
+ automatically when the inferior is created, new libraries are loaded,
+ or when attaching to the inferior. This is almost always what users
will want to have happen; but for very large programs, the startup
time will be excessive, and so if this is a problem, the user can
clear this flag and then add the shared library symbols as needed.
Note that there is a potential for confusion, since if the shared
library symbols are not loaded, commands like "info fun" will *not*
- report all the functions that are actually present. */
+ report all the functions that are actually present.
+
+ Note that HP-UX interprets this variable to mean, "threshhold size
+ in megabytes, where zero means never add". Other platforms interpret
+ this variable to mean, "always add if non-zero, never add if zero."
+ */
int auto_solib_add = 1;
@@ -181,7 +239,19 @@ compare_psymbols (s1p, s2p)
}
else
{
- return (STRCMP (st1 + 2, st2 + 2));
+ /* Note: I replaced the STRCMP line (commented out below)
+ * with a simpler "strcmp()" which compares the 2 strings
+ * from the beginning. (STRCMP is a macro which first compares
+ * the initial characters, then falls back on strcmp).
+ * The reason is that the STRCMP line was tickling a C compiler
+ * bug on HP-UX 10.30, which is avoided with the simpler
+ * code. The performance gain from the more complicated code
+ * is negligible, given that we have already checked the
+ * initial 2 characters above. I reported the compiler bug,
+ * and once it is fixed the original line can be put back. RT
+ */
+ /* return ( STRCMP (st1 + 2, st2 + 2)); */
+ return ( strcmp (st1, st2));
}
}
@@ -230,9 +300,10 @@ sort_symtab_syms (s)
}
}
-/* Make a copy of the string at PTR with SIZE characters in the symbol obstack
- (and add a null character at the end in the copy).
- Returns the address of the copy. */
+/* Make a null terminated copy of the string at PTR with SIZE characters in
+ the obstack pointed to by OBSTACKP . Returns the address of the copy.
+ Note that the string at PTR does not have to be null terminated, I.E. it
+ may be part of a larger string and we are only saving a substring. */
char *
obsavestring (ptr, size, obstackp)
@@ -241,8 +312,9 @@ obsavestring (ptr, size, obstackp)
struct obstack *obstackp;
{
register char *p = (char *) obstack_alloc (obstackp, size + 1);
- /* Open-coded memcpy--saves function call time.
- These strings are usually short. */
+ /* Open-coded memcpy--saves function call time. These strings are usually
+ short. FIXME: Is this really still true with a compiler that can
+ inline memcpy? */
{
register char *p1 = ptr;
register char *p2 = p;
@@ -254,8 +326,8 @@ obsavestring (ptr, size, obstackp)
return p;
}
-/* Concatenate strings S1, S2 and S3; return the new string.
- Space is found in the symbol_obstack. */
+/* Concatenate strings S1, S2 and S3; return the new string. Space is found
+ in the obstack pointed to by OBSTACKP. */
char *
obconcat (obstackp, s1, s2, s3)
@@ -371,6 +443,31 @@ find_lowest_section (abfd, sect, obj)
*lowest = sect;
}
+/* Parse the user's idea of an offset for dynamic linking, into our idea
+ of how to represent it for fast symbol reading. This is the default
+ version of the sym_fns.sym_offsets function for symbol readers that
+ don't need to do anything special. It allocates a section_offsets table
+ for the objectfile OBJFILE and stuffs ADDR into all of the offsets. */
+
+struct section_offsets *
+default_symfile_offsets (objfile, addr)
+ struct objfile *objfile;
+ CORE_ADDR addr;
+{
+ struct section_offsets *section_offsets;
+ int i;
+
+ objfile->num_sections = SECT_OFF_MAX;
+ section_offsets = (struct section_offsets *)
+ obstack_alloc (&objfile -> psymbol_obstack, SIZEOF_SECTION_OFFSETS);
+
+ for (i = 0; i < SECT_OFF_MAX; i++)
+ ANOFFSET (section_offsets, i) = addr;
+
+ return section_offsets;
+}
+
+
/* Process a symbol file, as either the main file or as a dynamically
loaded file.
@@ -399,13 +496,13 @@ syms_from_objfile (objfile, addr, mainline, verbo)
/* Make sure that partially constructed symbol tables will be cleaned up
if an error occurs during symbol reading. */
- old_chain = make_cleanup (free_objfile, objfile);
+ old_chain = make_cleanup ((make_cleanup_func) free_objfile, objfile);
if (mainline)
{
/* We will modify the main symbol table, make sure that all its users
will be cleaned up if an error occurs during symbol reading. */
- make_cleanup (clear_symtab_users, 0);
+ make_cleanup ((make_cleanup_func) clear_symtab_users, 0);
/* Since no error yet, throw away the old symbol table. */
@@ -572,17 +669,25 @@ new_symfile_objfile (objfile, mainline, verbo)
as dynamically loaded code. If !mainline, ADDR is the address
where the text segment was loaded.
+ USER_LOADED is TRUE if the add-symbol-file command was how this
+ symbol file came to be processed.
+
+ IS_SOLIB is TRUE if this symbol file represents a solib, as discovered
+ by the target's implementation of the solib package.
+
Upon success, returns a pointer to the objfile that was added.
Upon failure, jumps back to command level (never returns). */
struct objfile *
-symbol_file_add (name, from_tty, addr, mainline, mapped, readnow)
+symbol_file_add (name, from_tty, addr, mainline, mapped, readnow, user_loaded, is_solib)
char *name;
int from_tty;
CORE_ADDR addr;
int mainline;
int mapped;
int readnow;
+ int user_loaded;
+ int is_solib;
{
struct objfile *objfile;
struct partial_symtab *psymtab;
@@ -599,7 +704,7 @@ symbol_file_add (name, from_tty, addr, mainline, mapped, readnow)
&& !query ("Load new symbol table from \"%s\"? ", name))
error ("Not confirmed.");
- objfile = allocate_objfile (abfd, mapped);
+ objfile = allocate_objfile (abfd, mapped, user_loaded, is_solib);
/* If the objfile uses a mapped symbol file, and we have a psymtab for
it, then skip reading any symbols at this time. */
@@ -626,12 +731,17 @@ symbol_file_add (name, from_tty, addr, mainline, mapped, readnow)
performed, or need to read an unmapped symbol table. */
if (from_tty || info_verbose)
{
- printf_filtered ("Reading symbols from %s...", name);
- wrap_here ("");
- gdb_flush (gdb_stdout);
+ if (pre_add_symbol_hook)
+ pre_add_symbol_hook (name);
+ else
+ {
+ printf_filtered ("Reading symbols from %s...", name);
+ wrap_here ("");
+ gdb_flush (gdb_stdout);
+ }
}
syms_from_objfile (objfile, addr, mainline, from_tty);
- }
+ }
/* We now have at least a partial symbol table. Check to see if the
user requested that all symbols be read on initial access via either
@@ -657,12 +767,19 @@ symbol_file_add (name, from_tty, addr, mainline, mapped, readnow)
if (from_tty || info_verbose)
{
- printf_filtered ("done.\n");
- gdb_flush (gdb_stdout);
+ if (post_add_symbol_hook)
+ post_add_symbol_hook ();
+ else
+ {
+ printf_filtered ("done.\n");
+ gdb_flush (gdb_stdout);
+ }
}
new_symfile_objfile (objfile, mainline, from_tty);
+ target_new_objfile (objfile);
+
return (objfile);
}
@@ -698,11 +815,23 @@ symbol_file_command (args, from_tty)
symfile_objfile -> name))
error ("Not confirmed.");
free_all_objfiles ();
+
+ /* solib descriptors may have handles to objfiles. Since their
+ storage has just been released, we'd better wipe the solib
+ descriptors as well.
+ */
+#if defined(SOLIB_RESTART)
+ SOLIB_RESTART ();
+#endif
+
symfile_objfile = NULL;
if (from_tty)
{
printf_unfiltered ("No symbol file now.\n");
}
+#ifdef HPUXHPPA
+ RESET_HP_UX_GLOBALS ();
+#endif
}
else
{
@@ -710,7 +839,7 @@ symbol_file_command (args, from_tty)
{
nomem (0);
}
- cleanups = make_cleanup (freeargv, (char *) argv);
+ cleanups = make_cleanup ((make_cleanup_func) freeargv, (char *) argv);
while (*argv != NULL)
{
if (STREQ (*argv, "-mapped"))
@@ -742,11 +871,16 @@ symbol_file_command (args, from_tty)
if (text_relocation == (CORE_ADDR)0)
return;
else if (text_relocation == (CORE_ADDR)-1)
- symbol_file_add (name, from_tty, (CORE_ADDR)0, 1, mapped,
- readnow);
+ {
+ symbol_file_add (name, from_tty, (CORE_ADDR)0,
+ 1, mapped, readnow, 1, 0);
+#ifdef HPUXHPPA
+ RESET_HP_UX_GLOBALS ();
+#endif
+ }
else
symbol_file_add (name, from_tty, (CORE_ADDR)text_relocation,
- 0, mapped, readnow);
+ 0, mapped, readnow, 1, 0);
/* Getting new symbols may change our opinion about what is
frameless. */
@@ -761,6 +895,7 @@ symbol_file_command (args, from_tty)
{
error ("no symbol file name was specified");
}
+ TUIDO(((TuiOpaqueFuncPtr)tuiDisplayMainFunction));
do_cleanups (cleanups);
}
}
@@ -803,7 +938,7 @@ set_initial_language ()
malloc'd` copy of NAME (tilde-expanded and made absolute).
In case of trouble, error() is called. */
-static bfd *
+bfd *
symfile_bfd_open (name)
char *name;
{
@@ -811,10 +946,21 @@ symfile_bfd_open (name)
int desc;
char *absolute_name;
+
+
name = tilde_expand (name); /* Returns 1st new malloc'd copy */
/* Look down path for it, allocate 2nd new malloc'd copy. */
desc = openp (getenv ("PATH"), 1, name, O_RDONLY | O_BINARY, 0, &absolute_name);
+#if defined(__GO32__) || defined(_WIN32)
+ if (desc < 0)
+ {
+ char *exename = alloca (strlen (name) + 5);
+ strcat (strcpy (exename, name), ".exe");
+ desc = openp (getenv ("PATH"), 1, exename, O_RDONLY | O_BINARY,
+ 0, &absolute_name);
+ }
+#endif
if (desc < 0)
{
make_cleanup (free, name);
@@ -845,7 +991,6 @@ symfile_bfd_open (name)
error ("\"%s\": can't read symbols: %s.", name,
bfd_errmsg (bfd_get_error ()));
}
-
return (sym_bfd);
}
@@ -917,6 +1062,8 @@ load_command (arg, from_tty)
to worry about finding it, and (b) On VMS, fork() is very slow and so
we don't want to run a subprocess. On the other hand, I'm not sure how
performance compares. */
+#define GENERIC_LOAD_CHUNK 256
+#define VALIDATE_DOWNLOAD 0
void
generic_load (filename, from_tty)
char *filename;
@@ -926,7 +1073,20 @@ generic_load (filename, from_tty)
asection *s;
bfd *loadfile_bfd;
time_t start_time, end_time; /* Start and end times of download */
- unsigned long data_count; /* Number of bytes transferred to memory */
+ unsigned long data_count = 0; /* Number of bytes transferred to memory */
+ int n;
+ unsigned long load_offset = 0; /* offset to add to vma for each section */
+ char buf[GENERIC_LOAD_CHUNK+8];
+#if VALIDATE_DOWNLOAD
+ char verify_buffer[GENERIC_LOAD_CHUNK+8] ;
+#endif
+
+ /* enable user to specify address for downloading as 2nd arg to load */
+ n = sscanf(filename, "%s 0x%lx", buf, &load_offset);
+ if (n > 1 )
+ filename = buf;
+ else
+ load_offset = 0;
loadfile_bfd = bfd_openr (filename, gnutarget);
if (loadfile_bfd == NULL)
@@ -937,7 +1097,7 @@ generic_load (filename, from_tty)
/* FIXME: should be checking for errors from bfd_close (for one thing,
on error it does not free all the storage associated with the
bfd). */
- old_cleanups = make_cleanup (bfd_close, loadfile_bfd);
+ old_cleanups = make_cleanup ((make_cleanup_func) bfd_close, loadfile_bfd);
if (!bfd_check_format (loadfile_bfd, bfd_object))
{
@@ -950,45 +1110,87 @@ generic_load (filename, from_tty)
for (s = loadfile_bfd->sections; s; s = s->next)
{
if (s->flags & SEC_LOAD)
- {
- bfd_size_type size;
-
- size = bfd_get_section_size_before_reloc (s);
- if (size > 0)
- {
- char *buffer;
- struct cleanup *old_chain;
- bfd_vma vma;
-
- data_count += size;
-
- buffer = xmalloc (size);
- old_chain = make_cleanup (free, buffer);
-
- vma = bfd_get_section_vma (loadfile_bfd, s);
+ {
+ bfd_size_type size;
+
+ size = bfd_get_section_size_before_reloc (s);
+ if (size > 0)
+ {
+ char *buffer;
+ struct cleanup *old_chain;
+ bfd_vma lma;
+ unsigned long l = size ;
+ int err;
+ char *sect;
+ unsigned long sent;
+ unsigned long len;
+
+ l = l > GENERIC_LOAD_CHUNK ? GENERIC_LOAD_CHUNK : l ;
+
+ buffer = xmalloc (size);
+ old_chain = make_cleanup (free, buffer);
+
+ lma = s->lma;
+ lma += load_offset;
+
+ /* Is this really necessary? I guess it gives the user something
+ to look at during a long download. */
+ printf_filtered ("Loading section %s, size 0x%lx lma ",
+ bfd_get_section_name (loadfile_bfd, s),
+ (unsigned long) size);
+ print_address_numeric (lma, 1, gdb_stdout);
+ printf_filtered ("\n");
+
+ bfd_get_section_contents (loadfile_bfd, s, buffer, 0, size);
+
+ sect = (char *) bfd_get_section_name (loadfile_bfd, s);
+ sent = 0;
+ do
+ {
+ len = (size - sent) < l ? (size - sent) : l;
+ sent += len;
+ err = target_write_memory (lma, buffer, len);
+ if (ui_load_progress_hook)
+ if (ui_load_progress_hook (sect, sent))
+ error ("Canceled the download");
+#if VALIDATE_DOWNLOAD
+ /* Broken memories and broken monitors manifest themselves
+ here when bring new computers to life.
+ This doubles already slow downloads.
+ */
+ if (err) break ;
+ {
+ target_read_memory(lma,verify_buffer,len) ;
+ if (0 != bcmp(buffer,verify_buffer,len))
+ error("Download verify failed at %08x",
+ (unsigned long)lma) ;
+ }
- /* Is this really necessary? I guess it gives the user something
- to look at during a long download. */
- printf_filtered ("Loading section %s, size 0x%lx vma ",
- bfd_get_section_name (loadfile_bfd, s),
- (unsigned long) size);
- print_address_numeric (vma, 1, gdb_stdout);
- printf_filtered ("\n");
-
- bfd_get_section_contents (loadfile_bfd, s, buffer, 0, size);
-
- target_write_memory (vma, buffer, size);
-
- do_cleanups (old_chain);
- }
- }
+#endif
+ data_count += len ;
+ lma += len;
+ buffer += len;
+ } /* od */
+ while (err == 0 && sent < size);
+
+ if (err != 0)
+ error ("Memory access error while loading section %s.",
+ bfd_get_section_name (loadfile_bfd, s));
+
+ do_cleanups (old_chain);
+ }
+ }
}
end_time = time (NULL);
-
- /* We were doing this in remote-mips.c, I suspect it is right
- for other targets too. */
- write_pc (loadfile_bfd->start_address);
+ {
+ unsigned long entry ;
+ entry = bfd_get_start_address(loadfile_bfd) ;
+ printf_filtered ("Start address 0x%lx , load size %d\n", entry,data_count);
+ /* We were doing this in remote-mips.c, I suspect it is right
+ for other targets too. */
+ write_pc (entry);
+ }
/* FIXME: are we supposed to call symbol_file_add or not? According to
a comment from remote-mips.c (where a call to symbol_file_add was
@@ -996,13 +1198,27 @@ generic_load (filename, from_tty)
loaded in. remote-nindy.c had no call to symbol_file_add, but remote-vx.c
does. */
- if (end_time != start_time)
- printf_filtered ("Transfer rate: %d bits/sec.\n",
- (data_count * 8)/(end_time - start_time));
+ report_transfer_performance (data_count, start_time, end_time);
do_cleanups (old_cleanups);
}
+/* Report how fast the transfer went. */
+
+void
+report_transfer_performance (data_count, start_time, end_time)
+unsigned long data_count;
+time_t start_time, end_time;
+{
+ printf_filtered ("Transfer rate: ");
+ if (end_time != start_time)
+ printf_filtered ("%d bits/sec",
+ (data_count * 8) / (end_time - start_time));
+ else
+ printf_filtered ("%d bits in <1 sec", (data_count * 8));
+ printf_filtered (".\n");
+}
+
/* This function allows the addition of incrementally linked object files.
It does not modify any state in the target, only in the debugger. */
@@ -1082,11 +1298,14 @@ add_symbol_file_command (args, from_tty)
}
/* FIXME-32x64: Assumes text_addr fits in a long. */
- if (!query ("add symbol table from file \"%s\" at text_addr = %s?\n",
- name, local_hex_string ((unsigned long)text_addr)))
+ if ((from_tty)
+ && (!query ("add symbol table from file \"%s\" at text_addr = %s?\n",
+ name, local_hex_string ((unsigned long)text_addr))))
error ("Not confirmed.");
- symbol_file_add (name, 0, text_addr, 0, mapped, readnow);
+ symbol_file_add (name, from_tty, text_addr, 0, mapped, readnow,
+ 1, /* user_loaded */
+ 0); /* We'll guess it's ! is_solib */
/* Getting new symbols may change our opinion about what is
frameless. */
@@ -1160,9 +1379,10 @@ reread_symbols ()
/* If we get an error, blow away this objfile (not sure if
that is the correct response for things like shared
libraries). */
- old_cleanups = make_cleanup (free_objfile, objfile);
+ old_cleanups = make_cleanup ((make_cleanup_func) free_objfile,
+ objfile);
/* We need to do this whenever any symbols go away. */
- make_cleanup (clear_symtab_users, 0);
+ make_cleanup ((make_cleanup_func) clear_symtab_users, 0);
/* Clean up any state BFD has sitting around. We don't need
to close the descriptor but BFD lacks a way of closing the
@@ -1251,7 +1471,12 @@ reread_symbols ()
distinguishing between the main file and additional files
in this way seems rather dubious. */
if (objfile == symfile_objfile)
- (*objfile->sf->sym_new_init) (objfile);
+ {
+ (*objfile->sf->sym_new_init) (objfile);
+#ifdef HPUXHPPA
+ RESET_HP_UX_GLOBALS ();
+#endif
+ }
(*objfile->sf->sym_init) (objfile);
clear_complaints (1, 1);
@@ -1299,31 +1524,150 @@ reread_symbols ()
}
+
+typedef struct {
+ char *ext;
+ enum language lang;
+} filename_language;
+
+static filename_language * filename_language_table;
+static int fl_table_size, fl_table_next;
+
+static void
+add_filename_language (ext, lang)
+ char *ext;
+ enum language lang;
+{
+ if (fl_table_next >= fl_table_size)
+ {
+ fl_table_size += 10;
+ filename_language_table = realloc (filename_language_table,
+ fl_table_size);
+ }
+
+ filename_language_table[fl_table_next].ext = strsave (ext);
+ filename_language_table[fl_table_next].lang = lang;
+ fl_table_next++;
+}
+
+static char *ext_args;
+
+static void
+set_ext_lang_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ int i;
+ char *cp = ext_args;
+ enum language lang;
+
+ /* First arg is filename extension, starting with '.' */
+ if (*cp != '.')
+ error ("'%s': Filename extension must begin with '.'", ext_args);
+
+ /* Find end of first arg. */
+ while (*cp && !isspace (*cp))
+ cp++;
+
+ if (*cp == '\0')
+ error ("'%s': two arguments required -- filename extension and language",
+ ext_args);
+
+ /* Null-terminate first arg */
+ *cp++ = '\0';
+
+ /* Find beginning of second arg, which should be a source language. */
+ while (*cp && isspace (*cp))
+ cp++;
+
+ if (*cp == '\0')
+ error ("'%s': two arguments required -- filename extension and language",
+ ext_args);
+
+ /* Lookup the language from among those we know. */
+ lang = language_enum (cp);
+
+ /* Now lookup the filename extension: do we already know it? */
+ for (i = 0; i < fl_table_next; i++)
+ if (0 == strcmp (ext_args, filename_language_table[i].ext))
+ break;
+
+ if (i >= fl_table_next)
+ {
+ /* new file extension */
+ add_filename_language (ext_args, lang);
+ }
+ else
+ {
+ /* redefining a previously known filename extension */
+
+ /* if (from_tty) */
+ /* query ("Really make files of type %s '%s'?", */
+ /* ext_args, language_str (lang)); */
+
+ free (filename_language_table[i].ext);
+ filename_language_table[i].ext = strsave (ext_args);
+ filename_language_table[i].lang = lang;
+ }
+}
+
+static void
+info_ext_lang_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ int i;
+
+ printf_filtered ("Filename extensions and the languages they represent:");
+ printf_filtered ("\n\n");
+ for (i = 0; i < fl_table_next; i++)
+ printf_filtered ("\t%s\t- %s\n",
+ filename_language_table[i].ext,
+ language_str (filename_language_table[i].lang));
+}
+
+static void
+init_filename_language_table ()
+{
+ if (fl_table_size == 0) /* protect against repetition */
+ {
+ fl_table_size = 20;
+ fl_table_next = 0;
+ filename_language_table =
+ xmalloc (fl_table_size * sizeof (*filename_language_table));
+ add_filename_language (".c", language_c);
+ add_filename_language (".C", language_cplus);
+ add_filename_language (".cc", language_cplus);
+ add_filename_language (".cp", language_cplus);
+ add_filename_language (".cpp", language_cplus);
+ add_filename_language (".cxx", language_cplus);
+ add_filename_language (".c++", language_cplus);
+ add_filename_language (".java", language_java);
+ add_filename_language (".class", language_java);
+ add_filename_language (".ch", language_chill);
+ add_filename_language (".c186", language_chill);
+ add_filename_language (".c286", language_chill);
+ add_filename_language (".f", language_fortran);
+ add_filename_language (".F", language_fortran);
+ add_filename_language (".s", language_asm);
+ add_filename_language (".S", language_asm);
+ }
+}
+
enum language
deduce_language_from_filename (filename)
char *filename;
{
- char *c;
-
- if (0 == filename)
- ; /* Get default */
- else if (0 == (c = strrchr (filename, '.')))
- ; /* Get default. */
- else if (STREQ (c, ".c"))
- return language_c;
- else if (STREQ (c, ".cc") || STREQ (c, ".C") || STREQ (c, ".cxx")
- || STREQ (c, ".cpp") || STREQ (c, ".cp") || STREQ (c, ".c++"))
- return language_cplus;
- else if (STREQ (c, ".ch") || STREQ (c, ".c186") || STREQ (c, ".c286"))
- return language_chill;
- else if (STREQ (c, ".f") || STREQ (c, ".F"))
- return language_fortran;
- else if (STREQ (c, ".mod"))
- return language_m2;
- else if (STREQ (c, ".s") || STREQ (c, ".S"))
- return language_asm;
-
- return language_unknown; /* default */
+ int i;
+ char *cp;
+
+ if (filename != NULL)
+ if ((cp = strrchr (filename, '.')) != NULL)
+ for (i = 0; i < fl_table_next; i++)
+ if (strcmp (cp, filename_language_table[i].ext) == 0)
+ return filename_language_table[i].lang;
+
+ return language_unknown;
}
/* allocate_symtab:
@@ -1337,7 +1681,6 @@ deduce_language_from_filename (filename)
symtab->dirname
symtab->free_code
symtab->free_ptr
- initialize any EXTRA_SYMTAB_INFO
possibly free_named_symtabs (symtab->filename);
*/
@@ -1355,6 +1698,8 @@ allocate_symtab (filename, objfile)
&objfile -> symbol_obstack);
symtab -> fullname = NULL;
symtab -> language = deduce_language_from_filename (filename);
+ symtab -> debugformat = obsavestring ("unknown", 7,
+ &objfile -> symbol_obstack);
/* Hook it to the objfile it comes from */
@@ -1362,6 +1707,10 @@ allocate_symtab (filename, objfile)
symtab -> next = objfile -> symtabs;
objfile -> symtabs = symtab;
+ /* FIXME: This should go away. It is only defined for the Z8000,
+ and the Z8000 definition of this macro doesn't have anything to
+ do with the now-nonexistent EXTRA_SYMTAB_INFO macro, it's just
+ here for convenience. */
#ifdef INIT_EXTRA_SYMTAB_INFO
INIT_EXTRA_SYMTAB_INFO (symtab);
#endif
@@ -1391,18 +1740,57 @@ allocate_psymtab (filename, objfile)
&objfile -> psymbol_obstack);
psymtab -> symtab = NULL;
- /* Hook it to the objfile it comes from */
+ /* Prepend it to the psymtab list for the objfile it belongs to.
+ Psymtabs are searched in most recent inserted -> least recent
+ inserted order. */
psymtab -> objfile = objfile;
psymtab -> next = objfile -> psymtabs;
objfile -> psymtabs = psymtab;
+#if 0
+ {
+ struct partial_symtab **prev_pst;
+ psymtab -> objfile = objfile;
+ psymtab -> next = NULL;
+ prev_pst = &(objfile -> psymtabs);
+ while ((*prev_pst) != NULL)
+ prev_pst = &((*prev_pst) -> next);
+ (*prev_pst) = psymtab;
+ }
+#endif
return (psymtab);
}
+void
+discard_psymtab (pst)
+ struct partial_symtab *pst;
+{
+ struct partial_symtab **prev_pst;
+
+ /* From dbxread.c:
+ Empty psymtabs happen as a result of header files which don't
+ have any symbols in them. There can be a lot of them. But this
+ check is wrong, in that a psymtab with N_SLINE entries but
+ nothing else is not empty, but we don't realize that. Fixing
+ that without slowing things down might be tricky. */
+
+ /* First, snip it out of the psymtab chain */
+
+ prev_pst = &(pst->objfile->psymtabs);
+ while ((*prev_pst) != pst)
+ prev_pst = &((*prev_pst)->next);
+ (*prev_pst) = pst->next;
+
+ /* Next, put it on a free list for recycling */
+
+ pst->next = pst->objfile->free_psymtabs;
+ pst->objfile->free_psymtabs = pst;
+}
+
/* Reset all data structures in gdb which may contain references to symbol
- table date. */
+ table data. */
void
clear_symtab_users ()
@@ -1417,6 +1805,7 @@ clear_symtab_users ()
current_source_symtab = 0;
current_source_line = 0;
clear_pc_function_cache ();
+ target_new_objfile (NULL);
}
/* clear_symtab_users_once:
@@ -1701,6 +2090,83 @@ add_psymbol_to_list (name, namelength, namespace, class, list, val, coreaddr,
OBJSTAT (objfile, n_psyms++);
}
+/* Add a symbol with a long value to a psymtab. This differs from
+ * add_psymbol_to_list above in taking both a mangled and a demangled
+ * name. */
+
+void
+add_psymbol_with_dem_name_to_list (name, namelength, dem_name, dem_namelength,
+ namespace, class, list, val, coreaddr, language, objfile)
+ char *name;
+ int namelength;
+ char *dem_name;
+ int dem_namelength;
+ namespace_enum namespace;
+ enum address_class class;
+ struct psymbol_allocation_list *list;
+ long val; /* Value as a long */
+ CORE_ADDR coreaddr; /* Value as a CORE_ADDR */
+ enum language language;
+ struct objfile *objfile;
+{
+ register struct partial_symbol *psym;
+ char *buf = alloca (namelength + 1);
+ /* psymbol is static so that there will be no uninitialized gaps in the
+ structure which might contain random data, causing cache misses in
+ bcache. */
+ static struct partial_symbol psymbol;
+
+ /* Create local copy of the partial symbol */
+
+ memcpy (buf, name, namelength);
+ buf[namelength] = '\0';
+ SYMBOL_NAME (&psymbol) = bcache (buf, namelength + 1, &objfile->psymbol_cache);
+
+ buf = alloca (dem_namelength + 1);
+ memcpy (buf, dem_name, dem_namelength);
+ buf[dem_namelength] = '\0';
+
+ switch (language)
+ {
+ case language_c:
+ case language_cplus:
+ SYMBOL_CPLUS_DEMANGLED_NAME (&psymbol) =
+ bcache (buf, dem_namelength + 1, &objfile->psymbol_cache);
+ break;
+ case language_chill:
+ SYMBOL_CHILL_DEMANGLED_NAME (&psymbol) =
+ bcache (buf, dem_namelength + 1, &objfile->psymbol_cache);
+
+ /* FIXME What should be done for the default case? Ignoring for now. */
+ }
+
+ /* val and coreaddr are mutually exclusive, one of them *will* be zero */
+ if (val != 0)
+ {
+ SYMBOL_VALUE (&psymbol) = val;
+ }
+ else
+ {
+ SYMBOL_VALUE_ADDRESS (&psymbol) = coreaddr;
+ }
+ SYMBOL_SECTION (&psymbol) = 0;
+ SYMBOL_LANGUAGE (&psymbol) = language;
+ PSYMBOL_NAMESPACE (&psymbol) = namespace;
+ PSYMBOL_CLASS (&psymbol) = class;
+ SYMBOL_INIT_LANGUAGE_SPECIFIC (&psymbol, language);
+
+ /* Stash the partial symbol away in the cache */
+ psym = bcache (&psymbol, sizeof (struct partial_symbol), &objfile->psymbol_cache);
+
+ /* Save pointer to partial symbol in psymtab, growing symtab if needed. */
+ if (list->next >= list->list + list->size)
+ {
+ extend_psymbol_list (list, objfile);
+ }
+ *list->next++ = psym;
+ OBJSTAT (objfile, n_psyms++);
+}
+
/* Initialize storage for partial symbols. */
void
@@ -1725,16 +2191,761 @@ init_psymbol_list (objfile, total_symbols)
objfile -> global_psymbols.size = total_symbols / 10;
objfile -> static_psymbols.size = total_symbols / 10;
- objfile -> global_psymbols.next =
- objfile -> global_psymbols.list = (struct partial_symbol **)
- xmmalloc (objfile -> md, objfile -> global_psymbols.size
- * sizeof (struct partial_symbol *));
- objfile -> static_psymbols.next =
- objfile -> static_psymbols.list = (struct partial_symbol **)
- xmmalloc (objfile -> md, objfile -> static_psymbols.size
- * sizeof (struct partial_symbol *));
+
+ if (objfile -> global_psymbols.size > 0)
+ {
+ objfile -> global_psymbols.next =
+ objfile -> global_psymbols.list = (struct partial_symbol **)
+ xmmalloc (objfile -> md, (objfile -> global_psymbols.size
+ * sizeof (struct partial_symbol *)));
+ }
+ if (objfile -> static_psymbols.size > 0)
+ {
+ objfile -> static_psymbols.next =
+ objfile -> static_psymbols.list = (struct partial_symbol **)
+ xmmalloc (objfile -> md, (objfile -> static_psymbols.size
+ * sizeof (struct partial_symbol *)));
+ }
}
-
+
+/* OVERLAYS:
+ The following code implements an abstraction for debugging overlay sections.
+
+ The target model is as follows:
+ 1) The gnu linker will permit multiple sections to be mapped into the
+ same VMA, each with its own unique LMA (or load address).
+ 2) It is assumed that some runtime mechanism exists for mapping the
+ sections, one by one, from the load address into the VMA address.
+ 3) This code provides a mechanism for gdb to keep track of which
+ sections should be considered to be mapped from the VMA to the LMA.
+ This information is used for symbol lookup, and memory read/write.
+ For instance, if a section has been mapped then its contents
+ should be read from the VMA, otherwise from the LMA.
+
+ Two levels of debugger support for overlays are available. One is
+ "manual", in which the debugger relies on the user to tell it which
+ overlays are currently mapped. This level of support is
+ implemented entirely in the core debugger, and the information about
+ whether a section is mapped is kept in the objfile->obj_section table.
+
+ The second level of support is "automatic", and is only available if
+ the target-specific code provides functionality to read the target's
+ overlay mapping table, and translate its contents for the debugger
+ (by updating the mapped state information in the obj_section tables).
+
+ The interface is as follows:
+ User commands:
+ overlay map <name> -- tell gdb to consider this section mapped
+ overlay unmap <name> -- tell gdb to consider this section unmapped
+ overlay list -- list the sections that GDB thinks are mapped
+ overlay read-target -- get the target's state of what's mapped
+ overlay off/manual/auto -- set overlay debugging state
+ Functional interface:
+ find_pc_mapped_section(pc): if the pc is in the range of a mapped
+ section, return that section.
+ find_pc_overlay(pc): find any overlay section that contains
+ the pc, either in its VMA or its LMA
+ overlay_is_mapped(sect): true if overlay is marked as mapped
+ section_is_overlay(sect): true if section's VMA != LMA
+ pc_in_mapped_range(pc,sec): true if pc belongs to section's VMA
+ pc_in_unmapped_range(...): true if pc belongs to section's LMA
+ overlay_mapped_address(...): map an address from section's LMA to VMA
+ overlay_unmapped_address(...): map an address from section's VMA to LMA
+ symbol_overlayed_address(...): Return a "current" address for symbol:
+ either in VMA or LMA depending on whether
+ the symbol's section is currently mapped
+ */
+
+/* Overlay debugging state: */
+
+int overlay_debugging = 0; /* 0 == off, 1 == manual, -1 == auto */
+int overlay_cache_invalid = 0; /* True if need to refresh mapped state */
+
+/* Target vector for refreshing overlay mapped state */
+static void simple_overlay_update PARAMS ((struct obj_section *));
+void (*target_overlay_update) PARAMS ((struct obj_section *))
+ = simple_overlay_update;
+
+/* Function: section_is_overlay (SECTION)
+ Returns true if SECTION has VMA not equal to LMA, ie.
+ SECTION is loaded at an address different from where it will "run". */
+
+int
+section_is_overlay (section)
+ asection *section;
+{
+ if (overlay_debugging)
+ if (section && section->lma != 0 &&
+ section->vma != section->lma)
+ return 1;
+
+ return 0;
+}
+
+/* Function: overlay_invalidate_all (void)
+ Invalidate the mapped state of all overlay sections (mark it as stale). */
+
+static void
+overlay_invalidate_all ()
+{
+ struct objfile *objfile;
+ struct obj_section *sect;
+
+ ALL_OBJSECTIONS (objfile, sect)
+ if (section_is_overlay (sect->the_bfd_section))
+ sect->ovly_mapped = -1;
+}
+
+/* Function: overlay_is_mapped (SECTION)
+ Returns true if section is an overlay, and is currently mapped.
+ Private: public access is thru function section_is_mapped.
+
+ Access to the ovly_mapped flag is restricted to this function, so
+ that we can do automatic update. If the global flag
+ OVERLAY_CACHE_INVALID is set (by wait_for_inferior), then call
+ overlay_invalidate_all. If the mapped state of the particular
+ section is stale, then call TARGET_OVERLAY_UPDATE to refresh it. */
+
+static int
+overlay_is_mapped (osect)
+ struct obj_section *osect;
+{
+ if (osect == 0 || !section_is_overlay (osect->the_bfd_section))
+ return 0;
+
+ switch (overlay_debugging)
+ {
+ default:
+ case 0: return 0; /* overlay debugging off */
+ case -1: /* overlay debugging automatic */
+ /* Unles there is a target_overlay_update function,
+ there's really nothing useful to do here (can't really go auto) */
+ if (target_overlay_update)
+ {
+ if (overlay_cache_invalid)
+ {
+ overlay_invalidate_all ();
+ overlay_cache_invalid = 0;
+ }
+ if (osect->ovly_mapped == -1)
+ (*target_overlay_update) (osect);
+ }
+ /* fall thru to manual case */
+ case 1: /* overlay debugging manual */
+ return osect->ovly_mapped == 1;
+ }
+}
+
+/* Function: section_is_mapped
+ Returns true if section is an overlay, and is currently mapped. */
+
+int
+section_is_mapped (section)
+ asection *section;
+{
+ struct objfile *objfile;
+ struct obj_section *osect;
+
+ if (overlay_debugging)
+ if (section && section_is_overlay (section))
+ ALL_OBJSECTIONS (objfile, osect)
+ if (osect->the_bfd_section == section)
+ return overlay_is_mapped (osect);
+
+ return 0;
+}
+
+/* Function: pc_in_unmapped_range
+ If PC falls into the lma range of SECTION, return true, else false. */
+
+CORE_ADDR
+pc_in_unmapped_range (pc, section)
+ CORE_ADDR pc;
+ asection *section;
+{
+ int size;
+
+ if (overlay_debugging)
+ if (section && section_is_overlay (section))
+ {
+ size = bfd_get_section_size_before_reloc (section);
+ if (section->lma <= pc && pc < section->lma + size)
+ return 1;
+ }
+ return 0;
+}
+
+/* Function: pc_in_mapped_range
+ If PC falls into the vma range of SECTION, return true, else false. */
+
+CORE_ADDR
+pc_in_mapped_range (pc, section)
+ CORE_ADDR pc;
+ asection *section;
+{
+ int size;
+
+ if (overlay_debugging)
+ if (section && section_is_overlay (section))
+ {
+ size = bfd_get_section_size_before_reloc (section);
+ if (section->vma <= pc && pc < section->vma + size)
+ return 1;
+ }
+ return 0;
+}
+
+/* Function: overlay_unmapped_address (PC, SECTION)
+ Returns the address corresponding to PC in the unmapped (load) range.
+ May be the same as PC. */
+
+CORE_ADDR
+overlay_unmapped_address (pc, section)
+ CORE_ADDR pc;
+ asection *section;
+{
+ if (overlay_debugging)
+ if (section && section_is_overlay (section) &&
+ pc_in_mapped_range (pc, section))
+ return pc + section->lma - section->vma;
+
+ return pc;
+}
+
+/* Function: overlay_mapped_address (PC, SECTION)
+ Returns the address corresponding to PC in the mapped (runtime) range.
+ May be the same as PC. */
+
+CORE_ADDR
+overlay_mapped_address (pc, section)
+ CORE_ADDR pc;
+ asection *section;
+{
+ if (overlay_debugging)
+ if (section && section_is_overlay (section) &&
+ pc_in_unmapped_range (pc, section))
+ return pc + section->vma - section->lma;
+
+ return pc;
+}
+
+
+/* Function: symbol_overlayed_address
+ Return one of two addresses (relative to the VMA or to the LMA),
+ depending on whether the section is mapped or not. */
+
+CORE_ADDR
+symbol_overlayed_address (address, section)
+ CORE_ADDR address;
+ asection *section;
+{
+ if (overlay_debugging)
+ {
+ /* If the symbol has no section, just return its regular address. */
+ if (section == 0)
+ return address;
+ /* If the symbol's section is not an overlay, just return its address */
+ if (!section_is_overlay (section))
+ return address;
+ /* If the symbol's section is mapped, just return its address */
+ if (section_is_mapped (section))
+ return address;
+ /*
+ * HOWEVER: if the symbol is in an overlay section which is NOT mapped,
+ * then return its LOADED address rather than its vma address!!
+ */
+ return overlay_unmapped_address (address, section);
+ }
+ return address;
+}
+
+/* Function: find_pc_overlay (PC)
+ Return the best-match overlay section for PC:
+ If PC matches a mapped overlay section's VMA, return that section.
+ Else if PC matches an unmapped section's VMA, return that section.
+ Else if PC matches an unmapped section's LMA, return that section. */
+
+asection *
+find_pc_overlay (pc)
+ CORE_ADDR pc;
+{
+ struct objfile *objfile;
+ struct obj_section *osect, *best_match = NULL;
+
+ if (overlay_debugging)
+ ALL_OBJSECTIONS (objfile, osect)
+ if (section_is_overlay (osect->the_bfd_section))
+ {
+ if (pc_in_mapped_range (pc, osect->the_bfd_section))
+ {
+ if (overlay_is_mapped (osect))
+ return osect->the_bfd_section;
+ else
+ best_match = osect;
+ }
+ else if (pc_in_unmapped_range (pc, osect->the_bfd_section))
+ best_match = osect;
+ }
+ return best_match ? best_match->the_bfd_section : NULL;
+}
+
+/* Function: find_pc_mapped_section (PC)
+ If PC falls into the VMA address range of an overlay section that is
+ currently marked as MAPPED, return that section. Else return NULL. */
+
+asection *
+find_pc_mapped_section (pc)
+ CORE_ADDR pc;
+{
+ struct objfile *objfile;
+ struct obj_section *osect;
+
+ if (overlay_debugging)
+ ALL_OBJSECTIONS (objfile, osect)
+ if (pc_in_mapped_range (pc, osect->the_bfd_section) &&
+ overlay_is_mapped (osect))
+ return osect->the_bfd_section;
+
+ return NULL;
+}
+
+/* Function: list_overlays_command
+ Print a list of mapped sections and their PC ranges */
+
+void
+list_overlays_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ int nmapped = 0;
+ struct objfile *objfile;
+ struct obj_section *osect;
+
+ if (overlay_debugging)
+ ALL_OBJSECTIONS (objfile, osect)
+ if (overlay_is_mapped (osect))
+ {
+ const char *name;
+ bfd_vma lma, vma;
+ int size;
+
+ vma = bfd_section_vma (objfile->obfd, osect->the_bfd_section);
+ lma = bfd_section_lma (objfile->obfd, osect->the_bfd_section);
+ size = bfd_get_section_size_before_reloc (osect->the_bfd_section);
+ name = bfd_section_name (objfile->obfd, osect->the_bfd_section);
+
+ printf_filtered ("Section %s, loaded at ", name);
+ print_address_numeric (lma, 1, gdb_stdout);
+ puts_filtered (" - ");
+ print_address_numeric (lma + size, 1, gdb_stdout);
+ printf_filtered (", mapped at ");
+ print_address_numeric (vma, 1, gdb_stdout);
+ puts_filtered (" - ");
+ print_address_numeric (vma + size, 1, gdb_stdout);
+ puts_filtered ("\n");
+
+ nmapped ++;
+ }
+ if (nmapped == 0)
+ printf_filtered ("No sections are mapped.\n");
+}
+
+/* Function: map_overlay_command
+ Mark the named section as mapped (ie. residing at its VMA address). */
+
+void
+map_overlay_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ struct objfile *objfile, *objfile2;
+ struct obj_section *sec, *sec2;
+ asection *bfdsec;
+
+ if (!overlay_debugging)
+ error ("Overlay debugging not enabled. Use the 'OVERLAY ON' command.");
+
+ if (args == 0 || *args == 0)
+ error ("Argument required: name of an overlay section");
+
+ /* First, find a section matching the user supplied argument */
+ ALL_OBJSECTIONS (objfile, sec)
+ if (!strcmp (bfd_section_name (objfile->obfd, sec->the_bfd_section), args))
+ {
+ /* Now, check to see if the section is an overlay. */
+ bfdsec = sec->the_bfd_section;
+ if (!section_is_overlay (bfdsec))
+ continue; /* not an overlay section */
+
+ /* Mark the overlay as "mapped" */
+ sec->ovly_mapped = 1;
+
+ /* Next, make a pass and unmap any sections that are
+ overlapped by this new section: */
+ ALL_OBJSECTIONS (objfile2, sec2)
+ if (sec2->ovly_mapped &&
+ sec != sec2 &&
+ sec->the_bfd_section != sec2->the_bfd_section &&
+ (pc_in_mapped_range (sec2->addr, sec->the_bfd_section) ||
+ pc_in_mapped_range (sec2->endaddr, sec->the_bfd_section)))
+ {
+ if (info_verbose)
+ printf_filtered ("Note: section %s unmapped by overlap\n",
+ bfd_section_name (objfile->obfd,
+ sec2->the_bfd_section));
+ sec2->ovly_mapped = 0; /* sec2 overlaps sec: unmap sec2 */
+ }
+ return;
+ }
+ error ("No overlay section called %s", args);
+}
+
+/* Function: unmap_overlay_command
+ Mark the overlay section as unmapped
+ (ie. resident in its LMA address range, rather than the VMA range). */
+
+void
+unmap_overlay_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ struct objfile *objfile;
+ struct obj_section *sec;
+
+ if (!overlay_debugging)
+ error ("Overlay debugging not enabled. Use the 'OVERLAY ON' command.");
+
+ if (args == 0 || *args == 0)
+ error ("Argument required: name of an overlay section");
+
+ /* First, find a section matching the user supplied argument */
+ ALL_OBJSECTIONS (objfile, sec)
+ if (!strcmp (bfd_section_name (objfile->obfd, sec->the_bfd_section), args))
+ {
+ if (!sec->ovly_mapped)
+ error ("Section %s is not mapped", args);
+ sec->ovly_mapped = 0;
+ return;
+ }
+ error ("No overlay section called %s", args);
+}
+
+/* Function: overlay_auto_command
+ A utility command to turn on overlay debugging.
+ Possibly this should be done via a set/show command. */
+
+static void
+overlay_auto_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ overlay_debugging = -1;
+ if (info_verbose)
+ printf_filtered ("Automatic overlay debugging enabled.");
+}
+
+/* Function: overlay_manual_command
+ A utility command to turn on overlay debugging.
+ Possibly this should be done via a set/show command. */
+
+static void
+overlay_manual_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ overlay_debugging = 1;
+ if (info_verbose)
+ printf_filtered ("Overlay debugging enabled.");
+}
+
+/* Function: overlay_off_command
+ A utility command to turn on overlay debugging.
+ Possibly this should be done via a set/show command. */
+
+static void
+overlay_off_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ overlay_debugging = 0;
+ if (info_verbose)
+ printf_filtered ("Overlay debugging disabled.");
+}
+
+static void
+overlay_load_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ if (target_overlay_update)
+ (*target_overlay_update) (NULL);
+ else
+ error ("This target does not know how to read its overlay state.");
+}
+
+/* Function: overlay_command
+ A place-holder for a mis-typed command */
+
+/* Command list chain containing all defined "overlay" subcommands. */
+struct cmd_list_element *overlaylist;
+
+static void
+overlay_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ printf_unfiltered
+ ("\"overlay\" must be followed by the name of an overlay command.\n");
+ help_list (overlaylist, "overlay ", -1, gdb_stdout);
+}
+
+
+/* Target Overlays for the "Simplest" overlay manager:
+
+ This is GDB's default target overlay layer. It works with the
+ minimal overlay manager supplied as an example by Cygnus. The
+ entry point is via a function pointer "target_overlay_update",
+ so targets that use a different runtime overlay manager can
+ substitute their own overlay_update function and take over the
+ function pointer.
+
+ The overlay_update function pokes around in the target's data structures
+ to see what overlays are mapped, and updates GDB's overlay mapping with
+ this information.
+
+ In this simple implementation, the target data structures are as follows:
+ unsigned _novlys; /# number of overlay sections #/
+ unsigned _ovly_table[_novlys][4] = {
+ {VMA, SIZE, LMA, MAPPED}, /# one entry per overlay section #/
+ {..., ..., ..., ...},
+ }
+ unsigned _novly_regions; /# number of overlay regions #/
+ unsigned _ovly_region_table[_novly_regions][3] = {
+ {VMA, SIZE, MAPPED_TO_LMA}, /# one entry per overlay region #/
+ {..., ..., ...},
+ }
+ These functions will attempt to update GDB's mappedness state in the
+ symbol section table, based on the target's mappedness state.
+
+ To do this, we keep a cached copy of the target's _ovly_table, and
+ attempt to detect when the cached copy is invalidated. The main
+ entry point is "simple_overlay_update(SECT), which looks up SECT in
+ the cached table and re-reads only the entry for that section from
+ the target (whenever possible).
+ */
+
+/* Cached, dynamically allocated copies of the target data structures: */
+static unsigned (*cache_ovly_table)[4] = 0;
+#if 0
+static unsigned (*cache_ovly_region_table)[3] = 0;
+#endif
+static unsigned cache_novlys = 0;
+#if 0
+static unsigned cache_novly_regions = 0;
+#endif
+static CORE_ADDR cache_ovly_table_base = 0;
+#if 0
+static CORE_ADDR cache_ovly_region_table_base = 0;
+#endif
+enum ovly_index { VMA, SIZE, LMA, MAPPED};
+#define TARGET_LONG_BYTES (TARGET_LONG_BIT / TARGET_CHAR_BIT)
+
+/* Throw away the cached copy of _ovly_table */
+static void
+simple_free_overlay_table ()
+{
+ if (cache_ovly_table)
+ free(cache_ovly_table);
+ cache_novlys = 0;
+ cache_ovly_table = NULL;
+ cache_ovly_table_base = 0;
+}
+
+#if 0
+/* Throw away the cached copy of _ovly_region_table */
+static void
+simple_free_overlay_region_table ()
+{
+ if (cache_ovly_region_table)
+ free(cache_ovly_region_table);
+ cache_novly_regions = 0;
+ cache_ovly_region_table = NULL;
+ cache_ovly_region_table_base = 0;
+}
+#endif
+
+/* Read an array of ints from the target into a local buffer.
+ Convert to host order. int LEN is number of ints */
+static void
+read_target_long_array (memaddr, myaddr, len)
+ CORE_ADDR memaddr;
+ unsigned int *myaddr;
+ int len;
+{
+ char *buf = alloca (len * TARGET_LONG_BYTES);
+ int i;
+
+ read_memory (memaddr, buf, len * TARGET_LONG_BYTES);
+ for (i = 0; i < len; i++)
+ myaddr[i] = extract_unsigned_integer (TARGET_LONG_BYTES * i + buf,
+ TARGET_LONG_BYTES);
+}
+
+/* Find and grab a copy of the target _ovly_table
+ (and _novlys, which is needed for the table's size) */
+static int
+simple_read_overlay_table ()
+{
+ struct minimal_symbol *msym;
+
+ simple_free_overlay_table ();
+ msym = lookup_minimal_symbol ("_novlys", 0, 0);
+ if (msym != NULL)
+ cache_novlys = read_memory_integer (SYMBOL_VALUE_ADDRESS (msym), 4);
+ else
+ return 0; /* failure */
+ cache_ovly_table = (void *) xmalloc (cache_novlys * sizeof(*cache_ovly_table));
+ if (cache_ovly_table != NULL)
+ {
+ msym = lookup_minimal_symbol ("_ovly_table", 0, 0);
+ if (msym != NULL)
+ {
+ cache_ovly_table_base = SYMBOL_VALUE_ADDRESS (msym);
+ read_target_long_array (cache_ovly_table_base,
+ (int *) cache_ovly_table,
+ cache_novlys * 4);
+ }
+ else
+ return 0; /* failure */
+ }
+ else
+ return 0; /* failure */
+ return 1; /* SUCCESS */
+}
+
+#if 0
+/* Find and grab a copy of the target _ovly_region_table
+ (and _novly_regions, which is needed for the table's size) */
+static int
+simple_read_overlay_region_table ()
+{
+ struct minimal_symbol *msym;
+
+ simple_free_overlay_region_table ();
+ msym = lookup_minimal_symbol ("_novly_regions", 0, 0);
+ if (msym != NULL)
+ cache_novly_regions = read_memory_integer (SYMBOL_VALUE_ADDRESS (msym), 4);
+ else
+ return 0; /* failure */
+ cache_ovly_region_table = (void *) xmalloc (cache_novly_regions * 12);
+ if (cache_ovly_region_table != NULL)
+ {
+ msym = lookup_minimal_symbol ("_ovly_region_table", 0, 0);
+ if (msym != NULL)
+ {
+ cache_ovly_region_table_base = SYMBOL_VALUE_ADDRESS (msym);
+ read_target_long_array (cache_ovly_region_table_base,
+ (int *) cache_ovly_region_table,
+ cache_novly_regions * 3);
+ }
+ else
+ return 0; /* failure */
+ }
+ else
+ return 0; /* failure */
+ return 1; /* SUCCESS */
+}
+#endif
+
+/* Function: simple_overlay_update_1
+ A helper function for simple_overlay_update. Assuming a cached copy
+ of _ovly_table exists, look through it to find an entry whose vma,
+ lma and size match those of OSECT. Re-read the entry and make sure
+ it still matches OSECT (else the table may no longer be valid).
+ Set OSECT's mapped state to match the entry. Return: 1 for
+ success, 0 for failure. */
+
+static int
+simple_overlay_update_1 (osect)
+ struct obj_section *osect;
+{
+ int i, size;
+
+ size = bfd_get_section_size_before_reloc (osect->the_bfd_section);
+ for (i = 0; i < cache_novlys; i++)
+ if (cache_ovly_table[i][VMA] == osect->the_bfd_section->vma &&
+ cache_ovly_table[i][LMA] == osect->the_bfd_section->lma /* &&
+ cache_ovly_table[i][SIZE] == size */)
+ {
+ read_target_long_array (cache_ovly_table_base + i * TARGET_LONG_BYTES,
+ (int *) cache_ovly_table[i], 4);
+ if (cache_ovly_table[i][VMA] == osect->the_bfd_section->vma &&
+ cache_ovly_table[i][LMA] == osect->the_bfd_section->lma /* &&
+ cache_ovly_table[i][SIZE] == size */)
+ {
+ osect->ovly_mapped = cache_ovly_table[i][MAPPED];
+ return 1;
+ }
+ else /* Warning! Warning! Target's ovly table has changed! */
+ return 0;
+ }
+ return 0;
+}
+
+/* Function: simple_overlay_update
+ If OSECT is NULL, then update all sections' mapped state
+ (after re-reading the entire target _ovly_table).
+ If OSECT is non-NULL, then try to find a matching entry in the
+ cached ovly_table and update only OSECT's mapped state.
+ If a cached entry can't be found or the cache isn't valid, then
+ re-read the entire cache, and go ahead and update all sections. */
+
+static void
+simple_overlay_update (osect)
+ struct obj_section *osect;
+{
+ struct objfile *objfile;
+
+ /* Were we given an osect to look up? NULL means do all of them. */
+ if (osect)
+ /* Have we got a cached copy of the target's overlay table? */
+ if (cache_ovly_table != NULL)
+ /* Does its cached location match what's currently in the symtab? */
+ if (cache_ovly_table_base ==
+ SYMBOL_VALUE_ADDRESS (lookup_minimal_symbol ("_ovly_table", 0, 0)))
+ /* Then go ahead and try to look up this single section in the cache */
+ if (simple_overlay_update_1 (osect))
+ /* Found it! We're done. */
+ return;
+
+ /* Cached table no good: need to read the entire table anew.
+ Or else we want all the sections, in which case it's actually
+ more efficient to read the whole table in one block anyway. */
+
+ if (simple_read_overlay_table () == 0) /* read failed? No table? */
+ {
+ warning ("Failed to read the target overlay mapping table.");
+ return;
+ }
+ /* Now may as well update all sections, even if only one was requested. */
+ ALL_OBJSECTIONS (objfile, osect)
+ if (section_is_overlay (osect->the_bfd_section))
+ {
+ int i, size;
+
+ size = bfd_get_section_size_before_reloc (osect->the_bfd_section);
+ for (i = 0; i < cache_novlys; i++)
+ if (cache_ovly_table[i][VMA] == osect->the_bfd_section->vma &&
+ cache_ovly_table[i][LMA] == osect->the_bfd_section->lma /* &&
+ cache_ovly_table[i][SIZE] == size */)
+ { /* obj_section matches i'th entry in ovly_table */
+ osect->ovly_mapped = cache_ovly_table[i][MAPPED];
+ break; /* finished with inner for loop: break out */
+ }
+ }
+}
+
+
void
_initialize_symfile ()
{
@@ -1772,4 +2983,40 @@ for access from GDB.", &cmdlist);
&setlist),
&showlist);
+ add_prefix_cmd ("overlay", class_support, overlay_command,
+ "Commands for debugging overlays.", &overlaylist,
+ "overlay ", 0, &cmdlist);
+
+ add_com_alias ("ovly", "overlay", class_alias, 1);
+ add_com_alias ("ov", "overlay", class_alias, 1);
+
+ add_cmd ("map-overlay", class_support, map_overlay_command,
+ "Assert that an overlay section is mapped.", &overlaylist);
+
+ add_cmd ("unmap-overlay", class_support, unmap_overlay_command,
+ "Assert that an overlay section is unmapped.", &overlaylist);
+
+ add_cmd ("list-overlays", class_support, list_overlays_command,
+ "List mappings of overlay sections.", &overlaylist);
+
+ add_cmd ("manual", class_support, overlay_manual_command,
+ "Enable overlay debugging.", &overlaylist);
+ add_cmd ("off", class_support, overlay_off_command,
+ "Disable overlay debugging.", &overlaylist);
+ add_cmd ("auto", class_support, overlay_auto_command,
+ "Enable automatic overlay debugging.", &overlaylist);
+ add_cmd ("load-target", class_support, overlay_load_command,
+ "Read the overlay mapping state from the target.", &overlaylist);
+
+ /* Filename extension to source language lookup table: */
+ init_filename_language_table ();
+ c = add_set_cmd ("extension-language", class_files, var_string_noescape,
+ (char *) &ext_args,
+ "Set mapping between filename extension and source language.\n\
+Usage: set extension-language .foo bar",
+ &setlist);
+ c->function.cfunc = set_ext_lang_command;
+
+ add_info ("extensions", info_ext_lang_command,
+ "All filename extensions associated with a source language.");
}
diff --git a/contrib/gdb/gdb/symtab.c b/contrib/gdb/gdb/symtab.c
index fb3c8f7..1354df5 100644
--- a/contrib/gdb/gdb/symtab.c
+++ b/contrib/gdb/gdb/symtab.c
@@ -4240,6 +4240,7 @@ in_prologue (pc, func_start)
CORE_ADDR pc;
CORE_ADDR func_start;
{
+#if 0
struct symtab_and_line sal;
CORE_ADDR func_addr, func_end;
@@ -4266,6 +4267,7 @@ in_prologue (pc, func_start)
is doing a stepi/nexti through code without symbols. */
nosyms:
+#endif
/* If func_start is zero (meaning unknown) then we don't know whether pc is
in the prologue or not. I.E. it might be. */
diff --git a/contrib/gdb/gdb/target.c b/contrib/gdb/gdb/target.c
index fa7c167..2eea4ac 100644
--- a/contrib/gdb/gdb/target.c
+++ b/contrib/gdb/gdb/target.c
@@ -1,5 +1,5 @@
/* Select target systems and architectures at runtime for GDB.
- Copyright 1990, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright 1990, 1992-1995, 1998, 1999 Free Software Foundation, Inc.
Contributed by Cygnus Support.
This file is part of GDB.
@@ -44,6 +44,9 @@ static void
maybe_kill_then_create_inferior PARAMS ((char *, char *, char **));
static void
+default_clone_and_follow_inferior PARAMS ((int, int *));
+
+static void
maybe_kill_then_attach PARAMS ((char *, int));
static void
@@ -64,8 +67,11 @@ nomemory PARAMS ((CORE_ADDR, char *, int, int, struct target_ops *));
static int
return_zero PARAMS ((void));
-static void
-ignore PARAMS ((void));
+static int
+return_one PARAMS ((void));
+
+void
+target_ignore PARAMS ((void));
static void
target_command PARAMS ((char *, int));
@@ -73,6 +79,103 @@ target_command PARAMS ((char *, int));
static struct target_ops *
find_default_run_target PARAMS ((char *));
+static void
+update_current_target PARAMS ((void));
+
+/* Transfer LEN bytes between target address MEMADDR and GDB address MYADDR.
+ Returns 0 for success, errno code for failure (which includes partial
+ transfers--if you want a more useful response to partial transfers, try
+ target_read_memory_partial). */
+
+static int
+target_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len,
+ int write, asection *bfd_section));
+
+static void init_dummy_target PARAMS ((void));
+
+static void
+debug_to_open PARAMS ((char *, int));
+
+static void
+debug_to_close PARAMS ((int));
+
+static void
+debug_to_attach PARAMS ((char *, int));
+
+static void
+debug_to_detach PARAMS ((char *, int));
+
+static void
+debug_to_resume PARAMS ((int, int, enum target_signal));
+
+static int
+debug_to_wait PARAMS ((int, struct target_waitstatus *));
+
+static void
+debug_to_fetch_registers PARAMS ((int));
+
+static void
+debug_to_store_registers PARAMS ((int));
+
+static void
+debug_to_prepare_to_store PARAMS ((void));
+
+static int
+debug_to_xfer_memory PARAMS ((CORE_ADDR, char *, int, int, struct target_ops *));
+
+static void
+debug_to_files_info PARAMS ((struct target_ops *));
+
+static int
+debug_to_insert_breakpoint PARAMS ((CORE_ADDR, char *));
+
+static int
+debug_to_remove_breakpoint PARAMS ((CORE_ADDR, char *));
+
+static void
+debug_to_terminal_init PARAMS ((void));
+
+static void
+debug_to_terminal_inferior PARAMS ((void));
+
+static void
+debug_to_terminal_ours_for_output PARAMS ((void));
+
+static void
+debug_to_terminal_ours PARAMS ((void));
+
+static void
+debug_to_terminal_info PARAMS ((char *, int));
+
+static void
+debug_to_kill PARAMS ((void));
+
+static void
+debug_to_load PARAMS ((char *, int));
+
+static int
+debug_to_lookup_symbol PARAMS ((char *, CORE_ADDR *));
+
+static void
+debug_to_create_inferior PARAMS ((char *, char *, char **));
+
+static void
+debug_to_mourn_inferior PARAMS ((void));
+
+static int
+debug_to_can_run PARAMS ((void));
+
+static void
+debug_to_notice_signals PARAMS ((int));
+
+static int
+debug_to_thread_alive PARAMS ((int));
+
+static void
+debug_to_stop PARAMS ((void));
+
+static int debug_to_query PARAMS ((int/*char*/, char *, char *, int *));
+
/* Pointer to array of target architecture structures; the size of the
array; the current index into the array; the allocated size of the
array. */
@@ -85,48 +188,7 @@ unsigned target_struct_allocsize;
/* The initial current target, so that there is always a semi-valid
current target. */
-struct target_ops dummy_target = {
- "None", /* to_shortname */
- "None", /* to_longname */
- "", /* to_doc */
- 0, /* to_open */
- 0, /* to_close */
- find_default_attach, /* to_attach */
- 0, /* to_detach */
- 0, /* to_resume */
- 0, /* to_wait */
- 0, /* to_fetch_registers */
- 0, /* to_store_registers */
- 0, /* to_prepare_to_store */
- 0, /* to_xfer_memory */
- 0, /* to_files_info */
- 0, /* to_insert_breakpoint */
- 0, /* to_remove_breakpoint */
- 0, /* to_terminal_init */
- 0, /* to_terminal_inferior */
- 0, /* to_terminal_ours_for_output */
- 0, /* to_terminal_ours */
- 0, /* to_terminal_info */
- 0, /* to_kill */
- 0, /* to_load */
- 0, /* to_lookup_symbol */
- find_default_create_inferior, /* to_create_inferior */
- 0, /* to_mourn_inferior */
- 0, /* to_can_run */
- 0, /* to_notice_signals */
- 0, /* to_thread_alive */
- 0, /* to_stop */
- dummy_stratum, /* to_stratum */
- 0, /* to_next */
- 0, /* to_next */
- 0, /* to_has_all_memory */
- 0, /* to_has_memory */
- 0, /* to_has_registers */
- 0, /* to_has_execution */
- 0, /* to_sections */
- 0, /* to_sections_end */
- OPS_MAGIC, /* to_magic */
-};
+static struct target_ops dummy_target;
/* Top of target stack. */
@@ -202,8 +264,8 @@ information on the arguments for a particular protocol, type\n\
/* Stub functions */
-static void
-ignore ()
+void
+target_ignore ()
{
}
@@ -230,7 +292,7 @@ tcomplain ()
void
noprocess ()
{
- error ("You can't do that without a process to debug");
+ error ("You can't do that without a process to debug.");
}
/* ARGSUSED */
@@ -243,6 +305,17 @@ nosymbol (name, addrp)
}
/* ARGSUSED */
+void
+nosupport_runtime ()
+{
+ if (!inferior_pid)
+ noprocess ();
+ else
+ error ("No run-time support for this");
+}
+
+
+/* ARGSUSED */
static void
default_terminal_info (args, from_tty)
char *args;
@@ -295,6 +368,14 @@ maybe_kill_then_create_inferior (exec, args, env)
target_create_inferior (exec, args, env);
}
+static void
+default_clone_and_follow_inferior (child_pid, followed_child)
+ int child_pid;
+ int *followed_child;
+{
+ target_clone_and_follow_inferior (child_pid, followed_child);
+}
+
/* Clean up a target struct so it no longer has any zero pointers in it.
We default entries, at least to stubs that print error messages. */
@@ -308,34 +389,61 @@ cleanup_target (t)
/* FIELD DEFAULT VALUE */
- de_fault (to_open, (void (*)())tcomplain);
- de_fault (to_close, (void (*)())ignore);
+ de_fault (to_open, (void (*) PARAMS((char *, int))) tcomplain);
+ de_fault (to_close, (void (*) PARAMS((int))) target_ignore);
de_fault (to_attach, maybe_kill_then_attach);
- de_fault (to_detach, (void (*)())ignore);
- de_fault (to_resume, (void (*)())noprocess);
- de_fault (to_wait, (int (*)())noprocess);
- de_fault (to_fetch_registers, (void (*)())ignore);
- de_fault (to_store_registers, (void (*)())noprocess);
- de_fault (to_prepare_to_store, (void (*)())noprocess);
- de_fault (to_xfer_memory, (int (*)())nomemory);
- de_fault (to_files_info, (void (*)())ignore);
+ de_fault (to_post_attach, (void (*) PARAMS ((int))) target_ignore);
+ de_fault (to_require_attach, maybe_kill_then_attach);
+ de_fault (to_detach, (void (*) PARAMS((char *, int))) target_ignore);
+ de_fault (to_require_detach, (void (*) PARAMS((int, char *, int))) target_ignore);
+ de_fault (to_resume, (void (*) PARAMS((int, int, enum target_signal))) noprocess);
+ de_fault (to_wait, (int (*) PARAMS((int, struct target_waitstatus *))) noprocess);
+ de_fault (to_post_wait, (void (*) PARAMS ((int, int))) target_ignore);
+ de_fault (to_fetch_registers, (void (*) PARAMS((int))) target_ignore);
+ de_fault (to_store_registers, (void (*) PARAMS((int))) noprocess);
+ de_fault (to_prepare_to_store, (void (*) PARAMS((void))) noprocess);
+ de_fault (to_xfer_memory, (int (*) PARAMS((CORE_ADDR, char *, int, int, struct target_ops *))) nomemory);
+ de_fault (to_files_info, (void (*) PARAMS((struct target_ops *))) target_ignore);
de_fault (to_insert_breakpoint, memory_insert_breakpoint);
de_fault (to_remove_breakpoint, memory_remove_breakpoint);
- de_fault (to_terminal_init, ignore);
- de_fault (to_terminal_inferior, ignore);
- de_fault (to_terminal_ours_for_output,ignore);
- de_fault (to_terminal_ours, ignore);
+ de_fault (to_terminal_init, (void (*) PARAMS((void))) target_ignore);
+ de_fault (to_terminal_inferior, (void (*) PARAMS ((void))) target_ignore);
+ de_fault (to_terminal_ours_for_output,(void (*) PARAMS ((void))) target_ignore);
+ de_fault (to_terminal_ours, (void (*) PARAMS ((void))) target_ignore);
de_fault (to_terminal_info, default_terminal_info);
- de_fault (to_kill, (void (*)())noprocess);
- de_fault (to_load, (void (*)())tcomplain);
- de_fault (to_lookup_symbol, nosymbol);
+ de_fault (to_kill, (void (*) PARAMS((void))) noprocess);
+ de_fault (to_load, (void (*) PARAMS((char *, int))) tcomplain);
+ de_fault (to_lookup_symbol, (int (*) PARAMS ((char *, CORE_ADDR *))) nosymbol);
de_fault (to_create_inferior, maybe_kill_then_create_inferior);
- de_fault (to_mourn_inferior, (void (*)())noprocess);
+ de_fault (to_post_startup_inferior, (void (*) PARAMS ((int))) target_ignore);
+ de_fault (to_acknowledge_created_inferior, (void (*) PARAMS((int))) target_ignore);
+ de_fault (to_clone_and_follow_inferior, default_clone_and_follow_inferior);
+ de_fault (to_post_follow_inferior_by_clone, (void (*) PARAMS ((void))) target_ignore);
+ de_fault (to_insert_fork_catchpoint, (int (*) PARAMS ((int))) tcomplain);
+ de_fault (to_remove_fork_catchpoint, (int (*) PARAMS ((int))) tcomplain);
+ de_fault (to_insert_vfork_catchpoint, (int (*) PARAMS ((int))) tcomplain);
+ de_fault (to_remove_vfork_catchpoint, (int (*) PARAMS ((int))) tcomplain);
+ de_fault (to_has_forked, (int (*) PARAMS ((int, int *))) return_zero);
+ de_fault (to_has_vforked, (int (*) PARAMS ((int, int *))) return_zero);
+ de_fault (to_can_follow_vfork_prior_to_exec, (int (*) PARAMS ((void ))) return_zero);
+ de_fault (to_post_follow_vfork, (void (*) PARAMS ((int, int, int, int))) target_ignore);
+ de_fault (to_insert_exec_catchpoint, (int (*) PARAMS ((int))) tcomplain);
+ de_fault (to_remove_exec_catchpoint, (int (*) PARAMS ((int))) tcomplain);
+ de_fault (to_has_execd, (int (*) PARAMS ((int, char **))) return_zero);
+ de_fault (to_reported_exec_events_per_exec_call, (int (*) PARAMS ((void))) return_one);
+ de_fault (to_has_syscall_event, (int (*) PARAMS ((int, enum target_waitkind *, int *))) return_zero);
+ de_fault (to_has_exited, (int (*) PARAMS ((int, int, int *))) return_zero);
+ de_fault (to_mourn_inferior, (void (*) PARAMS ((void))) noprocess);
de_fault (to_can_run, return_zero);
- de_fault (to_notice_signals, (void (*)())ignore);
- de_fault (to_thread_alive, (int (*)())ignore);
- de_fault (to_stop, (void (*)())ignore);
-
+ de_fault (to_notice_signals, (void (*) PARAMS((int))) target_ignore);
+ de_fault (to_thread_alive, (int (*) PARAMS((int))) target_ignore);
+ de_fault (to_stop, (void (*) PARAMS((void))) target_ignore);
+ de_fault (to_query, (int (*) PARAMS((int/*char*/, char*, char *, int *))) target_ignore);
+ de_fault (to_enable_exception_callback, (struct symtab_and_line * (*) PARAMS((enum exception_event_kind, int))) nosupport_runtime);
+ de_fault (to_get_current_exception_event, (struct exception_event_record * (*) PARAMS((void))) nosupport_runtime);
+
+ de_fault (to_pid_to_exec_file, (char* (*) PARAMS((int))) return_zero);
+ de_fault (to_core_file_to_sym_file, (char* (*) PARAMS ((char *))) return_zero);
#undef de_fault
}
@@ -366,9 +474,13 @@ update_current_target ()
INHERIT (to_open, t);
INHERIT (to_close, t);
INHERIT (to_attach, t);
+ INHERIT (to_post_attach, t);
+ INHERIT (to_require_attach, t);
INHERIT (to_detach, t);
+ INHERIT (to_require_detach, t);
INHERIT (to_resume, t);
INHERIT (to_wait, t);
+ INHERIT (to_post_wait, t);
INHERIT (to_fetch_registers, t);
INHERIT (to_store_registers, t);
INHERIT (to_prepare_to_store, t);
@@ -385,11 +497,34 @@ update_current_target ()
INHERIT (to_load, t);
INHERIT (to_lookup_symbol, t);
INHERIT (to_create_inferior, t);
+ INHERIT (to_post_startup_inferior, t);
+ INHERIT (to_acknowledge_created_inferior, t);
+ INHERIT (to_clone_and_follow_inferior, t);
+ INHERIT (to_post_follow_inferior_by_clone, t);
+ INHERIT (to_insert_fork_catchpoint, t);
+ INHERIT (to_remove_fork_catchpoint, t);
+ INHERIT (to_insert_vfork_catchpoint, t);
+ INHERIT (to_remove_vfork_catchpoint, t);
+ INHERIT (to_has_forked, t);
+ INHERIT (to_has_vforked, t);
+ INHERIT (to_can_follow_vfork_prior_to_exec, t);
+ INHERIT (to_post_follow_vfork, t);
+ INHERIT (to_insert_exec_catchpoint, t);
+ INHERIT (to_remove_exec_catchpoint, t);
+ INHERIT (to_has_execd, t);
+ INHERIT (to_reported_exec_events_per_exec_call, t);
+ INHERIT (to_has_syscall_event, t);
+ INHERIT (to_has_exited, t);
INHERIT (to_mourn_inferior, t);
INHERIT (to_can_run, t);
INHERIT (to_notice_signals, t);
INHERIT (to_thread_alive, t);
INHERIT (to_stop, t);
+ INHERIT (to_query, t);
+ INHERIT (to_enable_exception_callback, t);
+ INHERIT (to_get_current_exception_event, t);
+ INHERIT (to_pid_to_exec_file, t);
+ INHERIT (to_core_file_to_sym_file, t);
INHERIT (to_stratum, t);
INHERIT (DONT_USE, t);
INHERIT (to_has_all_memory, t);
@@ -397,6 +532,7 @@ update_current_target ()
INHERIT (to_has_stack, t);
INHERIT (to_has_registers, t);
INHERIT (to_has_execution, t);
+ INHERIT (to_has_thread_control, t);
INHERIT (to_sections, t);
INHERIT (to_sections_end, t);
INHERIT (to_magic, t);
@@ -445,7 +581,8 @@ push_target (t)
while (t->to_stratum == cur->target_ops->to_stratum)
{
/* There's already something on this stratum. Close it off. */
- (cur->target_ops->to_close) (0);
+ if (cur->target_ops->to_close)
+ (cur->target_ops->to_close) (0);
if (prev)
prev->next = cur->next; /* Unchain old target_ops */
else
@@ -565,9 +702,18 @@ target_read_string (memaddr, string, len, errnop)
tlen = MIN (len, 4 - (memaddr & 3));
offset = memaddr & 3;
- errcode = target_xfer_memory (memaddr & ~3, buf, 4, 0);
+ errcode = target_xfer_memory (memaddr & ~3, buf, 4, 0, NULL);
if (errcode != 0)
- goto done;
+ {
+ /* The transfer request might have crossed the boundary to an
+ unallocated region of memory. Retry the transfer, requesting
+ a single byte. */
+ tlen = 1;
+ offset = 0;
+ errcode = target_xfer_memory (memaddr, buf, 1, 0, NULL);
+ if (errcode != 0)
+ goto done;
+ }
if (bufptr - buffer + tlen > buffer_allocated)
{
@@ -616,7 +762,17 @@ target_read_memory (memaddr, myaddr, len)
char *myaddr;
int len;
{
- return target_xfer_memory (memaddr, myaddr, len, 0);
+ return target_xfer_memory (memaddr, myaddr, len, 0, NULL);
+}
+
+int
+target_read_memory_section (memaddr, myaddr, len, bfd_section)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+ asection *bfd_section;
+{
+ return target_xfer_memory (memaddr, myaddr, len, 0, bfd_section);
}
/* Read LEN bytes of target memory at address MEMADDR, placing the results
@@ -635,7 +791,7 @@ target_read_memory_partial (memaddr, myaddr, len, errnoptr)
int errcode; /* Error from last read. */
/* First try a complete read. */
- errcode = target_xfer_memory (memaddr, myaddr, len, 0);
+ errcode = target_xfer_memory (memaddr, myaddr, len, 0, NULL);
if (errcode == 0)
{
/* Got it all. */
@@ -646,7 +802,7 @@ target_read_memory_partial (memaddr, myaddr, len, errnoptr)
/* Loop, reading one byte at a time until we get as much as we can. */
for (errcode = 0, nread = 0; len > 0 && errcode == 0; nread++, len--)
{
- errcode = target_xfer_memory (memaddr++, myaddr++, 1, 0);
+ errcode = target_xfer_memory (memaddr++, myaddr++, 1, 0, NULL);
}
/* If an error, the last read was unsuccessful, so adjust count. */
if (errcode != 0)
@@ -667,9 +823,15 @@ target_write_memory (memaddr, myaddr, len)
char *myaddr;
int len;
{
- return target_xfer_memory (memaddr, myaddr, len, 1);
+ return target_xfer_memory (memaddr, myaddr, len, 1, NULL);
}
+/* This variable is used to pass section information down to targets. This
+ *should* be done by adding an argument to the target_xfer_memory function
+ of all the targets, but I didn't feel like changing 50+ files. */
+
+asection *target_memory_bfd_section = NULL;
+
/* Move memory to or from the targets. Iterate until all of it has
been moved, if necessary. The top target gets priority; anything
it doesn't want, is offered to the next one down, etc. Note the
@@ -680,18 +842,25 @@ target_write_memory (memaddr, myaddr, len)
Result is 0 or errno value. */
-int
-target_xfer_memory (memaddr, myaddr, len, write)
+static int
+target_xfer_memory (memaddr, myaddr, len, write, bfd_section)
CORE_ADDR memaddr;
char *myaddr;
int len;
int write;
+ asection *bfd_section;
{
int curlen;
int res;
struct target_ops *t;
struct target_stack_item *item;
+ /* Zero length requests are ok and require no work. */
+ if (len == 0)
+ return 0;
+
+ target_memory_bfd_section = bfd_section;
+
/* to_xfer_memory is not guaranteed to set errno, even when it returns
0. */
errno = 0;
@@ -875,6 +1044,31 @@ find_default_attach (args, from_tty)
}
void
+find_default_require_attach (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ struct target_ops *t;
+
+ t = find_default_run_target("require_attach");
+ (t->to_require_attach) (args, from_tty);
+ return;
+}
+
+void
+find_default_require_detach (pid, args, from_tty)
+ int pid;
+ char * args;
+ int from_tty;
+{
+ struct target_ops *t;
+
+ t = find_default_run_target("require_detach");
+ (t->to_require_detach) (pid, args, from_tty);
+ return;
+}
+
+void
find_default_create_inferior (exec_file, allargs, env)
char *exec_file;
char *allargs;
@@ -887,12 +1081,30 @@ find_default_create_inferior (exec_file, allargs, env)
return;
}
+void
+find_default_clone_and_follow_inferior (child_pid, followed_child)
+ int child_pid;
+ int *followed_child;
+{
+ struct target_ops *t;
+
+ t = find_default_run_target("run");
+ (t->to_clone_and_follow_inferior) (child_pid, followed_child);
+ return;
+}
+
static int
return_zero ()
{
return 0;
}
+static int
+return_one ()
+{
+ return 1;
+}
+
struct target_ops *
find_core_target ()
{
@@ -924,7 +1136,7 @@ generic_mourn_inferior ()
inferior_pid = 0;
attach_flag = 0;
- breakpoint_init_inferior ();
+ breakpoint_init_inferior (inf_exited);
registers_changed ();
#ifdef CLEAR_DEFERRED_STORES
@@ -990,7 +1202,7 @@ static struct {
{"SIGLWP", "Signal LWP"},
{"SIGDANGER", "Swap space dangerously low"},
{"SIGGRANT", "Monitor mode granted"},
- {"SIGRETRACT", "Need to relinguish monitor mode"},
+ {"SIGRETRACT", "Need to relinquish monitor mode"},
{"SIGMSG", "Monitor mode data available"},
{"SIGSOUND", "Sound completed"},
{"SIGSAK", "Secure attention"},
@@ -1027,6 +1239,15 @@ static struct {
{"SIG62", "Real-time event 62"},
{"SIG63", "Real-time event 63"},
+#if defined(MACH) || defined(__MACH__)
+ /* Mach exceptions */
+ {"EXC_BAD_ACCESS", "Could not access memory"},
+ {"EXC_BAD_INSTRUCTION", "Illegal instruction/operand"},
+ {"EXC_ARITHMETIC", "Arithmetic exception"},
+ {"EXC_EMULATION", "Emulation instruction"},
+ {"EXC_SOFTWARE", "Software generated exception"},
+ {"EXC_BREAKPOINT", "Breakpoint"},
+#endif
{NULL, "Unknown signal"},
{NULL, "Internal error: printing TARGET_SIGNAL_DEFAULT"},
@@ -1224,6 +1445,27 @@ target_signal_from_host (hostsig)
#if defined (SIGPRIO)
if (hostsig == SIGPRIO) return TARGET_SIGNAL_PRIO;
#endif
+
+ /* Mach exceptions. Assumes that the values for EXC_ are positive! */
+#if defined (EXC_BAD_ACCESS) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_BAD_ACCESS) return TARGET_EXC_BAD_ACCESS;
+#endif
+#if defined (EXC_BAD_INSTRUCTION) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_BAD_INSTRUCTION) return TARGET_EXC_BAD_INSTRUCTION;
+#endif
+#if defined (EXC_ARITHMETIC) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_ARITHMETIC) return TARGET_EXC_ARITHMETIC;
+#endif
+#if defined (EXC_EMULATION) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_EMULATION) return TARGET_EXC_EMULATION;
+#endif
+#if defined (EXC_SOFTWARE) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_SOFTWARE) return TARGET_EXC_SOFTWARE;
+#endif
+#if defined (EXC_BREAKPOINT) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_BREAKPOINT) return TARGET_EXC_BREAKPOINT;
+#endif
+
#if defined (REALTIME_LO)
if (hostsig >= REALTIME_LO && hostsig < REALTIME_HI)
return (enum target_signal)
@@ -1377,6 +1619,27 @@ target_signal_to_host (oursig)
#if defined (SIGPRIO)
case TARGET_SIGNAL_PRIO: return SIGPRIO;
#endif
+
+ /* Mach exceptions. Assumes that the values for EXC_ are positive! */
+#if defined (EXC_BAD_ACCESS) && defined (_NSIG)
+ case TARGET_EXC_BAD_ACCESS: return _NSIG + EXC_BAD_ACCESS;
+#endif
+#if defined (EXC_BAD_INSTRUCTION) && defined (_NSIG)
+ case TARGET_EXC_BAD_INSTRUCTION: return _NSIG + EXC_BAD_INSTRUCTION;
+#endif
+#if defined (EXC_ARITHMETIC) && defined (_NSIG)
+ case TARGET_EXC_ARITHMETIC: return _NSIG + EXC_ARITHMETIC;
+#endif
+#if defined (EXC_EMULATION) && defined (_NSIG)
+ case TARGET_EXC_EMULATION: return _NSIG + EXC_EMULATION;
+#endif
+#if defined (EXC_SOFTWARE) && defined (_NSIG)
+ case TARGET_EXC_SOFTWARE: return _NSIG + EXC_SOFTWARE;
+#endif
+#if defined (EXC_BREAKPOINT) && defined (_NSIG)
+ case TARGET_EXC_BREAKPOINT: return _NSIG + EXC_BREAKPOINT;
+#endif
+
default:
#if defined (REALTIME_LO)
if (oursig >= TARGET_SIGNAL_REALTIME_33
@@ -1460,12 +1723,50 @@ normal_pid_to_str (pid)
static char buf[30];
if (STREQ (current_target.to_shortname, "remote"))
- sprintf (buf, "thread %d", pid);
+ sprintf (buf, "thread %d\0", pid);
else
- sprintf (buf, "process %d", pid);
+ sprintf (buf, "process %d\0", pid);
return buf;
}
+
+/* Some targets (such as ttrace-based HPUX) don't allow us to request
+ notification of inferior events such as fork and vork immediately
+ after the inferior is created. (This because of how gdb gets an
+ inferior created via invoking a shell to do it. In such a scenario,
+ if the shell init file has commands in it, the shell will fork and
+ exec for each of those commands, and we will see each such fork
+ event. Very bad.)
+
+ This function is used by all targets that allow us to request
+ notification of forks, etc at inferior creation time; e.g., in
+ target_acknowledge_forked_child.
+ */
+void
+normal_target_post_startup_inferior (pid)
+ int pid;
+{
+ /* This space intentionally left blank. */
+}
+
+/* Set up the handful of non-empty slots needed by the dummy target
+ vector. */
+
+static void
+init_dummy_target ()
+{
+ dummy_target.to_shortname = "None";
+ dummy_target.to_longname = "None";
+ dummy_target.to_doc = "";
+ dummy_target.to_attach = find_default_attach;
+ dummy_target.to_require_attach = find_default_require_attach;
+ dummy_target.to_require_detach = find_default_require_detach;
+ dummy_target.to_create_inferior = find_default_create_inferior;
+ dummy_target.to_clone_and_follow_inferior = find_default_clone_and_follow_inferior;
+ dummy_target.to_stratum = dummy_stratum;
+ dummy_target.to_magic = OPS_MAGIC;
+}
+
#ifdef MAINTENANCE_CMDS
static struct target_ops debug_target;
@@ -1477,7 +1778,7 @@ debug_to_open (args, from_tty)
{
debug_target.to_open (args, from_tty);
- fprintf_unfiltered (stderr, "target_open (%s, %d)\n", args, from_tty);
+ fprintf_unfiltered (gdb_stderr, "target_open (%s, %d)\n", args, from_tty);
}
static void
@@ -1486,7 +1787,7 @@ debug_to_close (quitting)
{
debug_target.to_close (quitting);
- fprintf_unfiltered (stderr, "target_close (%d)\n", quitting);
+ fprintf_unfiltered (gdb_stderr, "target_close (%d)\n", quitting);
}
static void
@@ -1496,7 +1797,28 @@ debug_to_attach (args, from_tty)
{
debug_target.to_attach (args, from_tty);
- fprintf_unfiltered (stderr, "target_attach (%s, %d)\n", args, from_tty);
+ fprintf_unfiltered (gdb_stderr, "target_attach (%s, %d)\n", args, from_tty);
+}
+
+
+static void
+debug_to_post_attach (pid)
+ int pid;
+{
+ debug_target.to_post_attach (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_post_attach (%d)\n", pid);
+}
+
+static void
+debug_to_require_attach (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ debug_target.to_require_attach (args, from_tty);
+
+ fprintf_unfiltered (gdb_stderr,
+ "target_require_attach (%s, %d)\n", args, from_tty);
}
static void
@@ -1506,7 +1828,19 @@ debug_to_detach (args, from_tty)
{
debug_target.to_detach (args, from_tty);
- fprintf_unfiltered (stderr, "target_detach (%s, %d)\n", args, from_tty);
+ fprintf_unfiltered (gdb_stderr, "target_detach (%s, %d)\n", args, from_tty);
+}
+
+static void
+debug_to_require_detach (pid, args, from_tty)
+ int pid;
+ char * args;
+ int from_tty;
+{
+ debug_target.to_require_detach (pid, args, from_tty);
+
+ fprintf_unfiltered (gdb_stderr,
+ "target_require_detach (%d, %s, %d)\n", pid, args, from_tty);
}
static void
@@ -1517,7 +1851,7 @@ debug_to_resume (pid, step, siggnal)
{
debug_target.to_resume (pid, step, siggnal);
- fprintf_unfiltered (stderr, "target_resume (%d, %s, %s)\n", pid,
+ fprintf_unfiltered (gdb_stderr, "target_resume (%d, %s, %s)\n", pid,
step ? "step" : "continue",
target_signal_to_name (siggnal));
}
@@ -1531,29 +1865,40 @@ debug_to_wait (pid, status)
retval = debug_target.to_wait (pid, status);
- fprintf_unfiltered (stderr, "target_wait (%d, status) = %d, ", pid, retval);
- fprintf_unfiltered (stderr, "status->kind = ");
+ fprintf_unfiltered (gdb_stderr,
+ "target_wait (%d, status) = %d, ", pid, retval);
+ fprintf_unfiltered (gdb_stderr, "status->kind = ");
switch (status->kind)
{
case TARGET_WAITKIND_EXITED:
- fprintf_unfiltered (stderr, "exited, status = %d\n", status->value.integer);
+ fprintf_unfiltered (gdb_stderr, "exited, status = %d\n",
+ status->value.integer);
break;
case TARGET_WAITKIND_STOPPED:
- fprintf_unfiltered (stderr, "stopped, signal = %s\n",
+ fprintf_unfiltered (gdb_stderr, "stopped, signal = %s\n",
target_signal_to_name (status->value.sig));
break;
case TARGET_WAITKIND_SIGNALLED:
- fprintf_unfiltered (stderr, "signalled, signal = %s\n",
+ fprintf_unfiltered (gdb_stderr, "signalled, signal = %s\n",
target_signal_to_name (status->value.sig));
break;
case TARGET_WAITKIND_LOADED:
- fprintf_unfiltered (stderr, "loaded\n");
+ fprintf_unfiltered (gdb_stderr, "loaded\n");
+ break;
+ case TARGET_WAITKIND_FORKED:
+ fprintf_unfiltered (gdb_stderr, "forked\n");
+ break;
+ case TARGET_WAITKIND_VFORKED:
+ fprintf_unfiltered (gdb_stderr, "vforked\n");
+ break;
+ case TARGET_WAITKIND_EXECD:
+ fprintf_unfiltered (gdb_stderr, "execd\n");
break;
case TARGET_WAITKIND_SPURIOUS:
- fprintf_unfiltered (stderr, "spurious\n");
+ fprintf_unfiltered (gdb_stderr, "spurious\n");
break;
default:
- fprintf_unfiltered (stderr, "unknown???\n");
+ fprintf_unfiltered (gdb_stderr, "unknown???\n");
break;
}
@@ -1561,17 +1906,29 @@ debug_to_wait (pid, status)
}
static void
+debug_to_post_wait (pid, status)
+ int pid;
+ int status;
+{
+ debug_target.to_post_wait (pid, status);
+
+ fprintf_unfiltered (gdb_stderr, "target_post_wait (%d, %d)\n",
+ pid, status);
+}
+
+static void
debug_to_fetch_registers (regno)
int regno;
{
debug_target.to_fetch_registers (regno);
- fprintf_unfiltered (stderr, "target_fetch_registers (%s)",
- regno != -1 ? reg_names[regno] : "-1");
+ fprintf_unfiltered (gdb_stderr, "target_fetch_registers (%s)",
+ regno != -1 ? REGISTER_NAME (regno) : "-1");
if (regno != -1)
- fprintf_unfiltered (stderr, " = 0x%x %d", read_register (regno),
+ fprintf_unfiltered (gdb_stderr, " = 0x%x %d",
+ (unsigned long) read_register (regno),
read_register (regno));
- fprintf_unfiltered (stderr, "\n");
+ fprintf_unfiltered (gdb_stderr, "\n");
}
static void
@@ -1581,11 +1938,12 @@ debug_to_store_registers (regno)
debug_target.to_store_registers (regno);
if (regno >= 0 && regno < NUM_REGS)
- fprintf_unfiltered (stderr, "target_store_registers (%s) = 0x%x %d\n",
- reg_names[regno], read_register (regno),
- read_register (regno));
+ fprintf_unfiltered (gdb_stderr, "target_store_registers (%s) = 0x%x %d\n",
+ REGISTER_NAME (regno),
+ (unsigned long) read_register (regno),
+ (unsigned long) read_register (regno));
else
- fprintf_unfiltered (stderr, "target_store_registers (%d)\n", regno);
+ fprintf_unfiltered (gdb_stderr, "target_store_registers (%d)\n", regno);
}
static void
@@ -1593,7 +1951,7 @@ debug_to_prepare_to_store ()
{
debug_target.to_prepare_to_store ();
- fprintf_unfiltered (stderr, "target_prepare_to_store ()\n");
+ fprintf_unfiltered (gdb_stderr, "target_prepare_to_store ()\n");
}
static int
@@ -1608,8 +1966,12 @@ debug_to_xfer_memory (memaddr, myaddr, len, write, target)
retval = debug_target.to_xfer_memory (memaddr, myaddr, len, write, target);
- fprintf_unfiltered (stderr, "target_xfer_memory (0x%x, xxx, %d, %s, xxx) = %d",
- memaddr, len, write ? "write" : "read", retval);
+ fprintf_unfiltered (gdb_stderr,
+ "target_xfer_memory (0x%x, xxx, %d, %s, xxx) = %d",
+ (unsigned int) memaddr, /* possable truncate long long */
+ len, write ? "write" : "read", retval);
+
+
if (retval > 0)
{
@@ -1617,7 +1979,11 @@ debug_to_xfer_memory (memaddr, myaddr, len, write, target)
fputs_unfiltered (", bytes =", gdb_stderr);
for (i = 0; i < retval; i++)
- fprintf_unfiltered (stderr, " %02x", myaddr[i] & 0xff);
+ {
+ if ((((long) &(myaddr[i])) & 0xf) == 0)
+ fprintf_unfiltered (gdb_stderr, "\n");
+ fprintf_unfiltered (gdb_stderr, " %02x", myaddr[i] & 0xff);
+ }
}
fputc_unfiltered ('\n', gdb_stderr);
@@ -1631,7 +1997,7 @@ debug_to_files_info (target)
{
debug_target.to_files_info (target);
- fprintf_unfiltered (stderr, "target_files_info (xxx)\n");
+ fprintf_unfiltered (gdb_stderr, "target_files_info (xxx)\n");
}
static int
@@ -1643,8 +2009,9 @@ debug_to_insert_breakpoint (addr, save)
retval = debug_target.to_insert_breakpoint (addr, save);
- fprintf_unfiltered (stderr, "target_insert_breakpoint (0x%x, xxx) = %d\n",
- addr, retval);
+ fprintf_unfiltered (gdb_stderr,
+ "target_insert_breakpoint (0x%x, xxx) = %d\n",
+ (unsigned long) addr, retval);
return retval;
}
@@ -1657,8 +2024,9 @@ debug_to_remove_breakpoint (addr, save)
retval = debug_target.to_remove_breakpoint (addr, save);
- fprintf_unfiltered (stderr, "target_remove_breakpoint (0x%x, xxx) = %d\n",
- addr, retval);
+ fprintf_unfiltered (gdb_stderr,
+ "target_remove_breakpoint (0x%x, xxx) = %d\n",
+ (unsigned long)addr, retval);
return retval;
}
@@ -1667,7 +2035,7 @@ debug_to_terminal_init ()
{
debug_target.to_terminal_init ();
- fprintf_unfiltered (stderr, "target_terminal_init ()\n");
+ fprintf_unfiltered (gdb_stderr, "target_terminal_init ()\n");
}
static void
@@ -1675,7 +2043,7 @@ debug_to_terminal_inferior ()
{
debug_target.to_terminal_inferior ();
- fprintf_unfiltered (stderr, "target_terminal_inferior ()\n");
+ fprintf_unfiltered (gdb_stderr, "target_terminal_inferior ()\n");
}
static void
@@ -1683,7 +2051,7 @@ debug_to_terminal_ours_for_output ()
{
debug_target.to_terminal_ours_for_output ();
- fprintf_unfiltered (stderr, "target_terminal_ours_for_output ()\n");
+ fprintf_unfiltered (gdb_stderr, "target_terminal_ours_for_output ()\n");
}
static void
@@ -1691,7 +2059,7 @@ debug_to_terminal_ours ()
{
debug_target.to_terminal_ours ();
- fprintf_unfiltered (stderr, "target_terminal_ours ()\n");
+ fprintf_unfiltered (gdb_stderr, "target_terminal_ours ()\n");
}
static void
@@ -1701,7 +2069,7 @@ debug_to_terminal_info (arg, from_tty)
{
debug_target.to_terminal_info (arg, from_tty);
- fprintf_unfiltered (stderr, "target_terminal_info (%s, %d)\n", arg,
+ fprintf_unfiltered (gdb_stderr, "target_terminal_info (%s, %d)\n", arg,
from_tty);
}
@@ -1710,7 +2078,7 @@ debug_to_kill ()
{
debug_target.to_kill ();
- fprintf_unfiltered (stderr, "target_kill ()\n");
+ fprintf_unfiltered (gdb_stderr, "target_kill ()\n");
}
static void
@@ -1720,7 +2088,7 @@ debug_to_load (args, from_tty)
{
debug_target.to_load (args, from_tty);
- fprintf_unfiltered (stderr, "target_load (%s, %d)\n", args, from_tty);
+ fprintf_unfiltered (gdb_stderr, "target_load (%s, %d)\n", args, from_tty);
}
static int
@@ -1732,7 +2100,7 @@ debug_to_lookup_symbol (name, addrp)
retval = debug_target.to_lookup_symbol (name, addrp);
- fprintf_unfiltered (stderr, "target_lookup_symbol (%s, xxx)\n", name);
+ fprintf_unfiltered (gdb_stderr, "target_lookup_symbol (%s, xxx)\n", name);
return retval;
}
@@ -1745,16 +2113,274 @@ debug_to_create_inferior (exec_file, args, env)
{
debug_target.to_create_inferior (exec_file, args, env);
- fprintf_unfiltered (stderr, "target_create_inferior (%s, %s, xxx)\n",
+ fprintf_unfiltered (gdb_stderr, "target_create_inferior (%s, %s, xxx)\n",
exec_file, args);
}
static void
+debug_to_post_startup_inferior (pid)
+ int pid;
+{
+ debug_target.to_post_startup_inferior (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_post_startup_inferior (%d)\n",
+ pid);
+}
+
+static void
+debug_to_acknowledge_created_inferior (pid)
+ int pid;
+{
+ debug_target.to_acknowledge_created_inferior (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_acknowledge_created_inferior (%d)\n",
+ pid);
+}
+
+static void
+debug_to_clone_and_follow_inferior (child_pid, followed_child)
+ int child_pid;
+ int *followed_child;
+{
+ debug_target.to_clone_and_follow_inferior (child_pid, followed_child);
+
+ fprintf_unfiltered (gdb_stderr,
+ "target_clone_and_follow_inferior (%d, %d)\n",
+ child_pid, *followed_child);
+}
+
+static void
+debug_to_post_follow_inferior_by_clone ()
+{
+ debug_target.to_post_follow_inferior_by_clone ();
+
+ fprintf_unfiltered (gdb_stderr, "target_post_follow_inferior_by_clone ()\n");
+}
+
+static int
+debug_to_insert_fork_catchpoint (pid)
+ int pid;
+{
+ int retval;
+
+ retval = debug_target.to_insert_fork_catchpoint (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_insert_fork_catchpoint (%d) = %d\n",
+ pid, retval);
+
+ return retval;
+}
+
+static int
+debug_to_remove_fork_catchpoint (pid)
+ int pid;
+{
+ int retval;
+
+ retval = debug_target.to_remove_fork_catchpoint (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_remove_fork_catchpoint (%d) = %d\n",
+ pid, retval);
+
+ return retval;
+}
+
+static int
+debug_to_insert_vfork_catchpoint (pid)
+ int pid;
+{
+ int retval;
+
+ retval = debug_target.to_insert_vfork_catchpoint (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_insert_vfork_catchpoint (%d)= %d\n",
+ pid, retval);
+
+ return retval;
+}
+
+static int
+debug_to_remove_vfork_catchpoint (pid)
+ int pid;
+{
+ int retval;
+
+ retval = debug_target.to_remove_vfork_catchpoint (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_remove_vfork_catchpoint (%d) = %d\n",
+ pid, retval);
+
+ return retval;
+}
+
+static int
+debug_to_has_forked (pid, child_pid)
+ int pid;
+ int * child_pid;
+{
+ int has_forked;
+
+ has_forked = debug_target.to_has_forked (pid, child_pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_has_forked (%d, %d) = %d\n",
+ pid, *child_pid, has_forked);
+
+ return has_forked;
+}
+
+static int
+debug_to_has_vforked (pid, child_pid)
+ int pid;
+ int * child_pid;
+{
+ int has_vforked;
+
+ has_vforked = debug_target.to_has_vforked (pid, child_pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_has_vforked (%d, %d) = %d\n",
+ pid, *child_pid, has_vforked);
+
+ return has_vforked;
+}
+
+static int
+debug_to_can_follow_vfork_prior_to_exec ()
+{
+ int can_immediately_follow_vfork;
+
+ can_immediately_follow_vfork = debug_target.to_can_follow_vfork_prior_to_exec ();
+
+ fprintf_unfiltered (gdb_stderr, "target_can_follow_vfork_prior_to_exec () = %d\n",
+ can_immediately_follow_vfork);
+
+ return can_immediately_follow_vfork;
+}
+
+static void
+debug_to_post_follow_vfork (parent_pid, followed_parent, child_pid, followed_child)
+ int parent_pid;
+ int followed_parent;
+ int child_pid;
+ int followed_child;
+{
+ debug_target.to_post_follow_vfork (parent_pid, followed_parent, child_pid, followed_child);
+
+ fprintf_unfiltered (gdb_stderr,
+ "target_post_follow_vfork (%d, %d, %d, %d)\n",
+ parent_pid, followed_parent, child_pid, followed_child);
+}
+
+static int
+debug_to_insert_exec_catchpoint (pid)
+ int pid;
+{
+ int retval;
+
+ retval = debug_target.to_insert_exec_catchpoint (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_insert_exec_catchpoint (%d) = %d\n",
+ pid, retval);
+
+ return retval;
+}
+
+static int
+debug_to_remove_exec_catchpoint (pid)
+ int pid;
+{
+ int retval;
+
+ retval = debug_target.to_remove_exec_catchpoint (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_remove_exec_catchpoint (%d) = %d\n",
+ pid, retval);
+
+ return retval;
+}
+
+static int
+debug_to_has_execd (pid, execd_pathname)
+ int pid;
+ char ** execd_pathname;
+{
+ int has_execd;
+
+ has_execd = debug_target.to_has_execd (pid, execd_pathname);
+
+ fprintf_unfiltered (gdb_stderr, "target_has_execd (%d, %s) = %d\n",
+ pid, *execd_pathname, has_execd);
+
+ return has_execd;
+}
+
+static int
+debug_to_reported_exec_events_per_exec_call ()
+{
+ int reported_exec_events;
+
+ reported_exec_events = debug_target.to_reported_exec_events_per_exec_call ();
+
+ fprintf_unfiltered (gdb_stderr,
+ "target_reported_exec_events_per_exec_call () = %d\n",
+ reported_exec_events);
+
+ return reported_exec_events;
+}
+
+static int
+debug_to_has_syscall_event (pid, kind, syscall_id)
+ int pid;
+ enum target_waitkind * kind;
+ int * syscall_id;
+{
+ int has_syscall_event;
+ char * kind_spelling = "??";
+
+ has_syscall_event = debug_target.to_has_syscall_event (pid, kind, syscall_id);
+ if (has_syscall_event)
+ {
+ switch (*kind)
+ {
+ case TARGET_WAITKIND_SYSCALL_ENTRY:
+ kind_spelling = "SYSCALL_ENTRY";
+ break;
+ case TARGET_WAITKIND_SYSCALL_RETURN:
+ kind_spelling = "SYSCALL_RETURN";
+ break;
+ default:
+ break;
+ }
+ }
+
+ fprintf_unfiltered (gdb_stderr,
+ "target_has_syscall_event (%d, %s, %d) = %d\n",
+ pid, kind_spelling, *syscall_id, has_syscall_event);
+
+ return has_syscall_event;
+}
+
+static int
+debug_to_has_exited (pid, wait_status, exit_status)
+ int pid;
+ int wait_status;
+ int * exit_status;
+{
+ int has_exited;
+
+ has_exited = debug_target.to_has_exited (pid, wait_status, exit_status);
+
+ fprintf_unfiltered (gdb_stderr, "target_has_exited (%d, %d, %d) = %d\n",
+ pid, wait_status, *exit_status, has_exited);
+
+ return has_exited;
+}
+
+static void
debug_to_mourn_inferior ()
{
debug_target.to_mourn_inferior ();
- fprintf_unfiltered (stderr, "target_mourn_inferior ()\n");
+ fprintf_unfiltered (gdb_stderr, "target_mourn_inferior ()\n");
}
static int
@@ -1764,7 +2390,7 @@ debug_to_can_run ()
retval = debug_target.to_can_run ();
- fprintf_unfiltered (stderr, "target_can_run () = %d\n", retval);
+ fprintf_unfiltered (gdb_stderr, "target_can_run () = %d\n", retval);
return retval;
}
@@ -1775,17 +2401,21 @@ debug_to_notice_signals (pid)
{
debug_target.to_notice_signals (pid);
- fprintf_unfiltered (stderr, "target_notice_signals (%d)\n", pid);
+ fprintf_unfiltered (gdb_stderr, "target_notice_signals (%d)\n", pid);
}
static int
debug_to_thread_alive (pid)
int pid;
{
- debug_target.to_thread_alive (pid);
+ int retval;
+
+ retval = debug_target.to_thread_alive (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_thread_alive (%d) = %d\n",
+ pid, retval);
- fprintf_unfiltered (stderr, "target_thread_alive (%d)\n", pid);
- return (0);
+ return retval;
}
static void
@@ -1793,7 +2423,71 @@ debug_to_stop ()
{
debug_target.to_stop ();
- fprintf_unfiltered (stderr, "target_stop ()\n");
+ fprintf_unfiltered (gdb_stderr, "target_stop ()\n");
+}
+
+static int
+debug_to_query (type, req, resp, siz)
+ int type;
+ char *req;
+ char *resp;
+ int *siz;
+{
+ int retval;
+
+ retval = debug_target.to_query (type, req, resp, siz);
+
+ fprintf_unfiltered (gdb_stderr, "target_query (%c, %s, %s, %d) = %d\n", type, req, resp, *siz, retval);
+
+ return retval;
+}
+
+static struct symtab_and_line *
+debug_to_enable_exception_callback (kind, enable)
+ enum exception_event_kind kind;
+ int enable;
+{
+ debug_target.to_enable_exception_callback (kind, enable);
+
+ fprintf_unfiltered (gdb_stderr,
+ "target get_exception_callback_sal (%d, %d)\n",
+ kind, enable);
+}
+
+static struct exception_event_record *
+debug_to_get_current_exception_event ()
+{
+ debug_target.to_get_current_exception_event();
+
+ fprintf_unfiltered (gdb_stderr, "target get_current_exception_event ()\n");
+}
+
+static char *
+debug_to_pid_to_exec_file (pid)
+ int pid;
+{
+ char * exec_file;
+
+ exec_file = debug_target.to_pid_to_exec_file (pid);
+
+ fprintf_unfiltered (gdb_stderr, "target_pid_to_exec_file (%d) = %s\n",
+ pid, exec_file);
+
+ return exec_file;
+}
+
+static char *
+debug_to_core_file_to_sym_file (core)
+ char * core;
+{
+ char * sym_file;
+
+ sym_file = debug_target.to_core_file_to_sym_file (core);
+
+ fprintf_unfiltered (gdb_stderr, "target_core_file_to_sym_file (%s) = %s\n",
+ core, sym_file);
+
+ return sym_file;
}
static void
@@ -1804,9 +2498,13 @@ setup_target_debug ()
current_target.to_open = debug_to_open;
current_target.to_close = debug_to_close;
current_target.to_attach = debug_to_attach;
+ current_target.to_post_attach = debug_to_post_attach;
+ current_target.to_require_attach = debug_to_require_attach;
current_target.to_detach = debug_to_detach;
+ current_target.to_require_detach = debug_to_require_detach;
current_target.to_resume = debug_to_resume;
current_target.to_wait = debug_to_wait;
+ current_target.to_post_wait = debug_to_post_wait;
current_target.to_fetch_registers = debug_to_fetch_registers;
current_target.to_store_registers = debug_to_store_registers;
current_target.to_prepare_to_store = debug_to_prepare_to_store;
@@ -1823,11 +2521,35 @@ setup_target_debug ()
current_target.to_load = debug_to_load;
current_target.to_lookup_symbol = debug_to_lookup_symbol;
current_target.to_create_inferior = debug_to_create_inferior;
+ current_target.to_post_startup_inferior = debug_to_post_startup_inferior;
+ current_target.to_acknowledge_created_inferior = debug_to_acknowledge_created_inferior;
+ current_target.to_clone_and_follow_inferior = debug_to_clone_and_follow_inferior;
+ current_target.to_post_follow_inferior_by_clone = debug_to_post_follow_inferior_by_clone;
+ current_target.to_insert_fork_catchpoint = debug_to_insert_fork_catchpoint;
+ current_target.to_remove_fork_catchpoint = debug_to_remove_fork_catchpoint;
+ current_target.to_insert_vfork_catchpoint = debug_to_insert_vfork_catchpoint;
+ current_target.to_remove_vfork_catchpoint = debug_to_remove_vfork_catchpoint;
+ current_target.to_has_forked = debug_to_has_forked;
+ current_target.to_has_vforked = debug_to_has_vforked;
+ current_target.to_can_follow_vfork_prior_to_exec = debug_to_can_follow_vfork_prior_to_exec;
+ current_target.to_post_follow_vfork = debug_to_post_follow_vfork;
+ current_target.to_insert_exec_catchpoint = debug_to_insert_exec_catchpoint;
+ current_target.to_remove_exec_catchpoint = debug_to_remove_exec_catchpoint;
+ current_target.to_has_execd = debug_to_has_execd;
+ current_target.to_reported_exec_events_per_exec_call = debug_to_reported_exec_events_per_exec_call;
+ current_target.to_has_syscall_event = debug_to_has_syscall_event;
+ current_target.to_has_exited = debug_to_has_exited;
current_target.to_mourn_inferior = debug_to_mourn_inferior;
current_target.to_can_run = debug_to_can_run;
current_target.to_notice_signals = debug_to_notice_signals;
current_target.to_thread_alive = debug_to_thread_alive;
current_target.to_stop = debug_to_stop;
+ current_target.to_query = debug_to_query;
+ current_target.to_enable_exception_callback = debug_to_enable_exception_callback;
+ current_target.to_get_current_exception_event = debug_to_get_current_exception_event;
+ current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file;
+ current_target.to_core_file_to_sym_file = debug_to_core_file_to_sym_file;
+
}
#endif /* MAINTENANCE_CMDS */
@@ -1839,6 +2561,7 @@ core-file, and process, if any), as well as the symbol file name.";
void
initialize_targets ()
{
+ init_dummy_target ();
push_target (&dummy_target);
add_info ("target", target_info, targ_desc);
diff --git a/contrib/gdb/gdb/target.h b/contrib/gdb/gdb/target.h
index 209faeb..d070f16 100644
--- a/contrib/gdb/gdb/target.h
+++ b/contrib/gdb/gdb/target.h
@@ -1,5 +1,5 @@
/* Interface between GDB and target environments, including files and processes
- Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+ Copyright 1990, 91, 92, 93, 94, 1999 Free Software Foundation, Inc.
Contributed by Cygnus Support. Written by John Gilmore.
This file is part of GDB.
@@ -41,6 +41,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
stratum. */
#include "bfd.h"
+#include "symtab.h"
enum strata {
dummy_stratum, /* The lowest of the low */
@@ -51,6 +52,12 @@ enum strata {
process_stratum /* Executing processes */
};
+enum thread_control_capabilities {
+ tc_none = 0, /* Default: can't control thread execution. */
+ tc_schedlock = 1, /* Can lock the thread scheduler. */
+ tc_switch = 2 /* Can switch the running thread on demand. */
+};
+
/* Stuff for target_wait. */
/* Generally, what has the program done? */
@@ -69,6 +76,27 @@ enum target_waitkind {
(e.g. it called load(2) on AIX). */
TARGET_WAITKIND_LOADED,
+ /* The program has forked. A "related" process' ID is in value.related_pid.
+ I.e., if the child forks, value.related_pid is the parent's ID.
+ */
+ TARGET_WAITKIND_FORKED,
+
+ /* The program has vforked. A "related" process's ID is in value.related_pid.
+ */
+ TARGET_WAITKIND_VFORKED,
+
+ /* The program has exec'ed a new executable file. The new file's pathname
+ is pointed to by value.execd_pathname.
+ */
+ TARGET_WAITKIND_EXECD,
+
+ /* The program has entered or returned from a system call. On HP-UX, this
+ is used in the hardware watchpoint implementation. The syscall's unique
+ integer ID number is in value.syscall_id;
+ */
+ TARGET_WAITKIND_SYSCALL_ENTRY,
+ TARGET_WAITKIND_SYSCALL_RETURN,
+
/* Nothing happened, but we stopped anyway. This perhaps should be handled
within target_wait, but I'm not sure target_wait should be resuming the
inferior. */
@@ -178,7 +206,15 @@ enum target_signal {
TARGET_SIGNAL_REALTIME_61 = 73,
TARGET_SIGNAL_REALTIME_62 = 74,
TARGET_SIGNAL_REALTIME_63 = 75,
-
+#if defined(MACH) || defined(__MACH__)
+ /* Mach exceptions */
+ TARGET_EXC_BAD_ACCESS = 76,
+ TARGET_EXC_BAD_INSTRUCTION = 77,
+ TARGET_EXC_ARITHMETIC = 78,
+ TARGET_EXC_EMULATION = 79,
+ TARGET_EXC_SOFTWARE = 80,
+ TARGET_EXC_BREAKPOINT = 81,
+#endif
/* Some signal we don't know about. */
TARGET_SIGNAL_UNKNOWN,
@@ -193,10 +229,13 @@ enum target_signal {
struct target_waitstatus {
enum target_waitkind kind;
- /* Exit status or signal number. */
+ /* Forked child pid, execd pathname, exit status or signal number. */
union {
int integer;
enum target_signal sig;
+ int related_pid;
+ char * execd_pathname;
+ int syscall_id;
} value;
};
@@ -208,6 +247,7 @@ extern char *target_signal_to_name PARAMS ((enum target_signal));
/* Given a name (SIGHUP, etc.), return its signal. */
enum target_signal target_signal_from_name PARAMS ((char *));
+
/* If certain kinds of activity happen, target_wait should perform
callbacks. */
@@ -227,9 +267,13 @@ struct target_ops
void (*to_open) PARAMS ((char *, int));
void (*to_close) PARAMS ((int));
void (*to_attach) PARAMS ((char *, int));
+ void (*to_post_attach) PARAMS ((int));
+ void (*to_require_attach) PARAMS ((char *, int));
void (*to_detach) PARAMS ((char *, int));
+ void (*to_require_detach) PARAMS ((int, char *, int));
void (*to_resume) PARAMS ((int, int, enum target_signal));
int (*to_wait) PARAMS ((int, struct target_waitstatus *));
+ void (*to_post_wait) PARAMS ((int, int));
void (*to_fetch_registers) PARAMS ((int));
void (*to_store_registers) PARAMS ((int));
void (*to_prepare_to_store) PARAMS ((void));
@@ -289,11 +333,34 @@ struct target_ops
void (*to_load) PARAMS ((char *, int));
int (*to_lookup_symbol) PARAMS ((char *, CORE_ADDR *));
void (*to_create_inferior) PARAMS ((char *, char *, char **));
+ void (*to_post_startup_inferior) PARAMS ((int));
+ void (*to_acknowledge_created_inferior) PARAMS ((int));
+ void (*to_clone_and_follow_inferior) PARAMS ((int, int *));
+ void (*to_post_follow_inferior_by_clone) PARAMS ((void));
+ int (*to_insert_fork_catchpoint) PARAMS ((int));
+ int (*to_remove_fork_catchpoint) PARAMS ((int));
+ int (*to_insert_vfork_catchpoint) PARAMS ((int));
+ int (*to_remove_vfork_catchpoint) PARAMS ((int));
+ int (*to_has_forked) PARAMS ((int, int *));
+ int (*to_has_vforked) PARAMS ((int, int *));
+ int (*to_can_follow_vfork_prior_to_exec) PARAMS ((void));
+ void (*to_post_follow_vfork) PARAMS ((int, int, int, int));
+ int (*to_insert_exec_catchpoint) PARAMS ((int));
+ int (*to_remove_exec_catchpoint) PARAMS ((int));
+ int (*to_has_execd) PARAMS ((int, char **));
+ int (*to_reported_exec_events_per_exec_call) PARAMS ((void));
+ int (*to_has_syscall_event) PARAMS ((int, enum target_waitkind *, int *));
+ int (*to_has_exited) PARAMS ((int, int, int *));
void (*to_mourn_inferior) PARAMS ((void));
int (*to_can_run) PARAMS ((void));
void (*to_notice_signals) PARAMS ((int pid));
int (*to_thread_alive) PARAMS ((int pid));
void (*to_stop) PARAMS ((void));
+ int (*to_query) PARAMS ((int/*char*/, char *, char *, int *));
+ struct symtab_and_line * (*to_enable_exception_callback) PARAMS ((enum exception_event_kind, int));
+ struct exception_event_record * (*to_get_current_exception_event) PARAMS ((void));
+ char * (*to_pid_to_exec_file) PARAMS ((int pid));
+ char * (*to_core_file_to_sym_file) PARAMS ((char *));
enum strata to_stratum;
struct target_ops
*DONT_USE; /* formerly to_next */
@@ -302,6 +369,7 @@ struct target_ops
int to_has_stack;
int to_has_registers;
int to_has_execution;
+ int to_has_thread_control; /* control thread execution */
struct section_table
*to_sections;
struct section_table
@@ -366,6 +434,26 @@ extern struct target_stack_item *target_stack;
#define target_attach(args, from_tty) \
(*current_target.to_attach) (args, from_tty)
+/* The target_attach operation places a process under debugger control,
+ and stops the process.
+
+ This operation provides a target-specific hook that allows the
+ necessary bookkeeping to be performed after an attach completes.
+ */
+#define target_post_attach(pid) \
+ (*current_target.to_post_attach) (pid)
+
+/* Attaches to a process on the target side, if not already attached.
+ (If already attached, takes no action.)
+
+ This operation can be used to follow the child process of a fork.
+ On some targets, such child processes of an original inferior process
+ are automatically under debugger control, and thus do not require an
+ actual attach operation. */
+
+#define target_require_attach(args, from_tty) \
+ (*current_target.to_require_attach) (args, from_tty)
+
/* Takes a program previously attached to and detaches it.
The program may resume execution (some targets do, some don't) and will
no longer stop on signals, etc. We better not have left any breakpoints
@@ -376,6 +464,21 @@ extern struct target_stack_item *target_stack;
extern void
target_detach PARAMS ((char *, int));
+/* Detaches from a process on the target side, if not already dettached.
+ (If already detached, takes no action.)
+
+ This operation can be used to follow the parent process of a fork.
+ On some targets, such child processes of an original inferior process
+ are automatically under debugger control, and thus do require an actual
+ detach operation.
+
+ PID is the process id of the child to detach from.
+ ARGS is arguments typed by the user (e.g. a signal to send the process).
+ FROM_TTY says whether to be verbose or not. */
+
+#define target_require_detach(pid, args, from_tty) \
+ (*current_target.to_require_detach) (pid, args, from_tty)
+
/* Resume execution of the target process PID. STEP says whether to
single-step or to run free; SIGGNAL is the signal to be given to
the target, or TARGET_SIGNAL_0 for no signal. The caller may not
@@ -395,6 +498,20 @@ target_detach PARAMS ((char *, int));
#define target_wait(pid, status) \
(*current_target.to_wait) (pid, status)
+/* The target_wait operation waits for a process event to occur, and
+ thereby stop the process.
+
+ On some targets, certain events may happen in sequences. gdb's
+ correct response to any single event of such a sequence may require
+ knowledge of what earlier events in the sequence have been seen.
+
+ This operation provides a target-specific hook that allows the
+ necessary bookkeeping to be performed to track such sequences.
+ */
+
+#define target_post_wait(pid, status) \
+ (*current_target.to_post_wait) (pid, status)
+
/* Fetch register REGNO, or all regs if regno == -1. No result. */
#define target_fetch_registers(regno) \
@@ -419,7 +536,11 @@ target_detach PARAMS ((char *, int));
extern int target_read_string PARAMS ((CORE_ADDR, char **, int, int *));
extern int
-target_read_memory PARAMS ((CORE_ADDR, char *, int));
+target_read_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len));
+
+extern int
+target_read_memory_section PARAMS ((CORE_ADDR memaddr, char *myaddr, int len,
+ asection *bfd_section));
extern int
target_read_memory_partial PARAMS ((CORE_ADDR, char *, int, int *));
@@ -433,13 +554,79 @@ xfer_memory PARAMS ((CORE_ADDR, char *, int, int, struct target_ops *));
extern int
child_xfer_memory PARAMS ((CORE_ADDR, char *, int, int, struct target_ops *));
-/* Transfer LEN bytes between target address MEMADDR and GDB address MYADDR.
- Returns 0 for success, errno code for failure (which includes partial
- transfers--if you want a more useful response to partial transfers, try
- target_read_memory_partial). */
+extern char *
+child_pid_to_exec_file PARAMS ((int));
+
+extern char *
+child_core_file_to_sym_file PARAMS ((char *));
+
+#if defined(CHILD_POST_ATTACH)
+extern void
+child_post_attach PARAMS ((int));
+#endif
+
+extern void
+child_post_wait PARAMS ((int, int));
+
+extern void
+child_post_startup_inferior PARAMS ((int));
+
+extern void
+child_acknowledge_created_inferior PARAMS ((int));
+
+extern void
+child_clone_and_follow_inferior PARAMS ((int, int *));
+
+extern void
+child_post_follow_inferior_by_clone PARAMS ((void));
+
+extern int
+child_insert_fork_catchpoint PARAMS ((int));
+
+extern int
+child_remove_fork_catchpoint PARAMS ((int));
+
+extern int
+child_insert_vfork_catchpoint PARAMS ((int));
+
+extern int
+child_remove_vfork_catchpoint PARAMS ((int));
+
+extern int
+child_has_forked PARAMS ((int, int *));
+
+extern int
+child_has_vforked PARAMS ((int, int *));
+
+extern void
+child_acknowledge_created_inferior PARAMS ((int));
+
+extern int
+child_can_follow_vfork_prior_to_exec PARAMS ((void));
+
+extern void
+child_post_follow_vfork PARAMS ((int, int, int, int));
+
+extern int
+child_insert_exec_catchpoint PARAMS ((int));
+
+extern int
+child_remove_exec_catchpoint PARAMS ((int));
+
+extern int
+child_has_execd PARAMS ((int, char **));
+
+extern int
+child_reported_exec_events_per_exec_call PARAMS ((void));
+
+extern int
+child_has_syscall_event PARAMS ((int, enum target_waitkind *, int *));
+
+extern int
+child_has_exited PARAMS ((int, int, int *));
-extern int target_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
- int len, int write));
+extern int
+child_thread_alive PARAMS ((int));
/* From exec.c */
@@ -536,6 +723,149 @@ print_section_info PARAMS ((struct target_ops *, bfd *));
#define target_create_inferior(exec_file, args, env) \
(*current_target.to_create_inferior) (exec_file, args, env)
+
+/* Some targets (such as ttrace-based HPUX) don't allow us to request
+ notification of inferior events such as fork and vork immediately
+ after the inferior is created. (This because of how gdb gets an
+ inferior created via invoking a shell to do it. In such a scenario,
+ if the shell init file has commands in it, the shell will fork and
+ exec for each of those commands, and we will see each such fork
+ event. Very bad.)
+
+ Such targets will supply an appropriate definition for this function.
+ */
+#define target_post_startup_inferior(pid) \
+ (*current_target.to_post_startup_inferior) (pid)
+
+/* On some targets, the sequence of starting up an inferior requires
+ some synchronization between gdb and the new inferior process, PID.
+ */
+#define target_acknowledge_created_inferior(pid) \
+ (*current_target.to_acknowledge_created_inferior) (pid)
+
+/* An inferior process has been created via a fork() or similar
+ system call. This function will clone the debugger, then ensure
+ that CHILD_PID is attached to by that debugger.
+
+ FOLLOWED_CHILD is set TRUE on return *for the clone debugger only*,
+ and FALSE otherwise. (The original and clone debuggers can use this
+ to determine which they are, if need be.)
+
+ (This is not a terribly useful feature without a GUI to prevent
+ the two debuggers from competing for shell input.)
+ */
+#define target_clone_and_follow_inferior(child_pid,followed_child) \
+ (*current_target.to_clone_and_follow_inferior) (child_pid, followed_child)
+
+/* This operation is intended to be used as the last in a sequence of
+ steps taken when following both parent and child of a fork. This
+ is used by a clone of the debugger, which will follow the child.
+
+ The original debugger has detached from this process, and the
+ clone has attached to it.
+
+ On some targets, this requires a bit of cleanup to make it work
+ correctly.
+ */
+#define target_post_follow_inferior_by_clone() \
+ (*current_target.to_post_follow_inferior_by_clone) ()
+
+/* On some targets, we can catch an inferior fork or vfork event when it
+ occurs. These functions insert/remove an already-created catchpoint for
+ such events.
+ */
+#define target_insert_fork_catchpoint(pid) \
+ (*current_target.to_insert_fork_catchpoint) (pid)
+
+#define target_remove_fork_catchpoint(pid) \
+ (*current_target.to_remove_fork_catchpoint) (pid)
+
+#define target_insert_vfork_catchpoint(pid) \
+ (*current_target.to_insert_vfork_catchpoint) (pid)
+
+#define target_remove_vfork_catchpoint(pid) \
+ (*current_target.to_remove_vfork_catchpoint) (pid)
+
+/* Returns TRUE if PID has invoked the fork() system call. And,
+ also sets CHILD_PID to the process id of the other ("child")
+ inferior process that was created by that call.
+ */
+#define target_has_forked(pid,child_pid) \
+ (*current_target.to_has_forked) (pid,child_pid)
+
+/* Returns TRUE if PID has invoked the vfork() system call. And,
+ also sets CHILD_PID to the process id of the other ("child")
+ inferior process that was created by that call.
+ */
+#define target_has_vforked(pid,child_pid) \
+ (*current_target.to_has_vforked) (pid,child_pid)
+
+/* Some platforms (such as pre-10.20 HP-UX) don't allow us to do
+ anything to a vforked child before it subsequently calls exec().
+ On such platforms, we say that the debugger cannot "follow" the
+ child until it has vforked.
+
+ This function should be defined to return 1 by those targets
+ which can allow the debugger to immediately follow a vforked
+ child, and 0 if they cannot.
+ */
+#define target_can_follow_vfork_prior_to_exec() \
+ (*current_target.to_can_follow_vfork_prior_to_exec) ()
+
+/* An inferior process has been created via a vfork() system call.
+ The debugger has followed the parent, the child, or both. The
+ process of setting up for that follow may have required some
+ target-specific trickery to track the sequence of reported events.
+ If so, this function should be defined by those targets that
+ require the debugger to perform cleanup or initialization after
+ the vfork follow.
+ */
+#define target_post_follow_vfork(parent_pid,followed_parent,child_pid,followed_child) \
+ (*current_target.to_post_follow_vfork) (parent_pid,followed_parent,child_pid,followed_child)
+
+/* On some targets, we can catch an inferior exec event when it
+ occurs. These functions insert/remove an already-created catchpoint
+ for such events.
+ */
+#define target_insert_exec_catchpoint(pid) \
+ (*current_target.to_insert_exec_catchpoint) (pid)
+
+#define target_remove_exec_catchpoint(pid) \
+ (*current_target.to_remove_exec_catchpoint) (pid)
+
+/* Returns TRUE if PID has invoked a flavor of the exec() system call.
+ And, also sets EXECD_PATHNAME to the pathname of the executable file
+ that was passed to exec(), and is now being executed.
+ */
+#define target_has_execd(pid,execd_pathname) \
+ (*current_target.to_has_execd) (pid,execd_pathname)
+
+/* Returns the number of exec events that are reported when a process
+ invokes a flavor of the exec() system call on this target, if exec
+ events are being reported.
+ */
+#define target_reported_exec_events_per_exec_call() \
+ (*current_target.to_reported_exec_events_per_exec_call) ()
+
+/* Returns TRUE if PID has reported a syscall event. And, also sets
+ KIND to the appropriate TARGET_WAITKIND_, and sets SYSCALL_ID to
+ the unique integer ID of the syscall.
+ */
+#define target_has_syscall_event(pid,kind,syscall_id) \
+ (*current_target.to_has_syscall_event) (pid,kind,syscall_id)
+
+/* Returns TRUE if PID has exited. And, also sets EXIT_STATUS to the
+ exit code of PID, if any.
+ */
+#define target_has_exited(pid,wait_status,exit_status) \
+ (*current_target.to_has_exited) (pid,wait_status,exit_status)
+
+/* The debugger has completed a blocking wait() call. There is now
+ some process event that must be processed. This function should
+ be defined by those targets that require the debugger to perform
+ cleanup or internal state changes in response to the process event.
+ */
+
/* The inferior process has died. Do what is right. */
#define target_mourn_inferior() \
@@ -560,7 +890,32 @@ print_section_info PARAMS ((struct target_ops *, bfd *));
should act like SIGSTOP). This function is normally used by GUIs to
implement a stop button. */
-#define target_stop() current_target.to_stop ()
+#define target_stop current_target.to_stop
+
+/* Queries the target side for some information. The first argument is a
+ letter specifying the type of the query, which is used to determine who
+ should process it. The second argument is a string that specifies which
+ information is desired and the third is a buffer that carries back the
+ response from the target side. The fourth parameter is the size of the
+ output buffer supplied. */
+
+#define target_query(query_type, query, resp_buffer, bufffer_size) \
+ (*current_target.to_query) (query_type, query, resp_buffer, bufffer_size)
+
+/* Get the symbol information for a breakpointable routine called when
+ an exception event occurs.
+ Intended mainly for C++, and for those
+ platforms/implementations where such a callback mechanism is available,
+ e.g. HP-UX with ANSI C++ (aCC). Some compilers (e.g. g++) support
+ different mechanisms for debugging exceptions. */
+
+#define target_enable_exception_callback(kind, enable) \
+ (*current_target.to_enable_exception_callback) (kind, enable)
+
+/* Get the current exception event kind -- throw or catch, etc. */
+
+#define target_get_current_exception_event() \
+ (*current_target.to_get_current_exception_event) ()
/* Pointer to next target in the chain, e.g. a core file and an exec file. */
@@ -600,6 +955,16 @@ print_section_info PARAMS ((struct target_ops *, bfd *));
#define target_has_execution \
(current_target.to_has_execution)
+/* Can the target support the debugger control of thread execution?
+ a) Can it lock the thread scheduler?
+ b) Can it switch the currently running thread? */
+
+#define target_can_lock_scheduler \
+ (current_target.to_has_thread_control & tc_schedlock)
+
+#define target_can_switch_threads \
+ (current_target.to_has_thread_control & tc_switch)
+
extern void target_link PARAMS ((char *, CORE_ADDR *));
/* Converts a process id to a string. Usually, the string just contains
@@ -612,6 +977,38 @@ extern void target_link PARAMS ((char *, CORE_ADDR *));
extern char *normal_pid_to_str PARAMS ((int pid));
#endif
+#ifndef target_tid_to_str
+#define target_tid_to_str(PID) \
+ normal_pid_to_str (PID)
+extern char *normal_pid_to_str PARAMS ((int pid));
+#endif
+
+
+#ifndef target_new_objfile
+#define target_new_objfile(OBJFILE)
+#endif
+
+#ifndef target_pid_or_tid_to_str
+#define target_pid_or_tid_to_str(ID) \
+ normal_pid_to_str (ID)
+#endif
+
+/* Attempts to find the pathname of the executable file
+ that was run to create a specified process.
+
+ The process PID must be stopped when this operation is used.
+
+ If the executable file cannot be determined, NULL is returned.
+
+ Else, a pointer to a character string containing the pathname
+ is returned. This string should be copied into a buffer by
+ the client if the string will not be immediately used, or if
+ it must persist.
+ */
+
+#define target_pid_to_exec_file(pid) \
+ (current_target.to_pid_to_exec_file) (pid)
+
/* Hook to call target-dependant code after reading in a new symbol table. */
#ifndef TARGET_SYMFILE_POSTREAD
@@ -634,6 +1031,18 @@ extern char *normal_pid_to_str PARAMS ((int pid));
#define STOPPED_BY_WATCHPOINT(w) 0
#endif
+/* HP-UX supplies these operations, which respectively disable and enable
+ the memory page-protections that are used to implement hardware watchpoints
+ on that platform. See wait_for_inferior's use of these.
+ */
+#if !defined(TARGET_DISABLE_HW_WATCHPOINTS)
+#define TARGET_DISABLE_HW_WATCHPOINTS(pid)
+#endif
+
+#if !defined(TARGET_ENABLE_HW_WATCHPOINTS)
+#define TARGET_ENABLE_HW_WATCHPOINTS(pid)
+#endif
+
/* Provide defaults for systems that don't support hardware watchpoints. */
#ifndef TARGET_HAS_HARDWARE_WATCHPOINTS
@@ -645,9 +1054,26 @@ extern char *normal_pid_to_str PARAMS ((int pid));
#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(TYPE,CNT,OTHERTYPE) 0
-/* Set/clear a hardware watchpoint starting at ADDR, for LEN bytes. TYPE is 1
- for read and 2 for read/write accesses. Returns 0 for success, non-zero for
- failure. */
+#if !defined(TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT)
+#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(byte_count) \
+ (LONGEST)(byte_count) <= REGISTER_SIZE
+#endif
+
+/* However, some addresses may not be profitable to use hardware to watch,
+ or may be difficult to understand when the addressed object is out of
+ scope, and hence should be unwatched. On some targets, this may have
+ severe performance penalties, such that we might as well use regular
+ watchpoints, and save (possibly precious) hardware watchpoints for other
+ locations.
+ */
+#if !defined(TARGET_RANGE_PROFITABLE_FOR_HW_WATCHPOINT)
+#define TARGET_RANGE_PROFITABLE_FOR_HW_WATCHPOINT(pid,start,len) 0
+#endif
+
+
+/* Set/clear a hardware watchpoint starting at ADDR, for LEN bytes. TYPE is 0
+ for write, 1 for read, and 2 for read/write accesses. Returns 0 for
+ success, non-zero for failure. */
#define target_remove_watchpoint(ADDR,LEN,TYPE) -1
#define target_insert_watchpoint(ADDR,LEN,TYPE) -1
@@ -670,6 +1096,38 @@ extern char *normal_pid_to_str PARAMS ((int pid));
#define DECR_PC_AFTER_HW_BREAK 0
#endif
+/* Sometimes gdb may pick up what appears to be a valid target address
+ from a minimal symbol, but the value really means, essentially,
+ "This is an index into a table which is populated when the inferior
+ is run. Therefore, do not attempt to use this as a PC."
+ */
+#if !defined(PC_REQUIRES_RUN_BEFORE_USE)
+#define PC_REQUIRES_RUN_BEFORE_USE(pc) (0)
+#endif
+
+/* This will only be defined by a target that supports catching vfork events,
+ such as HP-UX.
+
+ On some targets (such as HP-UX 10.20 and earlier), resuming a newly vforked
+ child process after it has exec'd, causes the parent process to resume as
+ well. To prevent the parent from running spontaneously, such targets should
+ define this to a function that prevents that from happening.
+ */
+#if !defined(ENSURE_VFORKING_PARENT_REMAINS_STOPPED)
+#define ENSURE_VFORKING_PARENT_REMAINS_STOPPED(PID) (0)
+#endif
+
+/* This will only be defined by a target that supports catching vfork events,
+ such as HP-UX.
+
+ On some targets (such as HP-UX 10.20 and earlier), a newly vforked child
+ process must be resumed when it delivers its exec event, before the parent
+ vfork event will be delivered to us.
+ */
+#if !defined(RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK)
+#define RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK() (0)
+#endif
+
/* Routines for maintenance of the target structures...
add_target: Add a target to the list of all possible targets.
@@ -722,24 +1180,40 @@ build_section_table PARAMS ((bfd *, struct section_table **,
/* From mem-break.c */
-extern int
-memory_remove_breakpoint PARAMS ((CORE_ADDR, char *));
+extern int memory_remove_breakpoint PARAMS ((CORE_ADDR, char *));
+
+extern int memory_insert_breakpoint PARAMS ((CORE_ADDR, char *));
+
+extern breakpoint_from_pc_fn memory_breakpoint_from_pc;
+#ifndef BREAKPOINT_FROM_PC
+#define BREAKPOINT_FROM_PC(pcptr, lenptr) memory_breakpoint_from_pc (pcptr, lenptr)
+#endif
-extern int
-memory_insert_breakpoint PARAMS ((CORE_ADDR, char *));
/* From target.c */
-void
+extern void
+initialize_targets PARAMS ((void));
+
+extern void
noprocess PARAMS ((void));
-void
+extern void
find_default_attach PARAMS ((char *, int));
void
+find_default_require_attach PARAMS ((char *, int));
+
+void
+find_default_require_detach PARAMS ((int, char *, int));
+
+extern void
find_default_create_inferior PARAMS ((char *, char *, char **));
-struct target_ops *
+void
+find_default_clone_and_follow_inferior PARAMS ((int, int *));
+
+extern struct target_ops *
find_core_target PARAMS ((void));
/* Stuff that should be shared among the various remote targets. */
@@ -750,6 +1224,10 @@ extern int remote_debug;
/* Speed in bits per second, or -1 which means don't mess with the speed. */
extern int baud_rate;
+/* Timeout limit for response from target. */
+extern int remote_timeout;
+
+extern asection *target_memory_bfd_section;
/* Functions for helping to write a native target. */
@@ -763,4 +1241,25 @@ extern int target_signal_to_host PARAMS ((enum target_signal));
/* Convert from a number used in a GDB command to an enum target_signal. */
extern enum target_signal target_signal_from_command PARAMS ((int));
+/* Any target can call this to switch to remote protocol (in remote.c). */
+extern void push_remote_target PARAMS ((char *name, int from_tty));
+
+/* Imported from machine dependent code */
+
+#ifndef SOFTWARE_SINGLE_STEP_P
+#define SOFTWARE_SINGLE_STEP_P 0
+#define SOFTWARE_SINGLE_STEP(sig,bp_p) abort ()
+#endif /* SOFTWARE_SINGLE_STEP_P */
+
+/* Blank target vector entries are initialized to target_ignore. */
+void target_ignore PARAMS ((void));
+
+/* Macro for getting target's idea of a frame pointer.
+ FIXME: GDB's whole scheme for dealing with "frames" and
+ "frame pointers" needs a serious shakedown. */
+#ifndef TARGET_VIRTUAL_FRAME_POINTER
+#define TARGET_VIRTUAL_FRAME_POINTER(ADDR, REGP, OFFP) \
+ do { *(REGP) = FP_REGNUM; *(OFFP) = 0; } while (0)
+#endif /* TARGET_VIRTUAL_FRAME_POINTER */
+
#endif /* !defined (TARGET_H) */
diff --git a/contrib/gdb/gdb/thread.c b/contrib/gdb/gdb/thread.c
index 6a7ab09..d07401a 100644
--- a/contrib/gdb/gdb/thread.c
+++ b/contrib/gdb/gdb/thread.c
@@ -548,7 +548,7 @@ thread_apply_all_command (cmd, from_tty)
error ("Please specify a command following the thread ID list");
old_chain = make_cleanup ((make_cleanup_func) restore_current_thread,
- (void *) inferior_pid);
+ (void *)(long) inferior_pid);
for (tp = thread_list; tp; tp = tp->next)
if (thread_alive (tp))
@@ -584,7 +584,7 @@ thread_apply_command (tidlist, from_tty)
error ("Please specify a command following the thread ID list");
old_chain = make_cleanup ((make_cleanup_func) restore_current_thread,
- (void *) inferior_pid);
+ (void *)(long) inferior_pid);
while (tidlist < cmd)
{
OpenPOWER on IntegriCloud