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:
parent
2887baec7d
commit
edc87f7d43
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=46289
@ -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)
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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
@ -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
|
||||
|
@ -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\
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 *) ®isters[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 *) ®isters[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 *) ®isters[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)
|
||||
{
|
||||
|
@ -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"
|
||||
|
@ -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 *) §ion, 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. */
|
||||
|
@ -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
@ -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
|
||||
|
@ -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
@ -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
@ -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) */
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user