1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-11 09:50:12 +00:00

Merge local changes into gdb-4.18 and add changes for FreeBSD/alpha.

This commit is contained in:
Doug Rabson 1999-05-02 11:25:35 +00:00
parent 2887baec7d
commit edc87f7d43
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=46289
26 changed files with 7512 additions and 1804 deletions

View File

@ -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)

View File

@ -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. */

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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>

View File

@ -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
}

File diff suppressed because it is too large Load Diff

View File

@ -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 GNU linker and the Sun (both SunOS4 and Solaris) linker are the only
ones 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.
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

View File

@ -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
_initialize_exec()
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 ()
{
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\

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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 one register. */
static void
store_register (regno)
int regno;
{
/* This isn't really an address. But ptrace thinks of it as one. */
CORE_ADDR regaddr;
char mess[128]; /* For messages */
register int i;
unsigned int offset; /* Offset of registers within the u area. */
if (CANNOT_STORE_REGISTER (regno))
{
return;
}
offset = U_REGS_OFFSET;
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)
{
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 -1, do this for all registers.
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;
{
/* This isn't really an address. But ptrace thinks of it as one. */
CORE_ADDR regaddr;
char buf[80];
register int i, numregs;
unsigned int offset = U_REGS_OFFSET;
if (regno >= 0)
{
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);
}
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)
{

View File

@ -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"

View File

@ -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);
/* Build section table. */
if (build_objfile_section_table (objfile))
if (abfd != NULL)
{
error ("Can't find the file sections in `%s': %s",
objfile -> name, bfd_errmsg (bfd_get_error ()));
objfile -> name = mstrsave (objfile -> md, bfd_get_filename (abfd));
objfile -> mtime = bfd_get_mtime (abfd);
/* 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 ()));
}
}
/* 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. */

View File

@ -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:

File diff suppressed because it is too large Load Diff

View File

@ -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)
{
status = wait_for (scb, timeout);
#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;
}
@ -590,6 +655,9 @@ baudtab[] =
#endif
#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

View File

@ -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,11 +150,19 @@ 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 *));
@ -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 @@ enable_break ()
}
/* 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 */
}

File diff suppressed because it is too large Load Diff

View File

@ -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. */

File diff suppressed because it is too large Load Diff

View File

@ -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 int target_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
int len, int write));
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
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) */

View File

@ -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)
{