mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Update to GDB 6.1.1. These files are identical to the vendor branch.
This commit is contained in:
parent
cafb9261fd
commit
c07ff117d2
29 changed files with 17963 additions and 10565 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
/* Read coff symbol tables and convert to internal format, for GDB.
|
||||
Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
|
||||
1997, 1998, 1999, 2000, 2001, 2002
|
||||
1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
|
||||
|
||||
|
|
@ -28,15 +28,13 @@
|
|||
#include "breakpoint.h"
|
||||
|
||||
#include "bfd.h"
|
||||
#include "obstack.h"
|
||||
#include "gdb_obstack.h"
|
||||
|
||||
#include "gdb_string.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#include "coff/internal.h" /* Internal format of COFF symbols in BFD */
|
||||
#include "libcoff.h" /* FIXME secret internal data from BFD */
|
||||
|
||||
#include "symfile.h"
|
||||
#include "objfiles.h"
|
||||
#include "buildsym.h"
|
||||
#include "gdb-stabs.h"
|
||||
|
|
@ -44,6 +42,10 @@
|
|||
#include "complaints.h"
|
||||
#include "target.h"
|
||||
#include "gdb_assert.h"
|
||||
#include "block.h"
|
||||
#include "dictionary.h"
|
||||
|
||||
#include "coff-pe-read.h"
|
||||
|
||||
extern void _initialize_coffread (void);
|
||||
|
||||
|
|
@ -122,41 +124,6 @@ static int pe_file;
|
|||
|
||||
static struct symbol *opaque_type_chain[HASHSIZE];
|
||||
|
||||
/* Complaints about various problems in the file being read */
|
||||
|
||||
struct complaint ef_complaint =
|
||||
{"Unmatched .ef symbol(s) ignored starting at symnum %d", 0, 0};
|
||||
|
||||
struct complaint ef_stack_complaint =
|
||||
{"`.ef' symbol without matching `.bf' symbol ignored starting at symnum %d", 0, 0};
|
||||
|
||||
struct complaint eb_stack_complaint =
|
||||
{"`.eb' symbol without matching `.bb' symbol ignored starting at symnum %d", 0, 0};
|
||||
|
||||
struct complaint bf_no_aux_complaint =
|
||||
{"`.bf' symbol %d has no aux entry", 0, 0};
|
||||
|
||||
struct complaint ef_no_aux_complaint =
|
||||
{"`.ef' symbol %d has no aux entry", 0, 0};
|
||||
|
||||
struct complaint lineno_complaint =
|
||||
{"Line number pointer %d lower than start of line numbers", 0, 0};
|
||||
|
||||
struct complaint unexpected_type_complaint =
|
||||
{"Unexpected type for symbol %s", 0, 0};
|
||||
|
||||
struct complaint bad_sclass_complaint =
|
||||
{"Bad n_sclass for symbol %s", 0, 0};
|
||||
|
||||
struct complaint misordered_blocks_complaint =
|
||||
{"Blocks out of order at address %x", 0, 0};
|
||||
|
||||
struct complaint tagndx_bad_complaint =
|
||||
{"Symbol table entry for %s has bad tagndx value", 0, 0};
|
||||
|
||||
struct complaint eb_complaint =
|
||||
{"Mismatched .eb symbol ignored starting at symnum %d", 0, 0};
|
||||
|
||||
/* Simplified internal version of coff symbol table information */
|
||||
|
||||
struct coff_symbol
|
||||
|
|
@ -228,12 +195,12 @@ static void coff_symtab_read (long, unsigned int, struct objfile *);
|
|||
static void
|
||||
coff_locate_sections (bfd *abfd, asection *sectp, void *csip)
|
||||
{
|
||||
register struct coff_symfile_info *csi;
|
||||
struct coff_symfile_info *csi;
|
||||
const char *name;
|
||||
|
||||
csi = (struct coff_symfile_info *) csip;
|
||||
name = bfd_get_section_name (abfd, sectp);
|
||||
if (STREQ (name, ".text"))
|
||||
if (DEPRECATED_STREQ (name, ".text"))
|
||||
{
|
||||
csi->textaddr = bfd_section_vma (abfd, sectp);
|
||||
csi->textsize += bfd_section_size (abfd, sectp);
|
||||
|
|
@ -242,7 +209,7 @@ coff_locate_sections (bfd *abfd, asection *sectp, void *csip)
|
|||
{
|
||||
csi->textsize += bfd_section_size (abfd, sectp);
|
||||
}
|
||||
else if (STREQ (name, ".stabstr"))
|
||||
else if (DEPRECATED_STREQ (name, ".stabstr"))
|
||||
{
|
||||
csi->stabstrsect = sectp;
|
||||
}
|
||||
|
|
@ -344,7 +311,7 @@ cs_section_address (struct coff_symbol *cs, bfd *abfd)
|
|||
or for associating a new type with the index. */
|
||||
|
||||
static struct type **
|
||||
coff_lookup_type (register int index)
|
||||
coff_lookup_type (int index)
|
||||
{
|
||||
if (index >= type_vector_length)
|
||||
{
|
||||
|
|
@ -370,8 +337,8 @@ coff_lookup_type (register int index)
|
|||
static struct type *
|
||||
coff_alloc_type (int index)
|
||||
{
|
||||
register struct type **type_addr = coff_lookup_type (index);
|
||||
register struct type *type = *type_addr;
|
||||
struct type **type_addr = coff_lookup_type (index);
|
||||
struct type *type = *type_addr;
|
||||
|
||||
/* If we are referring to a type not known at all yet,
|
||||
allocate an empty type for it.
|
||||
|
|
@ -422,8 +389,8 @@ complete_symtab (char *name, CORE_ADDR start_addr, unsigned int size)
|
|||
if (current_objfile->ei.entry_point >= current_source_start_addr &&
|
||||
current_objfile->ei.entry_point < current_source_end_addr)
|
||||
{
|
||||
current_objfile->ei.entry_file_lowpc = current_source_start_addr;
|
||||
current_objfile->ei.entry_file_highpc = current_source_end_addr;
|
||||
current_objfile->ei.deprecated_entry_file_lowpc = current_source_start_addr;
|
||||
current_objfile->ei.deprecated_entry_file_highpc = current_source_end_addr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -500,9 +467,8 @@ coff_symfile_init (struct objfile *objfile)
|
|||
of the line table (minimum and maximum file offset) so that the
|
||||
mainline code can read the whole thing for efficiency. */
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
find_linenos (bfd *abfd, sec_ptr asect, void *vpinfo)
|
||||
find_linenos (bfd *abfd, struct bfd_section *asect, void *vpinfo)
|
||||
{
|
||||
struct coff_symfile_info *info;
|
||||
int size, count;
|
||||
|
|
@ -537,7 +503,6 @@ static bfd *symfile_bfd;
|
|||
|
||||
/* Read a symbol file, after initialization by coff_symfile_init. */
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
coff_symfile_read (struct objfile *objfile, int mainline)
|
||||
{
|
||||
|
|
@ -546,11 +511,11 @@ coff_symfile_read (struct objfile *objfile, int mainline)
|
|||
bfd *abfd = objfile->obfd;
|
||||
coff_data_type *cdata = coff_data (abfd);
|
||||
char *name = bfd_get_filename (abfd);
|
||||
register int val;
|
||||
int val;
|
||||
unsigned int num_symbols;
|
||||
int symtab_offset;
|
||||
int stringtab_offset;
|
||||
struct cleanup *back_to;
|
||||
struct cleanup *back_to, *cleanup_minimal_symbols;
|
||||
int stabstrsize;
|
||||
int len;
|
||||
char * target;
|
||||
|
|
@ -593,16 +558,34 @@ coff_symfile_read (struct objfile *objfile, int mainline)
|
|||
|
||||
/* End of warning */
|
||||
|
||||
/* Read the line number table, all at once. */
|
||||
info->min_lineno_offset = 0;
|
||||
info->max_lineno_offset = 0;
|
||||
bfd_map_over_sections (abfd, find_linenos, (void *) info);
|
||||
|
||||
make_cleanup (free_linetab_cleanup, 0 /*ignore*/);
|
||||
val = init_lineno (abfd, info->min_lineno_offset,
|
||||
info->max_lineno_offset - info->min_lineno_offset);
|
||||
if (val < 0)
|
||||
error ("\"%s\": error reading line numbers\n", name);
|
||||
/* Only read line number information if we have symbols.
|
||||
|
||||
On Windows NT, some of the system's DLL's have sections with
|
||||
PointerToLinenumbers fields that are non-zero, but point at
|
||||
random places within the image file. (In the case I found,
|
||||
KERNEL32.DLL's .text section has a line number info pointer that
|
||||
points into the middle of the string `lib\\i386\kernel32.dll'.)
|
||||
|
||||
However, these DLL's also have no symbols. The line number
|
||||
tables are meaningless without symbols. And in fact, GDB never
|
||||
uses the line number information unless there are symbols. So we
|
||||
can avoid spurious error messages (and maybe run a little
|
||||
faster!) by not even reading the line number table unless we have
|
||||
symbols. */
|
||||
if (num_symbols > 0)
|
||||
{
|
||||
/* Read the line number table, all at once. */
|
||||
bfd_map_over_sections (abfd, find_linenos, (void *) info);
|
||||
|
||||
make_cleanup (free_linetab_cleanup, 0 /*ignore*/);
|
||||
val = init_lineno (abfd, info->min_lineno_offset,
|
||||
info->max_lineno_offset - info->min_lineno_offset);
|
||||
if (val < 0)
|
||||
error ("\"%s\": error reading line numbers\n", name);
|
||||
}
|
||||
|
||||
/* Now read the string table, all at once. */
|
||||
|
||||
|
|
@ -612,27 +595,21 @@ coff_symfile_read (struct objfile *objfile, int mainline)
|
|||
error ("\"%s\": can't get string table", name);
|
||||
|
||||
init_minimal_symbol_collection ();
|
||||
make_cleanup_discard_minimal_symbols ();
|
||||
cleanup_minimal_symbols = make_cleanup_discard_minimal_symbols ();
|
||||
|
||||
/* Now that the executable file is positioned at symbol table,
|
||||
process it and define symbols accordingly. */
|
||||
|
||||
coff_symtab_read ((long) symtab_offset, num_symbols, objfile);
|
||||
|
||||
/* Sort symbols alphabetically within each block. */
|
||||
|
||||
{
|
||||
struct symtab *s;
|
||||
|
||||
for (s = objfile->symtabs; s != NULL; s = s->next)
|
||||
sort_symtab_syms (s);
|
||||
}
|
||||
|
||||
/* Install any minimal symbols that have been collected as the current
|
||||
minimal symbols for this objfile. */
|
||||
|
||||
install_minimal_symbols (objfile);
|
||||
|
||||
/* Free the installed minimal symbol data. */
|
||||
do_cleanups (cleanup_minimal_symbols);
|
||||
|
||||
bfd_map_over_sections (abfd, coff_locate_sections, (void *) info);
|
||||
|
||||
if (info->stabsects)
|
||||
|
|
@ -698,9 +675,9 @@ static void
|
|||
coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
||||
struct objfile *objfile)
|
||||
{
|
||||
register struct context_stack *new;
|
||||
struct context_stack *new;
|
||||
struct coff_symbol coff_symbol;
|
||||
register struct coff_symbol *cs = &coff_symbol;
|
||||
struct coff_symbol *cs = &coff_symbol;
|
||||
static struct internal_syment main_sym;
|
||||
static union internal_auxent main_aux;
|
||||
struct coff_symbol fcn_cs_saved;
|
||||
|
|
@ -803,7 +780,8 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
|||
case C_LINE:
|
||||
case C_ALIAS:
|
||||
case C_HIDDEN:
|
||||
complain (&bad_sclass_complaint, cs->c_name);
|
||||
complaint (&symfile_complaints, "Bad n_sclass for symbol %s",
|
||||
cs->c_name);
|
||||
break;
|
||||
|
||||
case C_FILE:
|
||||
|
|
@ -839,7 +817,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
|||
case C_THUMBSTATFUNC:
|
||||
if (cs->c_name[0] == '.')
|
||||
{
|
||||
if (STREQ (cs->c_name, ".text"))
|
||||
if (DEPRECATED_STREQ (cs->c_name, ".text"))
|
||||
{
|
||||
/* FIXME: don't wire in ".text" as section name
|
||||
or symbol name! */
|
||||
|
|
@ -879,7 +857,6 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
|||
print_address_symbolic work right without the (now
|
||||
gone) "set fast-symbolic-addr off" kludge. */
|
||||
|
||||
/* FIXME: should use mst_abs, and not relocate, if absolute. */
|
||||
enum minimal_symbol_type ms_type;
|
||||
int sec;
|
||||
|
||||
|
|
@ -901,12 +878,23 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
|||
|| cs->c_sclass == C_THUMBEXT ?
|
||||
mst_bss : mst_file_bss;
|
||||
}
|
||||
else if (cs->c_secnum == N_ABS)
|
||||
{
|
||||
/* Use the correct minimal symbol type (and don't
|
||||
relocate) for absolute values. */
|
||||
ms_type = mst_abs;
|
||||
sec = cs_to_section (cs, objfile);
|
||||
tmpaddr = cs->c_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
sec = cs_to_section (cs, objfile);
|
||||
tmpaddr = cs->c_value;
|
||||
if (cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
|
||||
|| cs->c_sclass == C_THUMBEXT)
|
||||
/* Statics in a PE file also get relocated */
|
||||
if (cs->c_sclass == C_EXT
|
||||
|| cs->c_sclass == C_THUMBEXTFUNC
|
||||
|| cs->c_sclass == C_THUMBEXT
|
||||
|| (pe_file && (cs->c_sclass == C_STAT)))
|
||||
tmpaddr += ANOFFSET (objfile->section_offsets, sec);
|
||||
|
||||
if (sec == SECT_OFF_TEXT (objfile))
|
||||
|
|
@ -936,15 +924,8 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
|||
if (cs->c_name[0] != '@' /* Skip tdesc symbols */ )
|
||||
{
|
||||
struct minimal_symbol *msym;
|
||||
|
||||
/* FIXME: cagney/2001-02-01: The nasty (int) -> (long)
|
||||
-> (void*) cast is to ensure that that the value of
|
||||
cs->c_sclass can be correctly stored in a void
|
||||
pointer in MSYMBOL_INFO. Better solutions
|
||||
welcome. */
|
||||
gdb_assert (sizeof (void *) >= sizeof (cs->c_sclass));
|
||||
msym = prim_record_minimal_symbol_and_info
|
||||
(cs->c_name, tmpaddr, ms_type, (void *) (long) cs->c_sclass,
|
||||
(cs->c_name, tmpaddr, ms_type, NULL,
|
||||
sec, NULL, objfile);
|
||||
if (msym)
|
||||
COFF_MAKE_MSYMBOL_SPECIAL (cs->c_sclass, msym);
|
||||
|
|
@ -961,7 +942,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
|||
break;
|
||||
|
||||
case C_FCN:
|
||||
if (STREQ (cs->c_name, ".bf"))
|
||||
if (DEPRECATED_STREQ (cs->c_name, ".bf"))
|
||||
{
|
||||
within_function = 1;
|
||||
|
||||
|
|
@ -969,7 +950,8 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
|||
/* main_aux.x_sym.x_misc.x_lnsz.x_lnno
|
||||
contains line number of '{' } */
|
||||
if (cs->c_naux != 1)
|
||||
complain (&bf_no_aux_complaint, cs->c_symnum);
|
||||
complaint (&symfile_complaints,
|
||||
"`.bf' symbol %d has no aux entry", cs->c_symnum);
|
||||
fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
|
||||
fcn_first_line_addr = cs->c_value;
|
||||
|
||||
|
|
@ -982,7 +964,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
|||
new->name =
|
||||
process_coff_symbol (&fcn_cs_saved, &fcn_aux_saved, objfile);
|
||||
}
|
||||
else if (STREQ (cs->c_name, ".ef"))
|
||||
else if (DEPRECATED_STREQ (cs->c_name, ".ef"))
|
||||
{
|
||||
if (!within_function)
|
||||
error ("Bad coff function information\n");
|
||||
|
|
@ -993,7 +975,9 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
|||
|
||||
if (context_stack_depth <= 0)
|
||||
{ /* We attempted to pop an empty context stack */
|
||||
complain (&ef_stack_complaint, cs->c_symnum);
|
||||
complaint (&symfile_complaints,
|
||||
"`.ef' symbol without matching `.bf' symbol ignored starting at symnum %d",
|
||||
cs->c_symnum);
|
||||
within_function = 0;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1002,13 +986,16 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
|||
/* Stack must be empty now. */
|
||||
if (context_stack_depth > 0 || new == NULL)
|
||||
{
|
||||
complain (&ef_complaint, cs->c_symnum);
|
||||
complaint (&symfile_complaints,
|
||||
"Unmatched .ef symbol(s) ignored starting at symnum %d",
|
||||
cs->c_symnum);
|
||||
within_function = 0;
|
||||
break;
|
||||
}
|
||||
if (cs->c_naux != 1)
|
||||
{
|
||||
complain (&ef_no_aux_complaint, cs->c_symnum);
|
||||
complaint (&symfile_complaints,
|
||||
"`.ef' symbol %d has no aux entry", cs->c_symnum);
|
||||
fcn_last_line = 0x7FFFFFFF;
|
||||
}
|
||||
else
|
||||
|
|
@ -1053,24 +1040,28 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
|||
break;
|
||||
|
||||
case C_BLOCK:
|
||||
if (STREQ (cs->c_name, ".bb"))
|
||||
if (DEPRECATED_STREQ (cs->c_name, ".bb"))
|
||||
{
|
||||
tmpaddr = cs->c_value;
|
||||
tmpaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
|
||||
push_context (++depth, tmpaddr);
|
||||
}
|
||||
else if (STREQ (cs->c_name, ".eb"))
|
||||
else if (DEPRECATED_STREQ (cs->c_name, ".eb"))
|
||||
{
|
||||
if (context_stack_depth <= 0)
|
||||
{ /* We attempted to pop an empty context stack */
|
||||
complain (&eb_stack_complaint, cs->c_symnum);
|
||||
complaint (&symfile_complaints,
|
||||
"`.eb' symbol without matching `.bb' symbol ignored starting at symnum %d",
|
||||
cs->c_symnum);
|
||||
break;
|
||||
}
|
||||
|
||||
new = pop_context ();
|
||||
if (depth-- != new->depth)
|
||||
{
|
||||
complain (&eb_complaint, symnum);
|
||||
complaint (&symfile_complaints,
|
||||
"Mismatched .eb symbol ignored starting at symnum %d",
|
||||
symnum);
|
||||
break;
|
||||
}
|
||||
if (local_symbols && context_stack_depth > 0)
|
||||
|
|
@ -1092,6 +1083,13 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
|||
}
|
||||
}
|
||||
|
||||
if ((nsyms == 0) && (pe_file))
|
||||
{
|
||||
/* We've got no debugging symbols, but it's is a portable
|
||||
executable, so try to read the export table */
|
||||
read_pe_exported_syms (objfile);
|
||||
}
|
||||
|
||||
if (last_source_file)
|
||||
coff_end_symtab (objfile);
|
||||
|
||||
|
|
@ -1110,9 +1108,9 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
|
|||
in internal_auxent form, and skip any other auxents. */
|
||||
|
||||
static void
|
||||
read_one_sym (register struct coff_symbol *cs,
|
||||
register struct internal_syment *sym,
|
||||
register union internal_auxent *aux)
|
||||
read_one_sym (struct coff_symbol *cs,
|
||||
struct internal_syment *sym,
|
||||
union internal_auxent *aux)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -1261,7 +1259,7 @@ static char *
|
|||
coff_getfilename (union internal_auxent *aux_entry)
|
||||
{
|
||||
static char buffer[BUFSIZ];
|
||||
register char *temp;
|
||||
char *temp;
|
||||
char *result;
|
||||
|
||||
if (aux_entry->x_file.x_n.x_zeroes == 0)
|
||||
|
|
@ -1339,17 +1337,19 @@ free_linetab_cleanup (void *ignore)
|
|||
#endif
|
||||
|
||||
static void
|
||||
enter_linenos (long file_offset, register int first_line,
|
||||
register int last_line, struct objfile *objfile)
|
||||
enter_linenos (long file_offset, int first_line,
|
||||
int last_line, struct objfile *objfile)
|
||||
{
|
||||
register char *rawptr;
|
||||
char *rawptr;
|
||||
struct internal_lineno lptr;
|
||||
|
||||
if (!linetab)
|
||||
return;
|
||||
if (file_offset < linetab_offset)
|
||||
{
|
||||
complain (&lineno_complaint, file_offset);
|
||||
complaint (&symfile_complaints,
|
||||
"Line number pointer %ld lower than start of line numbers",
|
||||
file_offset);
|
||||
if (file_offset > linetab_size) /* Too big to be an offset? */
|
||||
return;
|
||||
file_offset += linetab_offset; /* Try reading at that linetab offset */
|
||||
|
|
@ -1362,11 +1362,15 @@ enter_linenos (long file_offset, register int first_line,
|
|||
/* line numbers start at one for the first line of the function */
|
||||
first_line--;
|
||||
|
||||
for (;;)
|
||||
/* If the line number table is full (e.g. 64K lines in COFF debug
|
||||
info), the next function's L_LNNO32 might not be zero, so don't
|
||||
overstep the table's end in any case. */
|
||||
while (rawptr <= &linetab[0] + linetab_size)
|
||||
{
|
||||
bfd_coff_swap_lineno_in (symfile_bfd, rawptr, &lptr);
|
||||
rawptr += local_linesz;
|
||||
/* The next function, or the sentinel, will have L_LNNO32 zero; we exit. */
|
||||
/* The next function, or the sentinel, will have L_LNNO32 zero;
|
||||
we exit. */
|
||||
if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line)
|
||||
record_line (current_subfile, first_line + L_LNNO32 (&lptr),
|
||||
lptr.l_addr.l_paddr
|
||||
|
|
@ -1379,8 +1383,8 @@ enter_linenos (long file_offset, register int first_line,
|
|||
static void
|
||||
patch_type (struct type *type, struct type *real_type)
|
||||
{
|
||||
register struct type *target = TYPE_TARGET_TYPE (type);
|
||||
register struct type *real_target = TYPE_TARGET_TYPE (real_type);
|
||||
struct type *target = TYPE_TARGET_TYPE (type);
|
||||
struct type *real_target = TYPE_TARGET_TYPE (real_type);
|
||||
int field_size = TYPE_NFIELDS (real_target) * sizeof (struct field);
|
||||
|
||||
TYPE_LENGTH (target) = TYPE_LENGTH (real_target);
|
||||
|
|
@ -1403,33 +1407,32 @@ patch_type (struct type *type, struct type *real_type)
|
|||
static void
|
||||
patch_opaque_types (struct symtab *s)
|
||||
{
|
||||
register struct block *b;
|
||||
register int i;
|
||||
register struct symbol *real_sym;
|
||||
struct block *b;
|
||||
struct dict_iterator iter;
|
||||
struct symbol *real_sym;
|
||||
|
||||
/* Go through the per-file symbols only */
|
||||
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
|
||||
for (i = BLOCK_NSYMS (b) - 1; i >= 0; i--)
|
||||
ALL_BLOCK_SYMBOLS (b, iter, real_sym)
|
||||
{
|
||||
/* Find completed typedefs to use to fix opaque ones.
|
||||
Remove syms from the chain when their types are stored,
|
||||
but search the whole chain, as there may be several syms
|
||||
from different files with the same name. */
|
||||
real_sym = BLOCK_SYM (b, i);
|
||||
if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF &&
|
||||
SYMBOL_NAMESPACE (real_sym) == VAR_NAMESPACE &&
|
||||
SYMBOL_DOMAIN (real_sym) == VAR_DOMAIN &&
|
||||
TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR &&
|
||||
TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0)
|
||||
{
|
||||
register char *name = SYMBOL_NAME (real_sym);
|
||||
register int hash = hashname (name);
|
||||
register struct symbol *sym, *prev;
|
||||
char *name = DEPRECATED_SYMBOL_NAME (real_sym);
|
||||
int hash = hashname (name);
|
||||
struct symbol *sym, *prev;
|
||||
|
||||
prev = 0;
|
||||
for (sym = opaque_type_chain[hash]; sym;)
|
||||
{
|
||||
if (name[0] == SYMBOL_NAME (sym)[0] &&
|
||||
STREQ (name + 1, SYMBOL_NAME (sym) + 1))
|
||||
if (name[0] == DEPRECATED_SYMBOL_NAME (sym)[0] &&
|
||||
strcmp (name + 1, DEPRECATED_SYMBOL_NAME (sym) + 1) == 0)
|
||||
{
|
||||
if (prev)
|
||||
{
|
||||
|
|
@ -1462,26 +1465,24 @@ patch_opaque_types (struct symtab *s)
|
|||
}
|
||||
|
||||
static struct symbol *
|
||||
process_coff_symbol (register struct coff_symbol *cs,
|
||||
register union internal_auxent *aux,
|
||||
process_coff_symbol (struct coff_symbol *cs,
|
||||
union internal_auxent *aux,
|
||||
struct objfile *objfile)
|
||||
{
|
||||
register struct symbol *sym
|
||||
= (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
|
||||
struct symbol *sym
|
||||
= (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
|
||||
sizeof (struct symbol));
|
||||
char *name;
|
||||
|
||||
memset (sym, 0, sizeof (struct symbol));
|
||||
name = cs->c_name;
|
||||
name = EXTERNAL_NAME (name, objfile->obfd);
|
||||
SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
|
||||
&objfile->symbol_obstack);
|
||||
SYMBOL_LANGUAGE (sym) = language_auto;
|
||||
SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
|
||||
SYMBOL_SET_NAMES (sym, name, strlen (name), objfile);
|
||||
|
||||
/* default assumptions */
|
||||
SYMBOL_VALUE (sym) = cs->c_value;
|
||||
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
|
||||
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
|
||||
SYMBOL_SECTION (sym) = cs_to_section (cs, objfile);
|
||||
|
||||
if (ISFCN (cs->c_type))
|
||||
|
|
@ -1603,7 +1604,7 @@ process_coff_symbol (register struct coff_symbol *cs,
|
|||
|
||||
case C_TPDEF:
|
||||
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
|
||||
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
|
||||
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
|
||||
|
||||
/* If type has no name, give it one */
|
||||
if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
|
||||
|
|
@ -1633,13 +1634,8 @@ process_coff_symbol (register struct coff_symbol *cs,
|
|||
}
|
||||
else
|
||||
TYPE_NAME (SYMBOL_TYPE (sym)) =
|
||||
concat (SYMBOL_NAME (sym), NULL);
|
||||
concat (DEPRECATED_SYMBOL_NAME (sym), NULL);
|
||||
}
|
||||
#ifdef CXUX_TARGET
|
||||
/* Ignore vendor section for Harris CX/UX targets. */
|
||||
else if (cs->c_name[0] == '$')
|
||||
break;
|
||||
#endif /* CXUX_TARGET */
|
||||
|
||||
/* Keep track of any type which points to empty structured type,
|
||||
so it can be filled from a definition from another file. A
|
||||
|
|
@ -1651,7 +1647,7 @@ process_coff_symbol (register struct coff_symbol *cs,
|
|||
TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) !=
|
||||
TYPE_CODE_UNDEF)
|
||||
{
|
||||
register int i = hashname (SYMBOL_NAME (sym));
|
||||
int i = hashname (DEPRECATED_SYMBOL_NAME (sym));
|
||||
|
||||
SYMBOL_VALUE_CHAIN (sym) = opaque_type_chain[i];
|
||||
opaque_type_chain[i] = sym;
|
||||
|
|
@ -1663,17 +1659,17 @@ process_coff_symbol (register struct coff_symbol *cs,
|
|||
case C_UNTAG:
|
||||
case C_ENTAG:
|
||||
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
|
||||
SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
|
||||
SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
|
||||
|
||||
/* Some compilers try to be helpful by inventing "fake"
|
||||
names for anonymous enums, structures, and unions, like
|
||||
"~0fake" or ".0fake". Thanks, but no thanks... */
|
||||
if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0)
|
||||
if (SYMBOL_NAME (sym) != NULL
|
||||
&& *SYMBOL_NAME (sym) != '~'
|
||||
&& *SYMBOL_NAME (sym) != '.')
|
||||
if (DEPRECATED_SYMBOL_NAME (sym) != NULL
|
||||
&& *DEPRECATED_SYMBOL_NAME (sym) != '~'
|
||||
&& *DEPRECATED_SYMBOL_NAME (sym) != '.')
|
||||
TYPE_TAG_NAME (SYMBOL_TYPE (sym)) =
|
||||
concat (SYMBOL_NAME (sym), NULL);
|
||||
concat (DEPRECATED_SYMBOL_NAME (sym), NULL);
|
||||
|
||||
add_symbol_to_list (sym, &file_symbols);
|
||||
break;
|
||||
|
|
@ -1688,10 +1684,10 @@ process_coff_symbol (register struct coff_symbol *cs,
|
|||
/* Decode a coff type specifier; return the type that is meant. */
|
||||
|
||||
static struct type *
|
||||
decode_type (register struct coff_symbol *cs, unsigned int c_type,
|
||||
register union internal_auxent *aux)
|
||||
decode_type (struct coff_symbol *cs, unsigned int c_type,
|
||||
union internal_auxent *aux)
|
||||
{
|
||||
register struct type *type = 0;
|
||||
struct type *type = 0;
|
||||
unsigned int new_c_type;
|
||||
|
||||
if (c_type & ~N_BTMASK)
|
||||
|
|
@ -1710,7 +1706,7 @@ decode_type (register struct coff_symbol *cs, unsigned int c_type,
|
|||
else if (ISARY (c_type))
|
||||
{
|
||||
int i, n;
|
||||
register unsigned short *dim;
|
||||
unsigned short *dim;
|
||||
struct type *base_type, *index_type, *range_type;
|
||||
|
||||
/* Define an array type. */
|
||||
|
|
@ -1755,7 +1751,9 @@ decode_type (register struct coff_symbol *cs, unsigned int c_type,
|
|||
}
|
||||
else
|
||||
{
|
||||
complain (&tagndx_bad_complaint, cs->c_name);
|
||||
complaint (&symfile_complaints,
|
||||
"Symbol table entry for %s has bad tagndx value",
|
||||
cs->c_name);
|
||||
/* And fall through to decode_base_type... */
|
||||
}
|
||||
}
|
||||
|
|
@ -1767,8 +1765,8 @@ decode_type (register struct coff_symbol *cs, unsigned int c_type,
|
|||
return the type that the function returns. */
|
||||
|
||||
static struct type *
|
||||
decode_function_type (register struct coff_symbol *cs, unsigned int c_type,
|
||||
register union internal_auxent *aux)
|
||||
decode_function_type (struct coff_symbol *cs, unsigned int c_type,
|
||||
union internal_auxent *aux)
|
||||
{
|
||||
if (aux->x_sym.x_tagndx.l == 0)
|
||||
cs->c_naux = 0; /* auxent refers to function, not base type */
|
||||
|
|
@ -1779,8 +1777,8 @@ decode_function_type (register struct coff_symbol *cs, unsigned int c_type,
|
|||
/* basic C types */
|
||||
|
||||
static struct type *
|
||||
decode_base_type (register struct coff_symbol *cs, unsigned int c_type,
|
||||
register union internal_auxent *aux)
|
||||
decode_base_type (struct coff_symbol *cs, unsigned int c_type,
|
||||
union internal_auxent *aux)
|
||||
{
|
||||
struct type *type;
|
||||
|
||||
|
|
@ -1790,15 +1788,6 @@ decode_base_type (register struct coff_symbol *cs, unsigned int c_type,
|
|||
/* shows up with "void (*foo)();" structure members */
|
||||
return lookup_fundamental_type (current_objfile, FT_VOID);
|
||||
|
||||
#if 0
|
||||
/* DGUX actually defines both T_ARG and T_VOID to the same value. */
|
||||
#ifdef T_ARG
|
||||
case T_ARG:
|
||||
/* Shows up in DGUX, I think. Not sure where. */
|
||||
return lookup_fundamental_type (current_objfile, FT_VOID); /* shouldn't show up here */
|
||||
#endif
|
||||
#endif /* 0 */
|
||||
|
||||
#ifdef T_VOID
|
||||
case T_VOID:
|
||||
/* Intel 960 COFF has this symbol and meaning. */
|
||||
|
|
@ -1921,7 +1910,7 @@ decode_base_type (register struct coff_symbol *cs, unsigned int c_type,
|
|||
else
|
||||
return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
|
||||
}
|
||||
complain (&unexpected_type_complaint, cs->c_name);
|
||||
complaint (&symfile_complaints, "Unexpected type for symbol %s", cs->c_name);
|
||||
return lookup_fundamental_type (current_objfile, FT_VOID);
|
||||
}
|
||||
|
||||
|
|
@ -1939,14 +1928,14 @@ coff_read_struct_type (int index, int length, int lastsym)
|
|||
struct field field;
|
||||
};
|
||||
|
||||
register struct type *type;
|
||||
register struct nextfield *list = 0;
|
||||
struct type *type;
|
||||
struct nextfield *list = 0;
|
||||
struct nextfield *new;
|
||||
int nfields = 0;
|
||||
register int n;
|
||||
int n;
|
||||
char *name;
|
||||
struct coff_symbol member_sym;
|
||||
register struct coff_symbol *ms = &member_sym;
|
||||
struct coff_symbol *ms = &member_sym;
|
||||
struct internal_syment sub_sym;
|
||||
union internal_auxent sub_aux;
|
||||
int done = 0;
|
||||
|
|
@ -1976,10 +1965,11 @@ coff_read_struct_type (int index, int length, int lastsym)
|
|||
list->field.name =
|
||||
obsavestring (name,
|
||||
strlen (name),
|
||||
¤t_objfile->symbol_obstack);
|
||||
¤t_objfile->objfile_obstack);
|
||||
FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
|
||||
FIELD_BITPOS (list->field) = 8 * ms->c_value;
|
||||
FIELD_BITSIZE (list->field) = 0;
|
||||
FIELD_STATIC_KIND (list->field) = 0;
|
||||
nfields++;
|
||||
break;
|
||||
|
||||
|
|
@ -1994,10 +1984,11 @@ coff_read_struct_type (int index, int length, int lastsym)
|
|||
list->field.name =
|
||||
obsavestring (name,
|
||||
strlen (name),
|
||||
¤t_objfile->symbol_obstack);
|
||||
¤t_objfile->objfile_obstack);
|
||||
FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
|
||||
FIELD_BITPOS (list->field) = ms->c_value;
|
||||
FIELD_BITSIZE (list->field) = sub_aux.x_sym.x_misc.x_lnsz.x_size;
|
||||
FIELD_STATIC_KIND (list->field) = 0;
|
||||
nfields++;
|
||||
break;
|
||||
|
||||
|
|
@ -2024,22 +2015,21 @@ coff_read_struct_type (int index, int length, int lastsym)
|
|||
and create and return a suitable type object.
|
||||
Also defines the symbols that represent the values of the type. */
|
||||
|
||||
/* ARGSUSED */
|
||||
static struct type *
|
||||
coff_read_enum_type (int index, int length, int lastsym)
|
||||
{
|
||||
register struct symbol *sym;
|
||||
register struct type *type;
|
||||
struct symbol *sym;
|
||||
struct type *type;
|
||||
int nsyms = 0;
|
||||
int done = 0;
|
||||
struct pending **symlist;
|
||||
struct coff_symbol member_sym;
|
||||
register struct coff_symbol *ms = &member_sym;
|
||||
struct coff_symbol *ms = &member_sym;
|
||||
struct internal_syment sub_sym;
|
||||
union internal_auxent sub_aux;
|
||||
struct pending *osyms, *syms;
|
||||
int o_nsyms;
|
||||
register int n;
|
||||
int n;
|
||||
char *name;
|
||||
int unsigned_enum = 1;
|
||||
|
||||
|
|
@ -2061,15 +2051,15 @@ coff_read_enum_type (int index, int length, int lastsym)
|
|||
{
|
||||
case C_MOE:
|
||||
sym = (struct symbol *) obstack_alloc
|
||||
(¤t_objfile->symbol_obstack,
|
||||
(¤t_objfile->objfile_obstack,
|
||||
sizeof (struct symbol));
|
||||
memset (sym, 0, sizeof (struct symbol));
|
||||
|
||||
SYMBOL_NAME (sym) =
|
||||
DEPRECATED_SYMBOL_NAME (sym) =
|
||||
obsavestring (name, strlen (name),
|
||||
¤t_objfile->symbol_obstack);
|
||||
¤t_objfile->objfile_obstack);
|
||||
SYMBOL_CLASS (sym) = LOC_CONST;
|
||||
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
|
||||
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
|
||||
SYMBOL_VALUE (sym) = ms->c_value;
|
||||
add_symbol_to_list (sym, symlist);
|
||||
nsyms++;
|
||||
|
|
@ -2113,11 +2103,12 @@ coff_read_enum_type (int index, int length, int lastsym)
|
|||
{
|
||||
struct symbol *xsym = syms->symbol[j];
|
||||
SYMBOL_TYPE (xsym) = type;
|
||||
TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
|
||||
TYPE_FIELD_NAME (type, n) = DEPRECATED_SYMBOL_NAME (xsym);
|
||||
TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
|
||||
if (SYMBOL_VALUE (xsym) < 0)
|
||||
unsigned_enum = 0;
|
||||
TYPE_FIELD_BITSIZE (type, n) = 0;
|
||||
TYPE_FIELD_STATIC_KIND (type, n) = 0;
|
||||
}
|
||||
if (syms == osyms)
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* Definitions to make GDB run on an Alpha box under OSF1. This is
|
||||
also used by the Alpha/Netware and Alpha GNU/Linux targets.
|
||||
|
||||
Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2002 Free
|
||||
Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2002, 2004 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
|
@ -24,353 +24,21 @@
|
|||
#ifndef TM_ALPHA_H
|
||||
#define TM_ALPHA_H
|
||||
|
||||
#include "regcache.h"
|
||||
#include "bfd.h"
|
||||
#include "coff/sym.h" /* Needed for PDR below. */
|
||||
#include "coff/symconst.h"
|
||||
|
||||
struct frame_info;
|
||||
struct type;
|
||||
struct value;
|
||||
struct symbol;
|
||||
|
||||
/* Redefine some target bit sizes from the default. */
|
||||
|
||||
#define TARGET_LONG_BIT 64
|
||||
#define TARGET_LONG_LONG_BIT 64
|
||||
#define TARGET_PTR_BIT 64
|
||||
|
||||
/* Number of traps that happen between exec'ing the shell
|
||||
* to run an inferior, and when we finally get to
|
||||
* the inferior code. This is 2 on most implementations.
|
||||
*/
|
||||
#define START_INFERIOR_TRAPS_EXPECTED 3
|
||||
|
||||
/* Offset from address of function to start of its code.
|
||||
Zero on most machines. */
|
||||
|
||||
#define FUNCTION_START_OFFSET 0
|
||||
|
||||
/* Advance PC across any function entry prologue instructions
|
||||
to reach some "real" code. */
|
||||
|
||||
#define SKIP_PROLOGUE(pc) alpha_skip_prologue((pc))
|
||||
extern CORE_ADDR alpha_skip_prologue (CORE_ADDR addr);
|
||||
|
||||
/* Immediately after a function call, return the saved pc.
|
||||
Can't always go through the frames for this because on some machines
|
||||
the new frame is not set up until the new function executes
|
||||
some instructions. */
|
||||
|
||||
#define SAVED_PC_AFTER_CALL(frame) alpha_saved_pc_after_call(frame)
|
||||
extern CORE_ADDR alpha_saved_pc_after_call (struct frame_info *);
|
||||
|
||||
/* Are we currently handling a signal ? */
|
||||
|
||||
#define IN_SIGTRAMP(pc, name) alpha_osf_in_sigtramp ((pc), (name))
|
||||
extern int alpha_osf_in_sigtramp (CORE_ADDR, char *);
|
||||
|
||||
/* Stack grows downward. */
|
||||
|
||||
#define INNER_THAN(lhs,rhs) core_addr_lessthan ((lhs), (rhs))
|
||||
|
||||
#define BREAKPOINT {0x80, 0, 0, 0} /* call_pal bpt */
|
||||
|
||||
/* Amount PC must be decremented by after a breakpoint.
|
||||
This is often the number of bytes in BREAKPOINT
|
||||
but not always. */
|
||||
|
||||
#ifndef DECR_PC_AFTER_BREAK
|
||||
#define DECR_PC_AFTER_BREAK 4
|
||||
#endif
|
||||
|
||||
/* Say how long (ordinary) registers are. This is a piece of bogosity
|
||||
used in push_word and a few other places; REGISTER_RAW_SIZE is the
|
||||
real way to know how big a register is. */
|
||||
|
||||
#define REGISTER_SIZE 8
|
||||
|
||||
/* Number of machine registers */
|
||||
|
||||
#define NUM_REGS 66
|
||||
|
||||
|
||||
/* Return the name of register REGNO. */
|
||||
|
||||
#define REGISTER_NAME(regno) alpha_register_name ((regno))
|
||||
extern char *alpha_register_name (int);
|
||||
|
||||
|
||||
/* Register numbers of various important registers.
|
||||
Note that most of these values are "real" register numbers,
|
||||
and correspond to the general registers of the machine,
|
||||
and FP_REGNUM is a "phony" register number which is too large
|
||||
to be an actual register number as far as the user is concerned
|
||||
but serves to get the desired value when passed to read_register. */
|
||||
|
||||
#define V0_REGNUM 0 /* Function integer return value */
|
||||
#define T7_REGNUM 8 /* Return address register for OSF/1 __add* */
|
||||
#define GCC_FP_REGNUM 15 /* Used by gcc as frame register */
|
||||
#define A0_REGNUM 16 /* Loc of first arg during a subr call */
|
||||
#define T9_REGNUM 23 /* Return address register for OSF/1 __div* */
|
||||
#define T12_REGNUM 27 /* Contains start addr of current proc */
|
||||
#define SP_REGNUM 30 /* Contains address of top of stack */
|
||||
#define RA_REGNUM 26 /* Contains return address value */
|
||||
#define ZERO_REGNUM 31 /* Read-only register, always 0 */
|
||||
#define FP0_REGNUM 32 /* Floating point register 0 */
|
||||
#define FPA0_REGNUM 48 /* First float arg during a subr call */
|
||||
#define FPCR_REGNUM 63 /* Floating point control register */
|
||||
#define PC_REGNUM 64 /* Contains program counter */
|
||||
#define FP_REGNUM 65 /* Virtual frame pointer */
|
||||
|
||||
#define CANNOT_FETCH_REGISTER(regno) \
|
||||
alpha_cannot_fetch_register ((regno))
|
||||
extern int alpha_cannot_fetch_register (int);
|
||||
|
||||
#define CANNOT_STORE_REGISTER(regno) \
|
||||
alpha_cannot_store_register ((regno))
|
||||
extern int alpha_cannot_store_register (int);
|
||||
|
||||
/* Total amount of space needed to store our copies of the machine's
|
||||
register state, the array `registers'. */
|
||||
#define REGISTER_BYTES (NUM_REGS * 8)
|
||||
|
||||
/* Index within `registers' of the first byte of the space for
|
||||
register N. */
|
||||
|
||||
#define REGISTER_BYTE(N) alpha_register_byte ((N))
|
||||
extern int alpha_register_byte (int);
|
||||
|
||||
/* Number of bytes of storage in the actual machine representation
|
||||
for register N. On Alphas, all regs are 8 bytes. */
|
||||
|
||||
#define REGISTER_RAW_SIZE(N) alpha_register_raw_size ((N))
|
||||
extern int alpha_register_raw_size (int);
|
||||
|
||||
/* Number of bytes of storage in the program's representation
|
||||
for register N. On Alphas, all regs are 8 bytes. */
|
||||
|
||||
#define REGISTER_VIRTUAL_SIZE(N) alpha_register_virtual_size ((N))
|
||||
extern int alpha_register_virtual_size (int);
|
||||
|
||||
/* Largest value REGISTER_RAW_SIZE can have. */
|
||||
|
||||
#define MAX_REGISTER_RAW_SIZE 8
|
||||
|
||||
/* Largest value REGISTER_VIRTUAL_SIZE can have. */
|
||||
|
||||
#define MAX_REGISTER_VIRTUAL_SIZE 8
|
||||
|
||||
/* Nonzero if register N requires conversion
|
||||
from raw format to virtual format.
|
||||
The alpha needs a conversion between register and memory format if
|
||||
the register is a floating point register and
|
||||
memory format is float, as the register format must be double
|
||||
or
|
||||
memory format is an integer with 4 bytes or less, as the representation
|
||||
of integers in floating point registers is different. */
|
||||
|
||||
#define REGISTER_CONVERTIBLE(N) alpha_register_convertible ((N))
|
||||
extern int alpha_register_convertible (int);
|
||||
|
||||
/* Convert data from raw format for register REGNUM in buffer FROM
|
||||
to virtual format with type TYPE in buffer TO. */
|
||||
|
||||
#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM, TYPE, FROM, TO) \
|
||||
alpha_register_convert_to_virtual (REGNUM, TYPE, FROM, TO)
|
||||
extern void
|
||||
alpha_register_convert_to_virtual (int, struct type *, char *, char *);
|
||||
|
||||
/* Convert data from virtual format with type TYPE in buffer FROM
|
||||
to raw format for register REGNUM in buffer TO. */
|
||||
|
||||
#define REGISTER_CONVERT_TO_RAW(TYPE, REGNUM, FROM, TO) \
|
||||
alpha_register_convert_to_raw (TYPE, REGNUM, FROM, TO)
|
||||
extern void
|
||||
alpha_register_convert_to_raw (struct type *, int, char *, char *);
|
||||
|
||||
/* Return the GDB type object for the "standard" data type
|
||||
of data in register N. */
|
||||
|
||||
#define REGISTER_VIRTUAL_TYPE(N) alpha_register_virtual_type ((N))
|
||||
extern struct type * alpha_register_virtual_type (int);
|
||||
|
||||
/* Store the address of the place in which to copy the structure the
|
||||
subroutine will return. Handled by alpha_push_arguments. */
|
||||
|
||||
#define STORE_STRUCT_RETURN(addr, sp) \
|
||||
alpha_store_struct_return ((addr), (sp))
|
||||
extern void alpha_store_struct_return (CORE_ADDR, CORE_ADDR);
|
||||
/**/
|
||||
|
||||
/* Extract from an array REGBUF containing the (raw) register state
|
||||
a function return value of type TYPE, and copy that, in virtual format,
|
||||
into VALBUF. */
|
||||
|
||||
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
|
||||
alpha_extract_return_value(TYPE, REGBUF, VALBUF)
|
||||
extern void alpha_extract_return_value (struct type *, char *, char *);
|
||||
|
||||
/* Write into appropriate registers a function return value
|
||||
of type TYPE, given in virtual format. */
|
||||
|
||||
#define STORE_RETURN_VALUE(TYPE,VALBUF) \
|
||||
alpha_store_return_value(TYPE, VALBUF)
|
||||
extern void alpha_store_return_value (struct type *, char *);
|
||||
|
||||
/* Extract from an array REGBUF containing the (raw) register state
|
||||
the address in which a function should return its structure value,
|
||||
as a CORE_ADDR (or an expression that can be used as one). */
|
||||
/* The address is passed in a0 upon entry to the function, but when
|
||||
the function exits, the compiler has copied the value to v0. This
|
||||
convention is specified by the System V ABI, so I think we can rely
|
||||
on it. */
|
||||
|
||||
#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
|
||||
alpha_extract_struct_value_address (REGBUF)
|
||||
extern CORE_ADDR alpha_extract_struct_value_address (char *);
|
||||
|
||||
/* Structures are returned by ref in extra arg0 */
|
||||
#define USE_STRUCT_CONVENTION(gcc_p, type) \
|
||||
alpha_use_struct_convention ((gcc_p), (type))
|
||||
extern int alpha_use_struct_convention (int, struct type *);
|
||||
|
||||
|
||||
/* Describe the pointer in each stack frame to the previous stack frame
|
||||
(its caller). */
|
||||
|
||||
/* FRAME_CHAIN takes a frame's nominal address
|
||||
and produces the frame's chain-pointer. */
|
||||
|
||||
#define FRAME_CHAIN(thisframe) alpha_frame_chain (thisframe)
|
||||
extern CORE_ADDR alpha_frame_chain (struct frame_info *);
|
||||
|
||||
/* Define other aspects of the stack frame. */
|
||||
|
||||
|
||||
/* An expression that tells us whether the function invocation represented
|
||||
by FI does not have a frame on the stack associated with it. */
|
||||
/* We handle this differently for alpha, and maybe we should not */
|
||||
|
||||
#define FRAMELESS_FUNCTION_INVOCATION(FI) \
|
||||
generic_frameless_function_invocation_not ((FI))
|
||||
|
||||
/* Saved Pc. */
|
||||
|
||||
#define FRAME_SAVED_PC(FRAME) alpha_frame_saved_pc(FRAME)
|
||||
extern CORE_ADDR alpha_frame_saved_pc (struct frame_info *);
|
||||
|
||||
/* The alpha has two different virtual pointers for arguments and locals.
|
||||
|
||||
The virtual argument pointer is pointing to the bottom of the argument
|
||||
transfer area, which is located immediately below the virtual frame
|
||||
pointer. Its size is fixed for the native compiler, it is either zero
|
||||
(for the no arguments case) or large enough to hold all argument registers.
|
||||
gcc uses a variable sized argument transfer area. As it has
|
||||
to stay compatible with the native debugging tools it has to use the same
|
||||
virtual argument pointer and adjust the argument offsets accordingly.
|
||||
|
||||
The virtual local pointer is localoff bytes below the virtual frame
|
||||
pointer, the value of localoff is obtained from the PDR. */
|
||||
|
||||
#define ALPHA_NUM_ARG_REGS 6
|
||||
|
||||
#define FRAME_ARGS_ADDRESS(fi) alpha_frame_args_address ((fi))
|
||||
extern CORE_ADDR alpha_frame_args_address (struct frame_info *);
|
||||
|
||||
#define FRAME_LOCALS_ADDRESS(fi) alpha_frame_locals_address ((fi))
|
||||
extern CORE_ADDR alpha_frame_locals_address (struct frame_info *);
|
||||
|
||||
/* Return number of args passed to a frame.
|
||||
Can return -1, meaning no way to tell. */
|
||||
|
||||
#define FRAME_NUM_ARGS(fi) frame_num_args_unknown ((fi))
|
||||
|
||||
/* Return number of bytes at start of arglist that are not really args. */
|
||||
|
||||
#define FRAME_ARGS_SKIP 0
|
||||
|
||||
/* Put here the code to store, into a struct frame_saved_regs,
|
||||
the addresses of the saved registers of frame described by FRAME_INFO.
|
||||
This includes special registers such as pc and fp saved in special
|
||||
ways in the stack frame. sp is even more special:
|
||||
the address we return for it IS the sp for the next frame. */
|
||||
|
||||
#define FRAME_INIT_SAVED_REGS(frame_info) \
|
||||
alpha_frame_init_saved_regs (frame_info)
|
||||
extern void alpha_frame_init_saved_regs (struct frame_info *);
|
||||
|
||||
|
||||
/* Things needed for making the inferior call functions. */
|
||||
|
||||
#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \
|
||||
(alpha_push_arguments((nargs), (args), (sp), (struct_return), (struct_addr)))
|
||||
extern CORE_ADDR
|
||||
alpha_push_arguments (int, struct value **, CORE_ADDR, int, CORE_ADDR);
|
||||
|
||||
/* Push an empty stack frame, to record the current PC, etc. */
|
||||
|
||||
#define PUSH_DUMMY_FRAME alpha_push_dummy_frame()
|
||||
extern void alpha_push_dummy_frame (void);
|
||||
|
||||
/* Discard from the stack the innermost frame, restoring all registers. */
|
||||
|
||||
#define POP_FRAME alpha_pop_frame()
|
||||
extern void alpha_pop_frame (void);
|
||||
|
||||
/* Alpha OSF/1 inhibits execution of code on the stack.
|
||||
But there is no need for a dummy on the alpha. PUSH_ARGUMENTS
|
||||
takes care of all argument handling and bp_call_dummy takes care
|
||||
of stopping the dummy. */
|
||||
|
||||
#define CALL_DUMMY_LOCATION AT_ENTRY_POINT
|
||||
|
||||
/* On the Alpha the call dummy code is never copied to user space,
|
||||
stopping the user call is achieved via a bp_call_dummy breakpoint.
|
||||
But we need a fake CALL_DUMMY definition to enable the proper
|
||||
call_function_by_hand and to avoid zero length array warnings
|
||||
in valops.c */
|
||||
|
||||
#define CALL_DUMMY_P (1)
|
||||
|
||||
#define CALL_DUMMY_WORDS alpha_call_dummy_words
|
||||
extern LONGEST alpha_call_dummy_words[];
|
||||
|
||||
#define SIZEOF_CALL_DUMMY_WORDS 0
|
||||
|
||||
#define CALL_DUMMY_START_OFFSET (0)
|
||||
|
||||
#define CALL_DUMMY_BREAKPOINT_OFFSET (0)
|
||||
|
||||
#define CALL_DUMMY_ADDRESS() alpha_call_dummy_address()
|
||||
extern CORE_ADDR alpha_call_dummy_address (void);
|
||||
|
||||
/* Insert the specified number of args and function address
|
||||
into a call sequence of the above form stored at DUMMYNAME.
|
||||
We only have to set RA_REGNUM to the dummy breakpoint address
|
||||
and T12_REGNUM (the `procedure value register') to the function address. */
|
||||
|
||||
#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \
|
||||
alpha_fix_call_dummy ((dummyname), (pc), (fun), (nargs), (args), \
|
||||
(type), (gcc_p))
|
||||
extern void alpha_fix_call_dummy (char *, CORE_ADDR, CORE_ADDR, int,
|
||||
struct value **, struct type *, int);
|
||||
|
||||
/* There's a mess in stack frame creation. See comments in blockframe.c
|
||||
near reference to INIT_FRAME_PC_FIRST. */
|
||||
|
||||
#define INIT_FRAME_PC(fromleaf, prev) init_frame_pc_noop ((fromleaf), (prev))
|
||||
|
||||
#define INIT_FRAME_PC_FIRST(fromleaf, prev) \
|
||||
alpha_init_frame_pc_first ((fromleaf), (prev))
|
||||
extern void alpha_init_frame_pc_first (int, struct frame_info *);
|
||||
|
||||
/* Special symbol found in blocks associated with routines. We can hang
|
||||
alpha_extra_func_info_t's off of this. */
|
||||
|
||||
#define MIPS_EFI_SYMBOL_NAME "__GDB_EFI_INFO__"
|
||||
extern void ecoff_relocate_efi (struct symbol *, CORE_ADDR);
|
||||
|
||||
#define RA_REGNUM 26 /* XXXJRT needed by mdebugread.c */
|
||||
|
||||
/* Specific information about a procedure.
|
||||
This overlays the ALPHA's PDR records,
|
||||
alpharead.c (ab)uses this to save memory */
|
||||
|
|
@ -389,15 +57,6 @@ typedef struct alpha_extra_func_info
|
|||
#define mips_extra_func_info alpha_extra_func_info
|
||||
#define mips_extra_func_info_t alpha_extra_func_info_t
|
||||
|
||||
|
||||
#define INIT_EXTRA_FRAME_INFO(fromleaf, fci) \
|
||||
alpha_init_extra_frame_info(fromleaf, fci)
|
||||
extern void alpha_init_extra_frame_info (int, struct frame_info *);
|
||||
|
||||
#define PRINT_EXTRA_FRAME_INFO(fi) alpha_print_extra_frame_info ((fi))
|
||||
extern void alpha_print_extra_frame_info (struct frame_info *);
|
||||
|
||||
|
||||
/* It takes two values to specify a frame on the ALPHA. Sigh.
|
||||
|
||||
In fact, at the moment, the *PC* is the primary value that sets up
|
||||
|
|
@ -408,64 +67,8 @@ extern void alpha_print_extra_frame_info (struct frame_info *);
|
|||
up so that the primary value is the SP, and the PC is used to disambiguate
|
||||
multiple functions with the same SP that are at different stack levels. */
|
||||
|
||||
#define SETUP_ARBITRARY_FRAME(argc, argv) setup_arbitrary_frame (argc, argv)
|
||||
extern struct frame_info *setup_arbitrary_frame (int, CORE_ADDR *);
|
||||
|
||||
/* This is used by heuristic_proc_start. It should be shot it the head. */
|
||||
#ifndef VM_MIN_ADDRESS
|
||||
#define VM_MIN_ADDRESS (CORE_ADDR)0x120000000
|
||||
#endif
|
||||
|
||||
/* If PC is in a shared library trampoline code, return the PC
|
||||
where the function itself actually starts. If not, return 0. */
|
||||
#define SKIP_TRAMPOLINE_CODE(pc) find_solib_trampoline_target (pc)
|
||||
|
||||
/* If the current gcc for for this target does not produce correct debugging
|
||||
information for float parameters, both prototyped and unprototyped, then
|
||||
define this macro. This forces gdb to always assume that floats are
|
||||
passed as doubles and then converted in the callee.
|
||||
|
||||
For the alpha, it appears that the debug info marks the parameters as
|
||||
floats regardless of whether the function is prototyped, but the actual
|
||||
values are always passed in as doubles. Thus by setting this to 1, both
|
||||
types of calls will work. */
|
||||
|
||||
#define COERCE_FLOAT_TO_DOUBLE(formal, actual) \
|
||||
standard_coerce_float_to_double ((formal), (actual))
|
||||
|
||||
/* Return TRUE if procedure descriptor PROC is a procedure descriptor
|
||||
that refers to a dynamically generated sigtramp function.
|
||||
|
||||
OSF/1 doesn't use dynamic sigtramp functions, so this is always
|
||||
FALSE. */
|
||||
|
||||
#define PROC_DESC_IS_DYN_SIGTRAMP(proc) (0)
|
||||
#define SET_PROC_DESC_IS_DYN_SIGTRAMP(proc)
|
||||
|
||||
/* If PC is inside a dynamically generated sigtramp function, return
|
||||
how many bytes the program counter is beyond the start of that
|
||||
function. Otherwise, return a negative value.
|
||||
|
||||
OSF/1 doesn't use dynamic sigtramp functions, so this always
|
||||
returns -1. */
|
||||
|
||||
#define DYNAMIC_SIGTRAMP_OFFSET(pc) (-1)
|
||||
|
||||
/* Translate a signal handler frame into the address of the sigcontext
|
||||
structure. */
|
||||
|
||||
#define SIGCONTEXT_ADDR(frame) \
|
||||
(read_memory_integer ((frame)->next ? frame->next->frame : frame->frame, 8))
|
||||
|
||||
/* If FRAME refers to a sigtramp frame, return the address of the next
|
||||
frame. */
|
||||
|
||||
#define FRAME_PAST_SIGTRAMP_FRAME(frame, pc) \
|
||||
(alpha_osf_skip_sigtramp_frame (frame, pc))
|
||||
extern CORE_ADDR alpha_osf_skip_sigtramp_frame (struct frame_info *,
|
||||
CORE_ADDR);
|
||||
|
||||
/* Single step based on where the current instruction will take us. */
|
||||
extern void alpha_software_single_step (enum target_signal, int);
|
||||
#define SETUP_ARBITRARY_FRAME(argc, argv) \
|
||||
alpha_setup_arbitrary_frame (argc, argv)
|
||||
extern struct frame_info *alpha_setup_arbitrary_frame (int, CORE_ADDR *);
|
||||
|
||||
#endif /* TM_ALPHA_H */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/* Target-dependent definitions for FreeBSD/i386.
|
||||
Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
Copyright 1997, 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
|
|
@ -21,73 +22,10 @@
|
|||
#ifndef TM_FBSD_H
|
||||
#define TM_FBSD_H
|
||||
|
||||
#define HAVE_I387_REGS
|
||||
#include "i386/tm-i386.h"
|
||||
#include "solib.h"
|
||||
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
/* FreeBSD/ELF uses stabs-in-ELF with the DWARF register numbering
|
||||
scheme by default, so we must redefine STAB_REG_TO_REGNUM. This
|
||||
messes up the floating-point registers for a.out, but there is not
|
||||
much we can do about that. */
|
||||
|
||||
#undef STAB_REG_TO_REGNUM
|
||||
#define STAB_REG_TO_REGNUM(reg) i386_dwarf_reg_to_regnum ((reg))
|
||||
|
||||
/* FreeBSD uses the old gcc convention for struct returns. */
|
||||
|
||||
#define USE_STRUCT_CONVENTION(gcc_p, type) \
|
||||
generic_use_struct_convention (1, type)
|
||||
|
||||
|
||||
/* Support for longjmp. */
|
||||
|
||||
/* Details about jmp_buf. It's supposed to be an array of integers. */
|
||||
|
||||
#define JB_ELEMENT_SIZE 4 /* Size of elements in jmp_buf. */
|
||||
#define JB_PC 0 /* Array index of saved PC. */
|
||||
|
||||
/* Figure out where the longjmp will land. Store the address that
|
||||
longjmp will jump to in *ADDR, and return non-zero if successful. */
|
||||
|
||||
#define GET_LONGJMP_TARGET(addr) get_longjmp_target (addr)
|
||||
extern int get_longjmp_target (CORE_ADDR *addr);
|
||||
|
||||
|
||||
/* Support for signal handlers. */
|
||||
|
||||
#define IN_SIGTRAMP(pc, name) i386bsd_in_sigtramp (pc, name)
|
||||
extern int i386bsd_in_sigtramp (CORE_ADDR pc, char *name);
|
||||
|
||||
/* These defines allow the recognition of sigtramps as a function name
|
||||
<sigtramp>.
|
||||
|
||||
FIXME: kettenis/2001-07-13: These should be added to the target
|
||||
vector and turned into functions when we go "multi-arch". */
|
||||
|
||||
#define SIGTRAMP_START(pc) i386bsd_sigtramp_start
|
||||
#define SIGTRAMP_END(pc) i386bsd_sigtramp_end
|
||||
extern CORE_ADDR i386bsd_sigtramp_start;
|
||||
extern CORE_ADDR i386bsd_sigtramp_end;
|
||||
|
||||
/* Override FRAME_SAVED_PC to enable the recognition of signal handlers. */
|
||||
|
||||
#undef FRAME_SAVED_PC
|
||||
#define FRAME_SAVED_PC(frame) i386bsd_frame_saved_pc (frame)
|
||||
extern CORE_ADDR i386bsd_frame_saved_pc (struct frame_info *frame);
|
||||
|
||||
|
||||
/* Shared library support. */
|
||||
|
||||
#ifndef SVR4_SHARED_LIBS
|
||||
|
||||
/* Return non-zero if we are in a shared library trampoline code stub. */
|
||||
|
||||
#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \
|
||||
(name && !strcmp(name, "_DYNAMIC"))
|
||||
|
||||
#endif /* !SVR4_SHARED_LIBS */
|
||||
|
||||
#endif /* TM_FBSD_H */
|
||||
#endif /* tm-fbsd.h */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/* Machine independent GDB support for core files on systems using "regsets".
|
||||
Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000
|
||||
|
||||
Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2003
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
|
@ -19,66 +20,43 @@
|
|||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
/* N O T E S
|
||||
|
||||
This file is used by most systems that implement /proc. For these systems,
|
||||
the general registers are laid out the same way in both the core file and
|
||||
the gregset_p structure. The current exception to this is Irix-4.*, where
|
||||
the gregset_p structure is split up into two pieces in the core file.
|
||||
|
||||
The general register and floating point register sets are manipulated by
|
||||
separate ioctl's. This file makes the assumption that if FP0_REGNUM is
|
||||
defined, then support for the floating point register set is desired,
|
||||
regardless of whether or not the actual target has floating point hardware.
|
||||
|
||||
*/
|
||||
/* This file is used by most systems that use ELF for their core
|
||||
dumps. This includes most systems that have SVR4-ish variant of
|
||||
/proc. For these systems, the registers are laid out the same way
|
||||
in core files as in the gregset_t and fpregset_t structures that
|
||||
are used in the interaction with /proc (Irix 4 is an exception and
|
||||
therefore doesn't use this file). Quite a few systems without a
|
||||
SVR4-ish /proc define these structures too, and can make use of
|
||||
this code too. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
#include "gdbcore.h"
|
||||
#include "inferior.h"
|
||||
#include "target.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include "gdb_string.h"
|
||||
#include <time.h>
|
||||
#ifdef HAVE_SYS_PROCFS_H
|
||||
#include <sys/procfs.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include "gdb_string.h"
|
||||
|
||||
#include "inferior.h"
|
||||
#include "target.h"
|
||||
#include "command.h"
|
||||
#include "gdbcore.h"
|
||||
|
||||
/* Prototypes for supply_gregset etc. */
|
||||
/* Prototypes for supply_gregset etc. */
|
||||
#include "gregset.h"
|
||||
|
||||
static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
|
||||
/* Provide registers to GDB from a core file.
|
||||
|
||||
void _initialize_core_regset (void);
|
||||
CORE_REG_SECT points to an array of bytes, which are the contents
|
||||
of a `note' from a core file which BFD thinks might contain
|
||||
register contents. CORE_REG_SIZE is its size.
|
||||
|
||||
/*
|
||||
WHICH says which register set corelow suspects this is:
|
||||
0 --- the general-purpose register set, in gregset_t format
|
||||
2 --- the floating-point register set, in fpregset_t format
|
||||
|
||||
GLOBAL FUNCTION
|
||||
|
||||
fetch_core_registers -- fetch current registers from core file
|
||||
|
||||
SYNOPSIS
|
||||
|
||||
void fetch_core_registers (char *core_reg_sect,
|
||||
unsigned core_reg_size,
|
||||
int which, CORE_ADDR reg_addr)
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
Read the values of either the general register set (WHICH equals 0)
|
||||
or the floating point register set (WHICH equals 2) from the core
|
||||
file data (pointed to by CORE_REG_SECT), and update gdb's idea of
|
||||
their current values. The CORE_REG_SIZE parameter is compared to
|
||||
the size of the gregset or fpgregset structures (as appropriate) to
|
||||
validate the size of the structure from the core file. The
|
||||
REG_ADDR parameter is ignored.
|
||||
|
||||
*/
|
||||
REG_ADDR is ignored. */
|
||||
|
||||
static void
|
||||
fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
|
||||
|
|
@ -87,36 +65,40 @@ fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
|
|||
gdb_gregset_t gregset;
|
||||
gdb_fpregset_t fpregset;
|
||||
|
||||
if (which == 0)
|
||||
switch (which)
|
||||
{
|
||||
case 0:
|
||||
if (core_reg_size != sizeof (gregset))
|
||||
{
|
||||
warning ("wrong size gregset struct in core file");
|
||||
}
|
||||
warning ("Wrong size gregset in core file.");
|
||||
else
|
||||
{
|
||||
memcpy ((char *) &gregset, core_reg_sect, sizeof (gregset));
|
||||
memcpy (&gregset, core_reg_sect, sizeof (gregset));
|
||||
supply_gregset (&gregset);
|
||||
}
|
||||
}
|
||||
else if (which == 2)
|
||||
{
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (core_reg_size != sizeof (fpregset))
|
||||
{
|
||||
warning ("wrong size fpregset struct in core file");
|
||||
}
|
||||
warning ("Wrong size fpregset in core file.");
|
||||
else
|
||||
{
|
||||
memcpy ((char *) &fpregset, core_reg_sect, sizeof (fpregset));
|
||||
memcpy (&fpregset, core_reg_sect, sizeof (fpregset));
|
||||
if (FP0_REGNUM >= 0)
|
||||
supply_fpregset (&fpregset);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* We've covered all the kinds of registers we know about here,
|
||||
so this must be something we wouldn't know what to do with
|
||||
anyway. Just ignore it. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Register that we are able to handle ELF file formats using standard
|
||||
procfs "regset" structures. */
|
||||
/* Register that we are able to handle ELF core file formats using
|
||||
standard procfs "regset" structures. */
|
||||
|
||||
static struct core_fns regset_core_fns =
|
||||
{
|
||||
|
|
@ -127,6 +109,9 @@ static struct core_fns regset_core_fns =
|
|||
NULL /* next */
|
||||
};
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
extern void _initialize_core_regset (void);
|
||||
|
||||
void
|
||||
_initialize_core_regset (void)
|
||||
{
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +1,7 @@
|
|||
/* *INDENT-OFF* */ /* ATTR_FORMAT confuses indent, avoid running it for now */
|
||||
/* Basic, host-specific, and target-specific definitions for GDB.
|
||||
Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
|
||||
1997, 1998, 1999, 2000, 2001, 2002
|
||||
1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
|
@ -24,22 +24,33 @@
|
|||
#ifndef DEFS_H
|
||||
#define DEFS_H
|
||||
|
||||
#include "config.h" /* Generated by configure */
|
||||
#include "config.h" /* Generated by configure. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h> /* System call error return status */
|
||||
#include <errno.h> /* System call error return status. */
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef HAVE_STDDEF_H
|
||||
#include <stddef.h>
|
||||
#else
|
||||
#include <sys/types.h> /* for size_t */
|
||||
#include <sys/types.h> /* For size_t. */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* Just in case they're not defined in stdio.h. */
|
||||
/* First include ansidecl.h so we can use the various macro definitions
|
||||
here and in all subsequent file inclusions. */
|
||||
|
||||
#include "ansidecl.h"
|
||||
|
||||
#include "gdb_locale.h"
|
||||
|
||||
/* For ``enum target_signal''. */
|
||||
#include "gdb/signals.h"
|
||||
|
||||
/* Just in case they're not defined in stdio.h. */
|
||||
|
||||
#ifndef SEEK_SET
|
||||
#define SEEK_SET 0
|
||||
|
|
@ -48,17 +59,10 @@
|
|||
#define SEEK_CUR 1
|
||||
#endif
|
||||
|
||||
/* First include ansidecl.h so we can use the various macro definitions
|
||||
here and in all subsequent file inclusions. */
|
||||
|
||||
#include "ansidecl.h"
|
||||
|
||||
#include <stdarg.h> /* for va_list */
|
||||
#include <stdarg.h> /* For va_list. */
|
||||
|
||||
#include "libiberty.h"
|
||||
|
||||
#include "progress.h"
|
||||
|
||||
/* For BFD64 and bfd_vma. */
|
||||
#include "bfd.h"
|
||||
|
||||
|
|
@ -148,25 +152,32 @@ typedef bfd_vma CORE_ADDR;
|
|||
issue is found that we spend the effort on algorithmic
|
||||
optimizations than micro-optimizing.'' J.T. */
|
||||
|
||||
#define STREQ(a,b) (*(a) == *(b) ? !strcmp ((a), (b)) : 0)
|
||||
#define STREQN(a,b,c) (*(a) == *(b) ? !strncmp ((a), (b), (c)) : 0)
|
||||
/* NOTE: cagney/2003-11-23: All instances of STREQ[N] covered by
|
||||
testing GDB on a stabs system have been replaced by equivalent
|
||||
str[n]cmp calls. To avoid the possability of introducing bugs when
|
||||
making untested changes, the remaining references were deprecated
|
||||
rather than replaced. */
|
||||
|
||||
/* The character GNU C++ uses to build identifiers that must be unique from
|
||||
the program's identifiers (such as $this and $$vptr). */
|
||||
#define CPLUS_MARKER '$' /* May be overridden to '.' for SysV */
|
||||
/* DISCLAIMER: cagney/2003-11-23: Simplified definition of these
|
||||
macros so that they just map directly onto strcmp equivalent. I'm
|
||||
not responsible for any breakage due to code that relied on the old
|
||||
underlying implementation. */
|
||||
|
||||
#define DEPRECATED_STREQ(a,b) (strcmp ((a), (b)) == 0)
|
||||
#define DEPRECATED_STREQN(a,b,c) (strncmp ((a), (b), (c)) == 0)
|
||||
|
||||
/* Check if a character is one of the commonly used C++ marker characters. */
|
||||
extern int is_cplus_marker (int);
|
||||
|
||||
/* use tui interface if non-zero */
|
||||
extern int tui_version;
|
||||
|
||||
/* enable xdb commands if set */
|
||||
extern int xdb_commands;
|
||||
|
||||
/* enable dbx commands if set */
|
||||
extern int dbx_commands;
|
||||
|
||||
/* System root path, used to find libraries etc. */
|
||||
extern char *gdb_sysroot;
|
||||
|
||||
extern int quit_flag;
|
||||
extern int immediate_quit;
|
||||
extern int sevenbit_strings;
|
||||
|
|
@ -188,7 +199,6 @@ extern void quit (void);
|
|||
#define QUIT { \
|
||||
if (quit_flag) quit (); \
|
||||
if (interactive_hook) interactive_hook (); \
|
||||
PROGRESS (1); \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -203,13 +213,14 @@ enum language
|
|||
language_auto, /* Placeholder for automatic setting */
|
||||
language_c, /* C */
|
||||
language_cplus, /* C++ */
|
||||
language_objc, /* Objective-C */
|
||||
language_java, /* Java */
|
||||
language_chill, /* Chill */
|
||||
language_fortran, /* Fortran */
|
||||
language_m2, /* Modula-2 */
|
||||
language_asm, /* Assembly language */
|
||||
language_scm, /* Scheme / Guile */
|
||||
language_pascal /* Pascal */
|
||||
language_pascal, /* Pascal */
|
||||
language_minimal /* All other languages, minimal support only */
|
||||
};
|
||||
|
||||
enum precision_type
|
||||
|
|
@ -219,212 +230,28 @@ enum precision_type
|
|||
unspecified_precision
|
||||
};
|
||||
|
||||
/* The numbering of these signals is chosen to match traditional unix
|
||||
signals (insofar as various unices use the same numbers, anyway).
|
||||
It is also the numbering of the GDB remote protocol. Other remote
|
||||
protocols, if they use a different numbering, should make sure to
|
||||
translate appropriately.
|
||||
/* A generic, not quite boolean, enumeration. */
|
||||
enum auto_boolean
|
||||
{
|
||||
AUTO_BOOLEAN_TRUE,
|
||||
AUTO_BOOLEAN_FALSE,
|
||||
AUTO_BOOLEAN_AUTO
|
||||
};
|
||||
|
||||
Since these numbers have actually made it out into other software
|
||||
(stubs, etc.), you mustn't disturb the assigned numbering. If you
|
||||
need to add new signals here, add them to the end of the explicitly
|
||||
numbered signals.
|
||||
|
||||
This is based strongly on Unix/POSIX signals for several reasons:
|
||||
(1) This set of signals represents a widely-accepted attempt to
|
||||
represent events of this sort in a portable fashion, (2) we want a
|
||||
signal to make it from wait to child_wait to the user intact, (3) many
|
||||
remote protocols use a similar encoding. However, it is
|
||||
recognized that this set of signals has limitations (such as not
|
||||
distinguishing between various kinds of SIGSEGV, or not
|
||||
distinguishing hitting a breakpoint from finishing a single step).
|
||||
So in the future we may get around this either by adding additional
|
||||
signals for breakpoint, single-step, etc., or by adding signal
|
||||
codes; the latter seems more in the spirit of what BSD, System V,
|
||||
etc. are doing to address these issues. */
|
||||
|
||||
/* For an explanation of what each signal means, see
|
||||
target_signal_to_string. */
|
||||
|
||||
enum target_signal
|
||||
{
|
||||
/* Used some places (e.g. stop_signal) to record the concept that
|
||||
there is no signal. */
|
||||
TARGET_SIGNAL_0 = 0,
|
||||
TARGET_SIGNAL_FIRST = 0,
|
||||
TARGET_SIGNAL_HUP = 1,
|
||||
TARGET_SIGNAL_INT = 2,
|
||||
TARGET_SIGNAL_QUIT = 3,
|
||||
TARGET_SIGNAL_ILL = 4,
|
||||
TARGET_SIGNAL_TRAP = 5,
|
||||
TARGET_SIGNAL_ABRT = 6,
|
||||
TARGET_SIGNAL_EMT = 7,
|
||||
TARGET_SIGNAL_FPE = 8,
|
||||
TARGET_SIGNAL_KILL = 9,
|
||||
TARGET_SIGNAL_BUS = 10,
|
||||
TARGET_SIGNAL_SEGV = 11,
|
||||
TARGET_SIGNAL_SYS = 12,
|
||||
TARGET_SIGNAL_PIPE = 13,
|
||||
TARGET_SIGNAL_ALRM = 14,
|
||||
TARGET_SIGNAL_TERM = 15,
|
||||
TARGET_SIGNAL_URG = 16,
|
||||
TARGET_SIGNAL_STOP = 17,
|
||||
TARGET_SIGNAL_TSTP = 18,
|
||||
TARGET_SIGNAL_CONT = 19,
|
||||
TARGET_SIGNAL_CHLD = 20,
|
||||
TARGET_SIGNAL_TTIN = 21,
|
||||
TARGET_SIGNAL_TTOU = 22,
|
||||
TARGET_SIGNAL_IO = 23,
|
||||
TARGET_SIGNAL_XCPU = 24,
|
||||
TARGET_SIGNAL_XFSZ = 25,
|
||||
TARGET_SIGNAL_VTALRM = 26,
|
||||
TARGET_SIGNAL_PROF = 27,
|
||||
TARGET_SIGNAL_WINCH = 28,
|
||||
TARGET_SIGNAL_LOST = 29,
|
||||
TARGET_SIGNAL_USR1 = 30,
|
||||
TARGET_SIGNAL_USR2 = 31,
|
||||
TARGET_SIGNAL_PWR = 32,
|
||||
/* Similar to SIGIO. Perhaps they should have the same number. */
|
||||
TARGET_SIGNAL_POLL = 33,
|
||||
TARGET_SIGNAL_WIND = 34,
|
||||
TARGET_SIGNAL_PHONE = 35,
|
||||
TARGET_SIGNAL_WAITING = 36,
|
||||
TARGET_SIGNAL_LWP = 37,
|
||||
TARGET_SIGNAL_DANGER = 38,
|
||||
TARGET_SIGNAL_GRANT = 39,
|
||||
TARGET_SIGNAL_RETRACT = 40,
|
||||
TARGET_SIGNAL_MSG = 41,
|
||||
TARGET_SIGNAL_SOUND = 42,
|
||||
TARGET_SIGNAL_SAK = 43,
|
||||
TARGET_SIGNAL_PRIO = 44,
|
||||
TARGET_SIGNAL_REALTIME_33 = 45,
|
||||
TARGET_SIGNAL_REALTIME_34 = 46,
|
||||
TARGET_SIGNAL_REALTIME_35 = 47,
|
||||
TARGET_SIGNAL_REALTIME_36 = 48,
|
||||
TARGET_SIGNAL_REALTIME_37 = 49,
|
||||
TARGET_SIGNAL_REALTIME_38 = 50,
|
||||
TARGET_SIGNAL_REALTIME_39 = 51,
|
||||
TARGET_SIGNAL_REALTIME_40 = 52,
|
||||
TARGET_SIGNAL_REALTIME_41 = 53,
|
||||
TARGET_SIGNAL_REALTIME_42 = 54,
|
||||
TARGET_SIGNAL_REALTIME_43 = 55,
|
||||
TARGET_SIGNAL_REALTIME_44 = 56,
|
||||
TARGET_SIGNAL_REALTIME_45 = 57,
|
||||
TARGET_SIGNAL_REALTIME_46 = 58,
|
||||
TARGET_SIGNAL_REALTIME_47 = 59,
|
||||
TARGET_SIGNAL_REALTIME_48 = 60,
|
||||
TARGET_SIGNAL_REALTIME_49 = 61,
|
||||
TARGET_SIGNAL_REALTIME_50 = 62,
|
||||
TARGET_SIGNAL_REALTIME_51 = 63,
|
||||
TARGET_SIGNAL_REALTIME_52 = 64,
|
||||
TARGET_SIGNAL_REALTIME_53 = 65,
|
||||
TARGET_SIGNAL_REALTIME_54 = 66,
|
||||
TARGET_SIGNAL_REALTIME_55 = 67,
|
||||
TARGET_SIGNAL_REALTIME_56 = 68,
|
||||
TARGET_SIGNAL_REALTIME_57 = 69,
|
||||
TARGET_SIGNAL_REALTIME_58 = 70,
|
||||
TARGET_SIGNAL_REALTIME_59 = 71,
|
||||
TARGET_SIGNAL_REALTIME_60 = 72,
|
||||
TARGET_SIGNAL_REALTIME_61 = 73,
|
||||
TARGET_SIGNAL_REALTIME_62 = 74,
|
||||
TARGET_SIGNAL_REALTIME_63 = 75,
|
||||
|
||||
/* Used internally by Solaris threads. See signal(5) on Solaris. */
|
||||
TARGET_SIGNAL_CANCEL = 76,
|
||||
|
||||
/* Yes, this pains me, too. But LynxOS didn't have SIG32, and now
|
||||
GNU/Linux does, and we can't disturb the numbering, since it's
|
||||
part of the remote protocol. Note that in some GDB's
|
||||
TARGET_SIGNAL_REALTIME_32 is number 76. */
|
||||
TARGET_SIGNAL_REALTIME_32,
|
||||
/* Yet another pain, IRIX 6 has SIG64. */
|
||||
TARGET_SIGNAL_REALTIME_64,
|
||||
/* Yet another pain, GNU/Linux MIPS might go up to 128. */
|
||||
TARGET_SIGNAL_REALTIME_65,
|
||||
TARGET_SIGNAL_REALTIME_66,
|
||||
TARGET_SIGNAL_REALTIME_67,
|
||||
TARGET_SIGNAL_REALTIME_68,
|
||||
TARGET_SIGNAL_REALTIME_69,
|
||||
TARGET_SIGNAL_REALTIME_70,
|
||||
TARGET_SIGNAL_REALTIME_71,
|
||||
TARGET_SIGNAL_REALTIME_72,
|
||||
TARGET_SIGNAL_REALTIME_73,
|
||||
TARGET_SIGNAL_REALTIME_74,
|
||||
TARGET_SIGNAL_REALTIME_75,
|
||||
TARGET_SIGNAL_REALTIME_76,
|
||||
TARGET_SIGNAL_REALTIME_77,
|
||||
TARGET_SIGNAL_REALTIME_78,
|
||||
TARGET_SIGNAL_REALTIME_79,
|
||||
TARGET_SIGNAL_REALTIME_80,
|
||||
TARGET_SIGNAL_REALTIME_81,
|
||||
TARGET_SIGNAL_REALTIME_82,
|
||||
TARGET_SIGNAL_REALTIME_83,
|
||||
TARGET_SIGNAL_REALTIME_84,
|
||||
TARGET_SIGNAL_REALTIME_85,
|
||||
TARGET_SIGNAL_REALTIME_86,
|
||||
TARGET_SIGNAL_REALTIME_87,
|
||||
TARGET_SIGNAL_REALTIME_88,
|
||||
TARGET_SIGNAL_REALTIME_89,
|
||||
TARGET_SIGNAL_REALTIME_90,
|
||||
TARGET_SIGNAL_REALTIME_91,
|
||||
TARGET_SIGNAL_REALTIME_92,
|
||||
TARGET_SIGNAL_REALTIME_93,
|
||||
TARGET_SIGNAL_REALTIME_94,
|
||||
TARGET_SIGNAL_REALTIME_95,
|
||||
TARGET_SIGNAL_REALTIME_96,
|
||||
TARGET_SIGNAL_REALTIME_97,
|
||||
TARGET_SIGNAL_REALTIME_98,
|
||||
TARGET_SIGNAL_REALTIME_99,
|
||||
TARGET_SIGNAL_REALTIME_100,
|
||||
TARGET_SIGNAL_REALTIME_101,
|
||||
TARGET_SIGNAL_REALTIME_102,
|
||||
TARGET_SIGNAL_REALTIME_103,
|
||||
TARGET_SIGNAL_REALTIME_104,
|
||||
TARGET_SIGNAL_REALTIME_105,
|
||||
TARGET_SIGNAL_REALTIME_106,
|
||||
TARGET_SIGNAL_REALTIME_107,
|
||||
TARGET_SIGNAL_REALTIME_108,
|
||||
TARGET_SIGNAL_REALTIME_109,
|
||||
TARGET_SIGNAL_REALTIME_110,
|
||||
TARGET_SIGNAL_REALTIME_111,
|
||||
TARGET_SIGNAL_REALTIME_112,
|
||||
TARGET_SIGNAL_REALTIME_113,
|
||||
TARGET_SIGNAL_REALTIME_114,
|
||||
TARGET_SIGNAL_REALTIME_115,
|
||||
TARGET_SIGNAL_REALTIME_116,
|
||||
TARGET_SIGNAL_REALTIME_117,
|
||||
TARGET_SIGNAL_REALTIME_118,
|
||||
TARGET_SIGNAL_REALTIME_119,
|
||||
TARGET_SIGNAL_REALTIME_120,
|
||||
TARGET_SIGNAL_REALTIME_121,
|
||||
TARGET_SIGNAL_REALTIME_122,
|
||||
TARGET_SIGNAL_REALTIME_123,
|
||||
TARGET_SIGNAL_REALTIME_124,
|
||||
TARGET_SIGNAL_REALTIME_125,
|
||||
TARGET_SIGNAL_REALTIME_126,
|
||||
TARGET_SIGNAL_REALTIME_127,
|
||||
|
||||
#if defined(MACH) || defined(__MACH__)
|
||||
/* Mach exceptions */
|
||||
TARGET_EXC_BAD_ACCESS,
|
||||
TARGET_EXC_BAD_INSTRUCTION,
|
||||
TARGET_EXC_ARITHMETIC,
|
||||
TARGET_EXC_EMULATION,
|
||||
TARGET_EXC_SOFTWARE,
|
||||
TARGET_EXC_BREAKPOINT,
|
||||
#endif
|
||||
TARGET_SIGNAL_INFO,
|
||||
|
||||
/* Some signal we don't know about. */
|
||||
TARGET_SIGNAL_UNKNOWN,
|
||||
|
||||
/* Use whatever signal we use when one is not specifically specified
|
||||
(for passing to proceed and so on). */
|
||||
TARGET_SIGNAL_DEFAULT,
|
||||
|
||||
/* Last and unused enum value, for sizing arrays, etc. */
|
||||
TARGET_SIGNAL_LAST
|
||||
};
|
||||
/* Potential ways that a function can return a value of a given type. */
|
||||
enum return_value_convention
|
||||
{
|
||||
/* Where the return value has been squeezed into one or more
|
||||
registers. */
|
||||
RETURN_VALUE_REGISTER_CONVENTION,
|
||||
/* Commonly known as the "struct return convention". The caller
|
||||
passes an additional hidden first parameter to the caller. That
|
||||
parameter contains the address at which the value being returned
|
||||
should be stored. While typically, and historically, used for
|
||||
large structs, this is convention is applied to values of many
|
||||
different types. */
|
||||
RETURN_VALUE_STRUCT_CONVENTION
|
||||
};
|
||||
|
||||
/* the cleanup list records things that have to be undone
|
||||
if an error happens (descriptors to be closed, memory to be freed, etc.)
|
||||
|
|
@ -439,8 +266,8 @@ enum target_signal
|
|||
struct cleanup
|
||||
{
|
||||
struct cleanup *next;
|
||||
void (*function) (PTR);
|
||||
PTR arg;
|
||||
void (*function) (void *);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -481,23 +308,29 @@ struct cleanup
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/* Be conservative and use enum bitfields only with GCC.
|
||||
This is copied from gcc 3.3.1, system.h. */
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 2)
|
||||
#define ENUM_BITFIELD(TYPE) enum TYPE
|
||||
#else
|
||||
#define ENUM_BITFIELD(TYPE) unsigned int
|
||||
#endif
|
||||
|
||||
/* Needed for various prototypes */
|
||||
|
||||
struct symtab;
|
||||
struct breakpoint;
|
||||
struct frame_info;
|
||||
|
||||
/* From blockframe.c */
|
||||
|
||||
extern int inside_entry_func (CORE_ADDR);
|
||||
extern int inside_entry_func (struct frame_info *this_frame);
|
||||
|
||||
extern int inside_entry_file (CORE_ADDR addr);
|
||||
extern int deprecated_inside_entry_file (CORE_ADDR addr);
|
||||
|
||||
extern int inside_main_func (CORE_ADDR pc);
|
||||
|
||||
/* From ch-lang.c, for the moment. (FIXME) */
|
||||
|
||||
extern char *chill_demangle (const char *);
|
||||
|
||||
/* From utils.c */
|
||||
|
||||
extern void initialize_utils (void);
|
||||
|
|
@ -506,6 +339,10 @@ extern void notice_quit (void);
|
|||
|
||||
extern int strcmp_iw (const char *, const char *);
|
||||
|
||||
extern int strcmp_iw_ordered (const char *, const char *);
|
||||
|
||||
extern int streq (const char *, const char *);
|
||||
|
||||
extern int subset_compare (char *, char *);
|
||||
|
||||
extern char *safe_strerror (int);
|
||||
|
|
@ -516,7 +353,6 @@ extern void request_quit (int);
|
|||
|
||||
extern void do_cleanups (struct cleanup *);
|
||||
extern void do_final_cleanups (struct cleanup *);
|
||||
extern void do_my_cleanups (struct cleanup **, struct cleanup *);
|
||||
extern void do_run_cleanups (struct cleanup *);
|
||||
extern void do_exec_cleanups (struct cleanup *);
|
||||
extern void do_exec_error_cleanups (struct cleanup *);
|
||||
|
|
@ -569,13 +405,16 @@ extern void null_cleanup (void *);
|
|||
extern int myread (int, char *, int);
|
||||
|
||||
extern int query (const char *, ...) ATTR_FORMAT (printf, 1, 2);
|
||||
extern int nquery (const char *, ...) ATTR_FORMAT (printf, 1, 2);
|
||||
extern int yquery (const char *, ...) ATTR_FORMAT (printf, 1, 2);
|
||||
|
||||
extern void init_page_info (void);
|
||||
|
||||
extern CORE_ADDR host_pointer_to_address (void *ptr);
|
||||
extern void *address_to_host_pointer (CORE_ADDR addr);
|
||||
|
||||
extern char *gdb_realpath (const char *);
|
||||
extern char *xfullpath (const char *);
|
||||
|
||||
extern unsigned long gnu_debuglink_crc32 (unsigned long crc,
|
||||
unsigned char *buf, size_t len);
|
||||
|
||||
/* From demangle.c */
|
||||
|
||||
|
|
@ -587,7 +426,6 @@ struct type;
|
|||
typedef int (use_struct_convention_fn) (int gcc_p, struct type * value_type);
|
||||
extern use_struct_convention_fn generic_use_struct_convention;
|
||||
|
||||
typedef unsigned char *(breakpoint_from_pc_fn) (CORE_ADDR * pcptr, int *lenptr);
|
||||
|
||||
/* Annotation stuff. */
|
||||
|
||||
|
|
@ -601,22 +439,22 @@ extern void reinitialize_more_filter (void);
|
|||
|
||||
/* Normal results */
|
||||
extern struct ui_file *gdb_stdout;
|
||||
/* Input stream */
|
||||
extern struct ui_file *gdb_stdin;
|
||||
/* Serious error notifications */
|
||||
extern struct ui_file *gdb_stderr;
|
||||
/* Log/debug/trace messages that should bypass normal stdout/stderr
|
||||
filtering. For momement, always call this stream using
|
||||
filtering. For moment, always call this stream using
|
||||
*_unfiltered. In the very near future that restriction shall be
|
||||
removed - either call shall be unfiltered. (cagney 1999-06-13). */
|
||||
extern struct ui_file *gdb_stdlog;
|
||||
/* Target output that should bypass normal stdout/stderr filtering.
|
||||
For momement, always call this stream using *_unfiltered. In the
|
||||
For moment, always call this stream using *_unfiltered. In the
|
||||
very near future that restriction shall be removed - either call
|
||||
shall be unfiltered. (cagney 1999-07-02). */
|
||||
extern struct ui_file *gdb_stdtarg;
|
||||
|
||||
#if defined(TUI)
|
||||
#include "tui.h"
|
||||
#endif
|
||||
extern struct ui_file *gdb_stdtargerr;
|
||||
extern struct ui_file *gdb_stdtargin;
|
||||
|
||||
#include "ui-file.h"
|
||||
|
||||
|
|
@ -639,6 +477,8 @@ extern void puts_filtered (const char *);
|
|||
|
||||
extern void puts_unfiltered (const char *);
|
||||
|
||||
extern void puts_filtered_tabular (char *string, int width, int right);
|
||||
|
||||
extern void puts_debug (char *prefix, char *string, char *suffix);
|
||||
|
||||
extern void vprintf_filtered (const char *, va_list) ATTR_FORMAT (printf, 1, 0);
|
||||
|
|
@ -674,7 +514,7 @@ extern void fputstr_unfiltered (const char *str, int quotr, struct ui_file * str
|
|||
extern void fputstrn_unfiltered (const char *str, int n, int quotr, struct ui_file * stream);
|
||||
|
||||
/* Display the host ADDR on STREAM formatted as ``0x%x''. */
|
||||
extern void gdb_print_host_address (void *addr, struct ui_file *stream);
|
||||
extern void gdb_print_host_address (const void *addr, struct ui_file *stream);
|
||||
|
||||
/* Convert a CORE_ADDR into a HEX string. paddr() is like %08lx.
|
||||
paddr_nz() is like %lx. paddr_u() is like %lu. paddr_width() is
|
||||
|
|
@ -729,6 +569,8 @@ extern char *skip_quoted (char *);
|
|||
|
||||
extern char *gdb_readline (char *);
|
||||
|
||||
extern char *gdb_readline_wrapper (char *);
|
||||
|
||||
extern char *command_line_input (char *, int, char *);
|
||||
|
||||
extern void print_prompt (void);
|
||||
|
|
@ -764,10 +606,16 @@ extern int source_full_path_of (char *, char **);
|
|||
|
||||
extern void mod_path (char *, char **);
|
||||
|
||||
extern void add_path (char *, char **, int);
|
||||
|
||||
extern void directory_command (char *, int);
|
||||
|
||||
extern char *source_path;
|
||||
|
||||
extern void init_source_path (void);
|
||||
|
||||
extern void init_last_source_visited (void);
|
||||
|
||||
extern char *symtab_to_filename (struct symtab *);
|
||||
|
||||
/* From exec.c */
|
||||
|
|
@ -783,10 +631,6 @@ extern void exec_set_find_memory_regions (int (*) (int (*) (CORE_ADDR,
|
|||
void *),
|
||||
void *));
|
||||
|
||||
/* From findvar.c */
|
||||
|
||||
extern int read_relative_register_raw_bytes (int, char *);
|
||||
|
||||
/* Possible lvalue types. Like enum language, this should be in
|
||||
value.h, but needs to be here for the same reason. */
|
||||
|
||||
|
|
@ -808,12 +652,6 @@ enum lval_type
|
|||
lval_reg_frame_relative
|
||||
};
|
||||
|
||||
struct frame_info;
|
||||
|
||||
/* From readline (but not in any readline .h files). */
|
||||
|
||||
extern char *tilde_expand (char *);
|
||||
|
||||
/* Control types for commands */
|
||||
|
||||
enum misc_command_type
|
||||
|
|
@ -970,16 +808,6 @@ typedef struct ptid ptid_t;
|
|||
#include "tm.h"
|
||||
#endif
|
||||
|
||||
/* GDB_MULTI_ARCH is normally set by configure.in using information
|
||||
from configure.tgt or the config/%/%.mt Makefile fragment. Since
|
||||
some targets have defined it in their "tm.h" file, delay providing
|
||||
a default definition until after "tm.h" has been included.. */
|
||||
|
||||
#ifndef GDB_MULTI_ARCH
|
||||
#define GDB_MULTI_ARCH 0
|
||||
#endif
|
||||
|
||||
|
||||
/* If the xm.h file did not define the mode string used to open the
|
||||
files, assume that binary files are opened the same way as text
|
||||
files */
|
||||
|
|
@ -1044,11 +872,21 @@ extern void xmfree (void *md, void *ptr);
|
|||
"libiberty.h". */
|
||||
extern void xfree (void *);
|
||||
|
||||
/* Utility macros to allocate typed memory. Avoids errors like:
|
||||
struct foo *foo = xmalloc (sizeof struct bar); and memset (foo,
|
||||
sizeof (struct foo), 0). */
|
||||
#define XZALLOC(TYPE) ((TYPE*) memset (xmalloc (sizeof (TYPE)), 0, sizeof (TYPE)))
|
||||
#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
|
||||
#define XCALLOC(NMEMB, TYPE) ((TYPE*) xcalloc ((NMEMB), sizeof (TYPE)))
|
||||
|
||||
/* Like asprintf/vasprintf but get an internal_error if the call
|
||||
fails. */
|
||||
extern void xasprintf (char **ret, const char *format, ...) ATTR_FORMAT (printf, 2, 3);
|
||||
extern void xvasprintf (char **ret, const char *format, va_list ap);
|
||||
|
||||
/* Like asprintf, but return the string, throw an error if no memory. */
|
||||
extern char *xstrprintf (const char *format, ...) ATTR_FORMAT (printf, 1, 2);
|
||||
|
||||
extern int parse_escape (char **);
|
||||
|
||||
/* Message to be printed before the error message, when an error occurs. */
|
||||
|
|
@ -1065,20 +903,34 @@ extern char *warning_pre_print;
|
|||
|
||||
extern NORETURN void verror (const char *fmt, va_list ap) ATTR_NORETURN;
|
||||
|
||||
extern NORETURN void error (const char *fmt, ...) ATTR_NORETURN;
|
||||
extern NORETURN void error (const char *fmt, ...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2);
|
||||
|
||||
extern NORETURN void error_silent (const char *fmt, ...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2);
|
||||
|
||||
extern NORETURN void error_stream (struct ui_file *) ATTR_NORETURN;
|
||||
|
||||
/* Initialize the error buffer. */
|
||||
extern void error_init (void);
|
||||
|
||||
/* Returns a freshly allocate buffer containing the last error
|
||||
message. */
|
||||
extern char *error_last_message (void);
|
||||
|
||||
/* Output arbitrary error message. */
|
||||
extern void error_output_message (char *pre_print, char *msg);
|
||||
|
||||
extern NORETURN void internal_verror (const char *file, int line,
|
||||
const char *, va_list ap) ATTR_NORETURN;
|
||||
|
||||
extern NORETURN void internal_error (const char *file, int line,
|
||||
const char *, ...) ATTR_NORETURN ATTR_FORMAT (printf, 3, 4);
|
||||
|
||||
extern void internal_vwarning (const char *file, int line,
|
||||
const char *, va_list ap);
|
||||
|
||||
extern void internal_warning (const char *file, int line,
|
||||
const char *, ...) ATTR_FORMAT (printf, 3, 4);
|
||||
|
||||
extern NORETURN void nomem (long) ATTR_NORETURN;
|
||||
|
||||
/* Reasons for calling throw_exception(). NOTE: all reason values
|
||||
|
|
@ -1129,6 +981,11 @@ extern NORETURN void throw_exception (enum return_reason) ATTR_NORETURN;
|
|||
new cleanup_chain is established. The old values are restored
|
||||
before catch_exceptions() returns.
|
||||
|
||||
The variant catch_exceptions_with_msg() is the same as
|
||||
catch_exceptions() but adds the ability to return an allocated
|
||||
copy of the gdb error message. This is used when a silent error is
|
||||
issued and the caller wants to manually issue the error message.
|
||||
|
||||
FIXME; cagney/2001-08-13: The need to override the global UIOUT
|
||||
builder variable should just go away.
|
||||
|
||||
|
|
@ -1141,6 +998,11 @@ typedef int (catch_exceptions_ftype) (struct ui_out *ui_out, void *args);
|
|||
extern int catch_exceptions (struct ui_out *uiout,
|
||||
catch_exceptions_ftype *func, void *func_args,
|
||||
char *errstring, return_mask mask);
|
||||
extern int catch_exceptions_with_msg (struct ui_out *uiout,
|
||||
catch_exceptions_ftype *func,
|
||||
void *func_args,
|
||||
char *errstring, char **gdberrmsg,
|
||||
return_mask mask);
|
||||
|
||||
/* If CATCH_ERRORS_FTYPE throws an error, catch_errors() returns zero
|
||||
otherwize the result from CATCH_ERRORS_FTYPE is returned. It is
|
||||
|
|
@ -1151,7 +1013,7 @@ extern int catch_exceptions (struct ui_out *uiout,
|
|||
|
||||
This function is superseeded by catch_exceptions(). */
|
||||
|
||||
typedef int (catch_errors_ftype) (PTR);
|
||||
typedef int (catch_errors_ftype) (void *);
|
||||
extern int catch_errors (catch_errors_ftype *, void *, char *, return_mask);
|
||||
|
||||
/* Template to catch_errors() that wraps calls to command
|
||||
|
|
@ -1164,6 +1026,43 @@ extern void warning (const char *, ...) ATTR_FORMAT (printf, 1, 2);
|
|||
|
||||
extern void vwarning (const char *, va_list args);
|
||||
|
||||
/* List of known OS ABIs. If you change this, make sure to update the
|
||||
table in osabi.c. */
|
||||
enum gdb_osabi
|
||||
{
|
||||
GDB_OSABI_UNINITIALIZED = -1, /* For struct gdbarch_info. */
|
||||
|
||||
GDB_OSABI_UNKNOWN = 0, /* keep this zero */
|
||||
|
||||
GDB_OSABI_SVR4,
|
||||
GDB_OSABI_HURD,
|
||||
GDB_OSABI_SOLARIS,
|
||||
GDB_OSABI_OSF1,
|
||||
GDB_OSABI_LINUX,
|
||||
GDB_OSABI_FREEBSD_AOUT,
|
||||
GDB_OSABI_FREEBSD_ELF,
|
||||
GDB_OSABI_NETBSD_AOUT,
|
||||
GDB_OSABI_NETBSD_ELF,
|
||||
GDB_OSABI_OPENBSD_ELF,
|
||||
GDB_OSABI_WINCE,
|
||||
GDB_OSABI_GO32,
|
||||
GDB_OSABI_NETWARE,
|
||||
GDB_OSABI_IRIX,
|
||||
GDB_OSABI_LYNXOS,
|
||||
GDB_OSABI_INTERIX,
|
||||
GDB_OSABI_HPUX_ELF,
|
||||
GDB_OSABI_HPUX_SOM,
|
||||
|
||||
GDB_OSABI_ARM_EABI_V1,
|
||||
GDB_OSABI_ARM_EABI_V2,
|
||||
GDB_OSABI_ARM_APCS,
|
||||
GDB_OSABI_QNXNTO,
|
||||
|
||||
GDB_OSABI_CYGWIN,
|
||||
|
||||
GDB_OSABI_INVALID /* keep this last */
|
||||
};
|
||||
|
||||
/* Global functions from other, non-gdb GNU thingies.
|
||||
Libiberty thingies are no longer declared here. We include libiberty.h
|
||||
above, instead. */
|
||||
|
|
@ -1223,14 +1122,22 @@ extern void *alloca ();
|
|||
#endif /* Not GNU C */
|
||||
#endif /* alloca not defined */
|
||||
|
||||
/* Is GDB multi-arch? If there's a "tm.h" file, it is not. */
|
||||
#ifndef GDB_MULTI_ARCH
|
||||
#ifdef GDB_TM_FILE
|
||||
#define GDB_MULTI_ARCH GDB_MULTI_ARCH_PARTIAL
|
||||
#else
|
||||
#define GDB_MULTI_ARCH GDB_MULTI_ARCH_PURE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Dynamic target-system-dependent parameters for GDB. */
|
||||
#include "gdbarch.h"
|
||||
#if (GDB_MULTI_ARCH == 0)
|
||||
/* Multi-arch targets _should_ be including "arch-utils.h" directly
|
||||
into their *-tdep.c file. This is a prop to help old non-
|
||||
multi-arch targets to continue to compile. */
|
||||
#include "arch-utils.h"
|
||||
#endif
|
||||
|
||||
/* Maximum size of a register. Something small, but large enough for
|
||||
all known ISAs. If it turns out to be too small, make it bigger. */
|
||||
|
||||
enum { MAX_REGISTER_SIZE = 16 };
|
||||
|
||||
/* Static target-system-dependent parameters for GDB. */
|
||||
|
||||
|
|
@ -1261,22 +1168,18 @@ extern void *alloca ();
|
|||
|
||||
/* In findvar.c. */
|
||||
|
||||
extern LONGEST extract_signed_integer (void *, int);
|
||||
extern LONGEST extract_signed_integer (const void *, int);
|
||||
|
||||
extern ULONGEST extract_unsigned_integer (void *, int);
|
||||
extern ULONGEST extract_unsigned_integer (const void *, int);
|
||||
|
||||
extern int extract_long_unsigned_integer (void *, int, LONGEST *);
|
||||
extern int extract_long_unsigned_integer (const void *, int, LONGEST *);
|
||||
|
||||
extern CORE_ADDR extract_address (void *, int);
|
||||
|
||||
extern CORE_ADDR extract_typed_address (void *buf, struct type *type);
|
||||
extern CORE_ADDR extract_typed_address (const void *buf, struct type *type);
|
||||
|
||||
extern void store_signed_integer (void *, int, LONGEST);
|
||||
|
||||
extern void store_unsigned_integer (void *, int, ULONGEST);
|
||||
|
||||
extern void store_address (void *, int, LONGEST);
|
||||
|
||||
extern void store_typed_address (void *buf, struct type *type, CORE_ADDR addr);
|
||||
|
||||
|
||||
|
|
@ -1397,4 +1300,36 @@ extern int use_windows;
|
|||
#define ISATTY(FP) (isatty (fileno (FP)))
|
||||
#endif
|
||||
|
||||
/* Ensure that V is aligned to an N byte boundary (B's assumed to be a
|
||||
power of 2). Round up/down when necessary. Examples of correct
|
||||
use include:
|
||||
|
||||
addr = align_up (addr, 8); -- VALUE needs 8 byte alignment
|
||||
write_memory (addr, value, len);
|
||||
addr += len;
|
||||
|
||||
and:
|
||||
|
||||
sp = align_down (sp - len, 16); -- Keep SP 16 byte aligned
|
||||
write_memory (sp, value, len);
|
||||
|
||||
Note that uses such as:
|
||||
|
||||
write_memory (addr, value, len);
|
||||
addr += align_up (len, 8);
|
||||
|
||||
and:
|
||||
|
||||
sp -= align_up (len, 8);
|
||||
write_memory (sp, value, len);
|
||||
|
||||
are typically not correct as they don't ensure that the address (SP
|
||||
or ADDR) is correctly aligned (relying on previous alignment to
|
||||
keep things right). This is also why the methods are called
|
||||
"align_..." instead of "round_..." as the latter reads better with
|
||||
this incorrect coding style. */
|
||||
|
||||
extern ULONGEST align_up (ULONGEST v, int n);
|
||||
extern ULONGEST align_down (ULONGEST v, int n);
|
||||
|
||||
#endif /* #ifndef DEFS_H */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
/* Basic C++ demangling support for GDB.
|
||||
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
|
||||
2001, 2003 Free Software Foundation, Inc.
|
||||
|
||||
Written by Fred Fish at Cygnus Support.
|
||||
|
||||
This file is part of GDB.
|
||||
|
|
@ -87,8 +89,8 @@ set_demangling_command (char *ignore, int from_tty, struct cmd_list_element *c)
|
|||
dem->demangling_style != unknown_demangling;
|
||||
dem++)
|
||||
{
|
||||
if (STREQ (current_demangling_style_string,
|
||||
dem->demangling_style_name))
|
||||
if (strcmp (current_demangling_style_string,
|
||||
dem->demangling_style_name) == 0)
|
||||
{
|
||||
current_demangling_style = dem->demangling_style;
|
||||
break;
|
||||
|
|
@ -150,24 +152,18 @@ set_demangling_style (char *style)
|
|||
set_demangling_command ((char *) NULL, 0, (struct cmd_list_element *) NULL);
|
||||
}
|
||||
|
||||
/* In order to allow a single demangler executable to demangle strings
|
||||
using various common values of CPLUS_MARKER, as well as any specific
|
||||
one set at compile time, we maintain a string containing all the
|
||||
commonly used ones, and check to see if the marker we are looking for
|
||||
is in that string. CPLUS_MARKER is usually '$' on systems where the
|
||||
assembler can deal with that. Where the assembler can't, it's usually
|
||||
'.' (but on many systems '.' is used for other things). We put the
|
||||
current defined CPLUS_MARKER first (which defaults to '$'), followed
|
||||
by the next most common value, followed by an explicit '$' in case
|
||||
the value of CPLUS_MARKER is not '$'.
|
||||
/* G++ uses a special character to indicate certain internal names. Which
|
||||
character it is depends on the platform:
|
||||
- Usually '$' on systems where the assembler will accept that
|
||||
- Usually '.' otherwise (this includes most sysv4-like systems and most
|
||||
ELF targets)
|
||||
- Occasionally '_' if neither of the above is usable
|
||||
|
||||
We could avoid this if we could just get g++ to tell us what the actual
|
||||
cplus marker character is as part of the debug information, perhaps by
|
||||
ensuring that it is the character that terminates the gcc<n>_compiled
|
||||
marker symbol (FIXME). */
|
||||
We check '$' first because it is the safest, and '.' often has another
|
||||
meaning. We don't currently try to handle '_' because the precise forms
|
||||
of the names are different on those targets. */
|
||||
|
||||
static char cplus_markers[] =
|
||||
{CPLUS_MARKER, '.', '$', '\0'};
|
||||
static char cplus_markers[] = {'$', '.', '\0'};
|
||||
|
||||
int
|
||||
is_cplus_marker (int c)
|
||||
|
|
@ -204,5 +200,4 @@ Use `set demangle-style' without arguments for a list of demangling styles.",
|
|||
|
||||
/* Set the default demangling style chosen at compilation time. */
|
||||
set_demangling_style (DEFAULT_DEMANGLING_STYLE);
|
||||
set_cplus_marker_for_demangling (CPLUS_MARKER);
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -3,13 +3,12 @@
|
|||
|
||||
@c @finalout
|
||||
|
||||
@ifinfo
|
||||
@format
|
||||
START-INFO-DIR-ENTRY
|
||||
* Stabs: (stabs). The "stabs" debugging information format.
|
||||
END-INFO-DIR-ENTRY
|
||||
@end format
|
||||
@end ifinfo
|
||||
@c This is a dir.info fragment to support semi-automated addition of
|
||||
@c manuals to an info tree.
|
||||
@dircategory Software development
|
||||
@direntry
|
||||
* Stabs: (stabs). The "stabs" debugging information format.
|
||||
@end direntry
|
||||
|
||||
@ifinfo
|
||||
This document describes the stabs debugging symbol tables.
|
||||
|
|
@ -22,12 +21,9 @@ and David MacKenzie.
|
|||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.1 or
|
||||
any later version published by the Free Software Foundation; with no
|
||||
Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,''
|
||||
and with the Back-Cover Texts as in (a) below.
|
||||
|
||||
(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
|
||||
this GNU Manual, like GNU software. Copies published by the Free
|
||||
Software Foundation raise funds for GNU development.''
|
||||
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
|
||||
Texts. A copy of the license is included in the section entitled ``GNU
|
||||
Free Documentation License''.
|
||||
@end ifinfo
|
||||
|
||||
@setchapternewpage odd
|
||||
|
|
@ -54,13 +50,9 @@ Contributed by Cygnus Support.
|
|||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.1 or
|
||||
any later version published by the Free Software Foundation; with no
|
||||
Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,''
|
||||
and with the Back-Cover Texts as in (a) below.
|
||||
|
||||
(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
|
||||
this GNU Manual, like GNU software. Copies published by the Free
|
||||
Software Foundation raise funds for GNU development.''
|
||||
|
||||
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
|
||||
Texts. A copy of the license is included in the section entitled ``GNU
|
||||
Free Documentation License''.
|
||||
@end titlepage
|
||||
|
||||
@ifinfo
|
||||
|
|
@ -85,6 +77,7 @@ This document describes the stabs debugging format.
|
|||
* Stab Sections:: In some object file formats, stabs are
|
||||
in sections.
|
||||
* Symbol Types Index:: Index of symbolic stab symbol type names.
|
||||
* GNU Free Documentation License:: The license for this documentation
|
||||
@end menu
|
||||
@end ifinfo
|
||||
|
||||
|
|
@ -259,10 +252,10 @@ 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
|
||||
any type attributes they do not recognize. GDB 4.9 and other versions
|
||||
of dbx may not do this. Because of a conflict with C++
|
||||
of dbx may not do this. Because of a conflict with C@t{++}
|
||||
(@pxref{Cplusplus}), new attributes should not be defined which begin
|
||||
with a digit, @samp{(}, or @samp{-}; GDB may be unable to distinguish
|
||||
those from the C++ type descriptor @samp{@@}. The attributes are:
|
||||
those from the C@t{++} type descriptor @samp{@@}. The attributes are:
|
||||
|
||||
@table @code
|
||||
@item a@var{boundary}
|
||||
|
|
@ -287,6 +280,12 @@ Indicate that this type is a string instead of an array of characters,
|
|||
or a bitstring instead of a set. It doesn't change the layout of the
|
||||
data being represented, but does enable the debugger to know which type
|
||||
it is.
|
||||
|
||||
@item V
|
||||
Indicate that this type is a vector instead of an array. The only
|
||||
major difference between vectors and arrays is that vectors are
|
||||
passed by value instead of by reference (vector coprocessor extension).
|
||||
|
||||
@end table
|
||||
|
||||
All of this can make the string field quite long. All versions of GDB,
|
||||
|
|
@ -431,7 +430,7 @@ Some compilers (for example, GCC2 and SunOS4 @file{/bin/cc}) also
|
|||
include the directory in which the source was compiled, in a second
|
||||
@code{N_SO} symbol preceding the one containing the file name. This
|
||||
symbol can be distinguished by the fact that it ends in a slash. Code
|
||||
from the @code{cfront} C++ compiler can have additional @code{N_SO} symbols for
|
||||
from the @code{cfront} C@t{++} compiler can have additional @code{N_SO} symbols for
|
||||
nonexistent source files after the @code{N_SO} for the real source file;
|
||||
these are believed to contain no useful information.
|
||||
|
||||
|
|
@ -1766,7 +1765,7 @@ Another way is with the @samp{x} type descriptor, which is followed by
|
|||
@samp{s} for a structure tag, @samp{u} for a union tag, or @samp{e} for
|
||||
a enumerator tag, followed by the name of the tag, followed by @samp{:}.
|
||||
If the name contains @samp{::} between a @samp{<} and @samp{>} pair (for
|
||||
C++ templates), such a @samp{::} does not end the name---only a single
|
||||
C@t{++} templates), such a @samp{::} does not end the name---only a single
|
||||
@samp{:} ends the name; see @ref{Nested Symbols}.
|
||||
|
||||
For example, the following C declarations:
|
||||
|
|
@ -2041,8 +2040,9 @@ definition narrows the symbol type to structure.
|
|||
|
||||
Following the @samp{s} type descriptor is the number of bytes the
|
||||
structure occupies, followed by a description of each structure element.
|
||||
The structure element descriptions are of the form @var{name:type, bit
|
||||
offset from the start of the struct, number of bits in the element}.
|
||||
The structure element descriptions are of the form
|
||||
@samp{@var{name}:@var{type}, @var{bit offset from the start of the
|
||||
struct}, @var{number of bits in the element}}.
|
||||
|
||||
@c FIXME: phony line break. Can probably be fixed by using an example
|
||||
@c with fewer fields.
|
||||
|
|
@ -2062,13 +2062,13 @@ The @code{s_next} field is a pointer to the same kind of structure that
|
|||
the field is an element of. So the definition of structure type 16
|
||||
contains a type definition for an element which is a pointer to type 16.
|
||||
|
||||
If a field is a static member (this is a C++ feature in which a single
|
||||
If a field is a static member (this is a C@t{++} feature in which a single
|
||||
variable appears to be a field of every structure of a given type) it
|
||||
still starts out with the field name, a colon, and the type, but then
|
||||
instead of a comma, bit position, comma, and bit size, there is a colon
|
||||
followed by the name of the variable which each such field refers to.
|
||||
|
||||
If the structure has methods (a C++ feature), they follow the non-method
|
||||
If the structure has methods (a C@t{++} feature), they follow the non-method
|
||||
fields; see @ref{Cplusplus}.
|
||||
|
||||
@node Typedefs
|
||||
|
|
@ -2140,8 +2140,8 @@ the stab describes an enumeration, structure, or union tag. The type
|
|||
descriptor @samp{u}, following the @samp{23=} of the type definition,
|
||||
narrows it down to a union type definition. Following the @samp{u} is
|
||||
the number of bytes in the union. After that is a list of union element
|
||||
descriptions. Their format is @var{name:type, bit offset into the
|
||||
union, number of bytes for the element;}.
|
||||
descriptions. Their format is @samp{@var{name}:@var{type}, @var{bit
|
||||
offset into the union}, @var{number of bytes for the element};}.
|
||||
|
||||
The stab for the union variable is:
|
||||
|
||||
|
|
@ -2389,7 +2389,7 @@ Symnum n_type n_othr n_desc n_value n_strx String
|
|||
@end example
|
||||
|
||||
@node Cplusplus
|
||||
@chapter GNU C++ Stabs
|
||||
@chapter GNU C@t{++} Stabs
|
||||
|
||||
@menu
|
||||
* Class Names:: C++ class names are both tags and typedefs.
|
||||
|
|
@ -2409,9 +2409,9 @@ Symnum n_type n_othr n_desc n_value n_strx String
|
|||
@end menu
|
||||
|
||||
@node Class Names
|
||||
@section C++ Class Names
|
||||
@section C@t{++} Class Names
|
||||
|
||||
In C++, a class name which is declared with @code{class}, @code{struct},
|
||||
In C@t{++}, a class name which is declared with @code{class}, @code{struct},
|
||||
or @code{union}, is not only a tag, as in C, but also a type name. Thus
|
||||
there should be stabs with both @samp{t} and @samp{T} symbol descriptors
|
||||
(@pxref{Typedefs}).
|
||||
|
|
@ -2420,7 +2420,7 @@ To save space, there is a special abbreviation for this case. If the
|
|||
@samp{T} symbol descriptor is followed by @samp{t}, then the stab
|
||||
defines both a type name and a tag.
|
||||
|
||||
For example, the C++ code
|
||||
For example, the C@t{++} code
|
||||
|
||||
@example
|
||||
struct foo @{int x;@};
|
||||
|
|
@ -2442,7 +2442,7 @@ or
|
|||
@node Nested Symbols
|
||||
@section Defining a Symbol Within Another Type
|
||||
|
||||
In C++, a symbol (such as a type name) can be defined within another type.
|
||||
In C@t{++}, a symbol (such as a type name) can be defined within another type.
|
||||
@c FIXME: Needs example.
|
||||
|
||||
In stabs, this is sometimes represented by making the name of a symbol
|
||||
|
|
@ -2457,12 +2457,12 @@ then @code{foo::bar::baz} is the name of the symbol, @samp{t} is the
|
|||
symbol descriptor, and @samp{5=*6} is the type information.
|
||||
|
||||
@node Basic Cplusplus Types
|
||||
@section Basic Types For C++
|
||||
@section Basic Types For C@t{++}
|
||||
|
||||
<< the examples that follow are based on a01.C >>
|
||||
|
||||
|
||||
C++ adds two more builtin types to the set defined for C. These are
|
||||
C@t{++} adds two more builtin types to the set defined for C. These are
|
||||
the unknown type and the vtable record type. The unknown type, type
|
||||
16, is defined in terms of itself like the void type.
|
||||
|
||||
|
|
@ -2473,7 +2473,7 @@ pfn, and delta2. pfn is the function pointer.
|
|||
<< In boilerplate $vtbl_ptr_type, what are the fields delta,
|
||||
index, and delta2 used for? >>
|
||||
|
||||
This basic type is present in all C++ programs even if there are no
|
||||
This basic type is present in all C@t{++} programs even if there are no
|
||||
virtual methods defined.
|
||||
|
||||
@display
|
||||
|
|
@ -2503,8 +2503,8 @@ virtual methods defined.
|
|||
@node Simple Classes
|
||||
@section Simple Class Definition
|
||||
|
||||
The stabs describing C++ language features are an extension of the
|
||||
stabs describing C. Stabs representing C++ class types elaborate
|
||||
The stabs describing C@t{++} language features are an extension of the
|
||||
stabs describing C. Stabs representing C@t{++} class types elaborate
|
||||
extensively on the stab format used to describe structure types in C.
|
||||
Stabs representing class type variables look just like stabs
|
||||
representing C language variables.
|
||||
|
|
@ -2526,20 +2526,20 @@ stab is not located between an @code{N_FUN} and an @code{N_LBRAC} stab this indi
|
|||
that the class is defined at file scope. If it were, then the @code{N_LSYM}
|
||||
would signify a local variable.
|
||||
|
||||
A stab describing a C++ class type is similar in format to a stab
|
||||
A stab describing a C@t{++} class type is similar in format to a stab
|
||||
describing a C struct, with each class member shown as a field in the
|
||||
structure. The part of the struct format describing fields is
|
||||
expanded to include extra information relevant to C++ class members.
|
||||
expanded to include extra information relevant to C@t{++} class members.
|
||||
In addition, if the class has multiple base classes or virtual
|
||||
functions the struct format outside of the field parts is also
|
||||
augmented.
|
||||
|
||||
In this simple example the field part of the C++ class stab
|
||||
In this simple example the field part of the C@t{++} class stab
|
||||
representing member data looks just like the field part of a C struct
|
||||
stab. The section on protections describes how its format is
|
||||
sometimes extended for member data.
|
||||
|
||||
The field part of a C++ class stab representing a member function
|
||||
The field part of a C@t{++} class stab representing a member function
|
||||
differs substantially from the field part of a C struct stab. It
|
||||
still begins with @samp{name:} but then goes on to define a new type number
|
||||
for the member function, describe its return type, its argument types,
|
||||
|
|
@ -2566,7 +2566,7 @@ occur in the @var{operator-name} string.
|
|||
The next part of the method description represents the arguments to the
|
||||
method, preceded by a colon and ending with a semi-colon. The types of
|
||||
the arguments are expressed in the same way argument types are expressed
|
||||
in C++ name mangling. In this example an @code{int} and a @code{char}
|
||||
in C@t{++} name mangling. In this example an @code{int} and a @code{char}
|
||||
map to @samp{ic}.
|
||||
|
||||
This is followed by a number, a letter, and an asterisk or period,
|
||||
|
|
@ -2600,7 +2600,7 @@ information present for virtual methods.
|
|||
@node Class Instance
|
||||
@section Class Instance
|
||||
|
||||
As shown above, describing even a simple C++ class definition is
|
||||
As shown above, describing even a simple C@t{++} class definition is
|
||||
accomplished by massively extending the stab format used in C to
|
||||
describe structure types. However, once the class is defined, C stabs
|
||||
with no modifications can be used to describe class instances. The
|
||||
|
|
@ -2627,7 +2627,7 @@ different from a standard C stab describing a local variable.
|
|||
@node Methods
|
||||
@section Method Definition
|
||||
|
||||
The class definition shown above declares Ameth. The C++ source below
|
||||
The class definition shown above declares Ameth. The C@t{++} source below
|
||||
defines Ameth:
|
||||
|
||||
@example
|
||||
|
|
@ -2718,15 +2718,26 @@ compiler it can also be used in other contexts.
|
|||
@node Member Type Descriptor
|
||||
@section The @samp{@@} Type Descriptor
|
||||
|
||||
The @samp{@@} type descriptor is for a member (class and variable) type.
|
||||
It is followed by type information for the offset basetype, a comma, and
|
||||
type information for the type of the field being pointed to. (FIXME:
|
||||
this is acknowledged to be gibberish. Can anyone say what really goes
|
||||
here?).
|
||||
The @samp{@@} type descriptor is used together with the @samp{*} type
|
||||
descriptor for a pointer-to-non-static-member-data type. It is followed
|
||||
by type information for the class (or union), a comma, and type
|
||||
information for the member data.
|
||||
|
||||
The following C@t{++} source:
|
||||
|
||||
@smallexample
|
||||
typedef int A::*int_in_a;
|
||||
@end smallexample
|
||||
|
||||
generates the following stab:
|
||||
|
||||
@smallexample
|
||||
.stabs "int_in_a:t20=*21=@@19,1",128,0,0,0
|
||||
@end smallexample
|
||||
|
||||
Note that there is a conflict between this and type attributes
|
||||
(@pxref{String Field}); both use type descriptor @samp{@@}.
|
||||
Fortunately, the @samp{@@} type descriptor used in this C++ sense always
|
||||
Fortunately, the @samp{@@} type descriptor used in this C@t{++} sense always
|
||||
will be followed by a digit, @samp{(}, or @samp{-}, and type attributes
|
||||
never start with those things.
|
||||
|
||||
|
|
@ -2736,7 +2747,7 @@ never start with those things.
|
|||
In the simple class definition shown above all member data and
|
||||
functions were publicly accessible. The example that follows
|
||||
contrasts public, protected and privately accessible fields and shows
|
||||
how these protections are encoded in C++ stabs.
|
||||
how these protections are encoded in C@t{++} stabs.
|
||||
|
||||
If the character following the @samp{@var{field-name}:} part of the
|
||||
string is @samp{/}, then the next character is the visibility. @samp{0}
|
||||
|
|
@ -2750,7 +2761,7 @@ an optimized out field with a private or protected visibility).
|
|||
Visibility @samp{9} is not supported by GDB 4.11; this should be fixed
|
||||
in the next GDB release.
|
||||
|
||||
The following C++ source:
|
||||
The following C@t{++} source:
|
||||
|
||||
@example
|
||||
class vis @{
|
||||
|
|
@ -2780,7 +2791,7 @@ type float (@samp{12}), and offset and size @samp{,64,32;}.
|
|||
|
||||
Protections for member functions are signified by one digit embedded in
|
||||
the field part of the stab describing the method. The digit is 0 if
|
||||
private, 1 if protected and 2 if public. Consider the C++ class
|
||||
private, 1 if protected and 2 if public. Consider the C@t{++} class
|
||||
definition below:
|
||||
|
||||
@example
|
||||
|
|
@ -2878,7 +2889,7 @@ struct is @samp{Adat}, an integer, starting at structure offset 0 and
|
|||
occupying 32 bits.
|
||||
|
||||
The second field in the class struct is not explicitly defined by the
|
||||
C++ class definition but is implied by the fact that the class
|
||||
C@t{++} class definition but is implied by the fact that the class
|
||||
contains a virtual method. This field is the vtable pointer. The
|
||||
name of the vtable pointer field starts with @samp{$vf} and continues with a
|
||||
type reference to the class it is part of. In this example the type
|
||||
|
|
@ -2890,7 +2901,7 @@ This is in turn defined as a pointer to another new type (22).
|
|||
|
||||
Type 22 is the vtable itself, which is defined as an array, indexed by
|
||||
a range of integers between 0 and 1, and whose elements are of type
|
||||
17. Type 17 was the vtable record type defined by the boilerplate C++
|
||||
17. Type 17 was the vtable record type defined by the boilerplate C@t{++}
|
||||
type definitions, as shown earlier.
|
||||
|
||||
The bit offset of the vtable pointer field is 32. The number of bits
|
||||
|
|
@ -2944,7 +2955,7 @@ class. This is preceded by @samp{~%} and followed by a final semi-colon.
|
|||
@node Inheritance
|
||||
@section Inheritance
|
||||
|
||||
Stabs describing C++ derived classes include additional sections that
|
||||
Stabs describing C@t{++} derived classes include additional sections that
|
||||
describe the inheritance hierarchy of the class. A derived class stab
|
||||
also encodes the number of base classes. For each base class it tells
|
||||
if the base class is virtual or not, and if the inheritance is private
|
||||
|
|
@ -3275,13 +3286,13 @@ GNU Modula2 definition module dependency; see @ref{N_DEFD}.
|
|||
Function start/body/end line numbers (Solaris2).
|
||||
|
||||
@item 0x50 N_EHDECL
|
||||
GNU C++ exception variable; see @ref{N_EHDECL}.
|
||||
GNU C@t{++} exception variable; see @ref{N_EHDECL}.
|
||||
|
||||
@item 0x50 N_MOD2
|
||||
Modula2 info "for imc" (according to Ultrix V4.0); see @ref{N_MOD2}.
|
||||
|
||||
@item 0x54 N_CATCH
|
||||
GNU C++ @code{catch} clause; see @ref{N_CATCH}.
|
||||
GNU C@t{++} @code{catch} clause; see @ref{N_CATCH}.
|
||||
|
||||
@item 0x60 N_SSYM
|
||||
Structure of union element; see @ref{N_SSYM}.
|
||||
|
|
@ -3375,7 +3386,7 @@ for more information about their use.
|
|||
Variable on the stack; see @ref{Stack Variables}.
|
||||
|
||||
@item :
|
||||
C++ nested symbol; see @xref{Nested Symbols}.
|
||||
C@t{++} nested symbol; see @xref{Nested Symbols}.
|
||||
|
||||
@item a
|
||||
Parameter passed by reference in register; see @ref{Reference Parameters}.
|
||||
|
|
@ -3388,7 +3399,7 @@ Constant; see @ref{Constants}.
|
|||
|
||||
@item C
|
||||
Conformant array bound (Pascal, maybe other languages); @ref{Conformant
|
||||
Arrays}. Name of a caught exception (GNU C++). These can be
|
||||
Arrays}. Name of a caught exception (GNU C@t{++}). These can be
|
||||
distinguished because the latter uses @code{N_CATCH} and the former uses
|
||||
another symbol type.
|
||||
|
||||
|
|
@ -3489,17 +3500,17 @@ Type reference; see @ref{String Field}.
|
|||
Reference to builtin type; see @ref{Negative Type Numbers}.
|
||||
|
||||
@item #
|
||||
Method (C++); see @ref{Method Type Descriptor}.
|
||||
Method (C@t{++}); see @ref{Method Type Descriptor}.
|
||||
|
||||
@item *
|
||||
Pointer; see @ref{Miscellaneous Types}.
|
||||
|
||||
@item &
|
||||
Reference (C++).
|
||||
Reference (C@t{++}).
|
||||
|
||||
@item @@
|
||||
Type Attributes (AIX); see @ref{String Field}. Member (class and variable)
|
||||
type (GNU C++); see @ref{Member Type Descriptor}.
|
||||
type (GNU C@t{++}); see @ref{Member Type Descriptor}.
|
||||
|
||||
@item a
|
||||
Array; see @ref{Arrays}.
|
||||
|
|
@ -3604,7 +3615,7 @@ Wide character; see @ref{Builtin Type Descriptors}.
|
|||
Cross-reference; see @ref{Cross-References}.
|
||||
|
||||
@item Y
|
||||
Used by IBM's xlC C++ compiler (for structures, I think).
|
||||
Used by IBM's xlC C@t{++} compiler (for structures, I think).
|
||||
|
||||
@item z
|
||||
gstring; see @ref{Strings}.
|
||||
|
|
@ -3746,7 +3757,7 @@ if it is imported with the GNU M2 keyword @code{%INITIALIZE}. Perhaps
|
|||
|
||||
@deffn @code{.stabs} N_EHDECL
|
||||
@findex N_EHDECL
|
||||
GNU C++ exception variable <<?>>.
|
||||
GNU C@t{++} exception variable <<?>>.
|
||||
|
||||
"@var{string} is variable name"
|
||||
|
||||
|
|
@ -3768,9 +3779,9 @@ Note: conflicts with @code{N_EHDECL} <<?>>
|
|||
|
||||
@deffn @code{.stabn} N_CATCH
|
||||
@findex N_CATCH
|
||||
GNU C++ @code{catch} clause
|
||||
GNU C@t{++} @code{catch} clause
|
||||
|
||||
GNU C++ @code{catch} clause. The value is its address. The desc field
|
||||
GNU C@t{++} @code{catch} clause. The value is its address. The desc field
|
||||
is nonzero if this entry is immediately followed by a @code{CAUGHT} stab
|
||||
saying what exception was caught. Multiple @code{CAUGHT} stabs means
|
||||
that multiple exceptions can be caught here. If desc is 0, it means all
|
||||
|
|
@ -4015,6 +4026,10 @@ is no more work than having the linker relocate ELF symbols, and it
|
|||
solves the problem of having to associate the ELF and stab symbols.
|
||||
However, no one has yet designed or implemented such a scheme.
|
||||
|
||||
@raisesections
|
||||
@include fdl.texi
|
||||
@lowersections
|
||||
|
||||
@node Symbol Types Index
|
||||
@unnumbered Symbol Types Index
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
/* Work with executable files, for GDB.
|
||||
Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
||||
1998, 1999, 2000, 2001, 2002
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
|
||||
1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
|
|
@ -30,12 +31,14 @@
|
|||
#include "objfiles.h"
|
||||
#include "completer.h"
|
||||
#include "value.h"
|
||||
#include "exec.h"
|
||||
|
||||
#ifdef USG
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include "readline/readline.h"
|
||||
#include "gdb_string.h"
|
||||
|
||||
#include "gdbcore.h"
|
||||
|
|
@ -54,8 +57,6 @@ void (*file_changed_hook) (char *);
|
|||
|
||||
/* Prototypes for local functions */
|
||||
|
||||
static void add_to_section_table (bfd *, sec_ptr, PTR);
|
||||
|
||||
static void exec_close (int);
|
||||
|
||||
static void file_command (char *, int);
|
||||
|
|
@ -64,8 +65,6 @@ static void set_section_command (char *, int);
|
|||
|
||||
static void exec_files_info (struct target_ops *);
|
||||
|
||||
static void bfdsec_to_vmap (bfd *, sec_ptr, PTR);
|
||||
|
||||
static int ignore (CORE_ADDR, char *);
|
||||
|
||||
static void init_exec_ops (void);
|
||||
|
|
@ -84,14 +83,6 @@ bfd *exec_bfd = NULL;
|
|||
|
||||
int write_files = 0;
|
||||
|
||||
/* Text start and end addresses (KLUDGE) if needed */
|
||||
|
||||
#ifndef NEED_TEXT_START_END
|
||||
#define NEED_TEXT_START_END (0)
|
||||
#endif
|
||||
CORE_ADDR text_start = 0;
|
||||
CORE_ADDR text_end = 0;
|
||||
|
||||
struct vmap *vmap;
|
||||
|
||||
void
|
||||
|
|
@ -101,7 +92,6 @@ exec_open (char *args, int from_tty)
|
|||
exec_file_attach (args, from_tty);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
exec_close (int quitting)
|
||||
{
|
||||
|
|
@ -242,7 +232,7 @@ exec_file_attach (char *filename, int from_tty)
|
|||
|
||||
/* FIXME - This should only be run for RS6000, but the ifdef is a poor
|
||||
way to accomplish. */
|
||||
#ifdef IBM6000_TARGET
|
||||
#ifdef DEPRECATED_IBM6000_TARGET
|
||||
/* Setup initial vmap. */
|
||||
|
||||
map_vmap (exec_bfd, 0);
|
||||
|
|
@ -254,7 +244,7 @@ exec_file_attach (char *filename, int from_tty)
|
|||
error ("\"%s\": can't find the file sections: %s",
|
||||
scratch_pathname, bfd_errmsg (bfd_get_error ()));
|
||||
}
|
||||
#endif /* IBM6000_TARGET */
|
||||
#endif /* DEPRECATED_IBM6000_TARGET */
|
||||
|
||||
if (build_section_table (exec_bfd, &exec_ops.to_sections,
|
||||
&exec_ops.to_sections_end))
|
||||
|
|
@ -266,30 +256,9 @@ exec_file_attach (char *filename, int from_tty)
|
|||
scratch_pathname, bfd_errmsg (bfd_get_error ()));
|
||||
}
|
||||
|
||||
/* text_end is sometimes used for where to put call dummies. A
|
||||
few ports use these for other purposes too. */
|
||||
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;
|
||||
}
|
||||
}
|
||||
#ifdef DEPRECATED_HPUX_TEXT_END
|
||||
DEPRECATED_HPUX_TEXT_END (&exec_ops);
|
||||
#endif
|
||||
|
||||
validate_files ();
|
||||
|
||||
|
|
@ -365,7 +334,8 @@ file_command (char *arg, int from_tty)
|
|||
we cast it back to its proper type. */
|
||||
|
||||
static void
|
||||
add_to_section_table (bfd *abfd, sec_ptr asect, PTR table_pp_char)
|
||||
add_to_section_table (bfd *abfd, struct bfd_section *asect,
|
||||
void *table_pp_char)
|
||||
{
|
||||
struct section_table **table_pp = (struct section_table **) table_pp_char;
|
||||
flagword aflag;
|
||||
|
|
@ -386,7 +356,7 @@ add_to_section_table (bfd *abfd, sec_ptr asect, PTR table_pp_char)
|
|||
Returns 0 if OK, 1 on error. */
|
||||
|
||||
int
|
||||
build_section_table (bfd *some_bfd, struct section_table **start,
|
||||
build_section_table (struct bfd *some_bfd, struct section_table **start,
|
||||
struct section_table **end)
|
||||
{
|
||||
unsigned count;
|
||||
|
|
@ -404,7 +374,7 @@ build_section_table (bfd *some_bfd, struct section_table **start,
|
|||
}
|
||||
|
||||
static void
|
||||
bfdsec_to_vmap (bfd *abfd, sec_ptr sect, PTR arg3)
|
||||
bfdsec_to_vmap (struct bfd *abfd, struct bfd_section *sect, void *arg3)
|
||||
{
|
||||
struct vmap_and_bfd *vmap_bfd = (struct vmap_and_bfd *) arg3;
|
||||
struct vmap *vp;
|
||||
|
|
@ -414,14 +384,14 @@ bfdsec_to_vmap (bfd *abfd, sec_ptr sect, PTR arg3)
|
|||
if ((bfd_get_section_flags (abfd, sect) & SEC_LOAD) == 0)
|
||||
return;
|
||||
|
||||
if (STREQ (bfd_section_name (abfd, sect), ".text"))
|
||||
if (DEPRECATED_STREQ (bfd_section_name (abfd, sect), ".text"))
|
||||
{
|
||||
vp->tstart = bfd_section_vma (abfd, sect);
|
||||
vp->tend = vp->tstart + bfd_section_size (abfd, sect);
|
||||
vp->tvma = bfd_section_vma (abfd, sect);
|
||||
vp->toffs = sect->filepos;
|
||||
}
|
||||
else if (STREQ (bfd_section_name (abfd, sect), ".data"))
|
||||
else if (DEPRECATED_STREQ (bfd_section_name (abfd, sect), ".data"))
|
||||
{
|
||||
vp->dstart = bfd_section_vma (abfd, sect);
|
||||
vp->dend = vp->dstart + bfd_section_size (abfd, sect);
|
||||
|
|
@ -481,10 +451,9 @@ xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
|
|||
struct mem_attrib *attrib,
|
||||
struct target_ops *target)
|
||||
{
|
||||
boolean res;
|
||||
int res;
|
||||
struct section_table *p;
|
||||
CORE_ADDR nextsectaddr, memend;
|
||||
boolean (*xfer_fn) (bfd *, sec_ptr, PTR, file_ptr, bfd_size_type);
|
||||
asection *section = NULL;
|
||||
|
||||
if (len <= 0)
|
||||
|
|
@ -498,7 +467,6 @@ xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
|
|||
}
|
||||
|
||||
memend = memaddr + len;
|
||||
xfer_fn = write ? bfd_set_section_contents : bfd_get_section_contents;
|
||||
nextsectaddr = memend;
|
||||
|
||||
for (p = target->to_sections; p < target->to_sections_end; p++)
|
||||
|
|
@ -507,26 +475,40 @@ xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
|
|||
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 (memaddr >= p->endaddr)
|
||||
{
|
||||
/* This section ends before the transfer starts. */
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This section overlaps the transfer. Just do half. */
|
||||
len = p->endaddr - memaddr;
|
||||
res = xfer_fn (p->bfd, p->the_bfd_section, myaddr,
|
||||
memaddr - p->addr, len);
|
||||
return (res != 0) ? len : 0;
|
||||
}
|
||||
{
|
||||
if (memend <= p->endaddr)
|
||||
{
|
||||
/* Entire transfer is within this section. */
|
||||
if (write)
|
||||
res = bfd_set_section_contents (p->bfd, p->the_bfd_section,
|
||||
myaddr, memaddr - p->addr,
|
||||
len);
|
||||
else
|
||||
res = bfd_get_section_contents (p->bfd, p->the_bfd_section,
|
||||
myaddr, memaddr - p->addr,
|
||||
len);
|
||||
return (res != 0) ? len : 0;
|
||||
}
|
||||
else if (memaddr >= p->endaddr)
|
||||
{
|
||||
/* This section ends before the transfer starts. */
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This section overlaps the transfer. Just do half. */
|
||||
len = p->endaddr - memaddr;
|
||||
if (write)
|
||||
res = bfd_set_section_contents (p->bfd, p->the_bfd_section,
|
||||
myaddr, memaddr - p->addr,
|
||||
len);
|
||||
else
|
||||
res = bfd_get_section_contents (p->bfd, p->the_bfd_section,
|
||||
myaddr, memaddr - p->addr,
|
||||
len);
|
||||
return (res != 0) ? len : 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
nextsectaddr = min (nextsectaddr, p->addr);
|
||||
}
|
||||
|
|
@ -542,6 +524,8 @@ void
|
|||
print_section_info (struct target_ops *t, bfd *abfd)
|
||||
{
|
||||
struct section_table *p;
|
||||
/* FIXME: "016l" is not wide enough when TARGET_ADDR_BIT > 64. */
|
||||
char *fmt = TARGET_ADDR_BIT <= 32 ? "08l" : "016l";
|
||||
|
||||
printf_filtered ("\t`%s', ", bfd_get_filename (abfd));
|
||||
wrap_here (" ");
|
||||
|
|
@ -554,12 +538,17 @@ print_section_info (struct target_ops *t, bfd *abfd)
|
|||
}
|
||||
for (p = t->to_sections; p < t->to_sections_end; p++)
|
||||
{
|
||||
/* FIXME-32x64 need a print_address_numeric with field width */
|
||||
printf_filtered ("\t%s", local_hex_string_custom ((unsigned long) p->addr, "08l"));
|
||||
printf_filtered (" - %s", local_hex_string_custom ((unsigned long) p->endaddr, "08l"));
|
||||
printf_filtered ("\t%s", local_hex_string_custom (p->addr, fmt));
|
||||
printf_filtered (" - %s", local_hex_string_custom (p->endaddr, fmt));
|
||||
|
||||
/* FIXME: A format of "08l" is not wide enough for file offsets
|
||||
larger than 4GB. OTOH, making it "016l" isn't desirable either
|
||||
since most output will then be much wider than necessary. It
|
||||
may make sense to test the size of the file and choose the
|
||||
format string accordingly. */
|
||||
if (info_verbose)
|
||||
printf_filtered (" @ %s",
|
||||
local_hex_string_custom ((unsigned long) p->the_bfd_section->filepos, "08l"));
|
||||
local_hex_string_custom (p->the_bfd_section->filepos, "08l"));
|
||||
printf_filtered (" is %s", bfd_section_name (p->bfd, p->the_bfd_section));
|
||||
if (p->bfd != abfd)
|
||||
{
|
||||
|
|
@ -712,14 +701,11 @@ Specify the filename of the executable file.";
|
|||
exec_ops.to_open = exec_open;
|
||||
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_make_corefile_notes = exec_make_note_section;
|
||||
|
|
@ -742,7 +728,7 @@ 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;
|
||||
set_cmd_completer (c, filename_completer);
|
||||
}
|
||||
|
||||
c = add_cmd ("exec-file", class_files, exec_file_command,
|
||||
|
|
@ -750,7 +736,7 @@ No arg means to have no executable file and no symbols.", &cmdlist);
|
|||
If FILE cannot be found as specified, your execution directory path\n\
|
||||
is searched for a command of that name.\n\
|
||||
No arg means have no executable file.", &cmdlist);
|
||||
c->completer = filename_completer;
|
||||
set_cmd_completer (c, filename_completer);
|
||||
|
||||
add_com ("section", class_files, set_section_command,
|
||||
"Change the base address of section SECTION of the exec file to ADDR.\n\
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Replay a remote debug session logfile for GDB.
|
||||
Copyright 1996, 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
Copyright 1996, 1998, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
|
||||
Written by Fred Fish (fnf@cygnus.com) from pieces of gdbserver.
|
||||
|
||||
This file is part of GDB.
|
||||
|
|
@ -54,14 +54,15 @@ static void
|
|||
perror_with_name (char *string)
|
||||
{
|
||||
#ifndef STDC_HEADERS
|
||||
extern int sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
extern int errno;
|
||||
#endif
|
||||
const char *err;
|
||||
char *combined;
|
||||
|
||||
err = (errno < sys_nerr) ? sys_errlist[errno] : "unknown error";
|
||||
err = strerror (errno);
|
||||
if (err == NULL)
|
||||
err = "unknown error";
|
||||
|
||||
combined = (char *) alloca (strlen (err) + strlen (string) + 3);
|
||||
strcpy (combined, string);
|
||||
strcat (combined, ": ");
|
||||
|
|
@ -93,10 +94,6 @@ remote_close (void)
|
|||
static void
|
||||
remote_open (char *name)
|
||||
{
|
||||
#ifndef HAVE_STRING_H
|
||||
extern char *strchr ();
|
||||
#endif
|
||||
|
||||
if (!strchr (name, ':'))
|
||||
{
|
||||
fprintf (stderr, "%s: Must specify tcp connection as host:addr\n", name);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* General utility routines for the remote server for GDB.
|
||||
Copyright 1986, 1989, 1993, 1995, 1996, 1997, 1999, 2000, 2002
|
||||
Copyright 1986, 1989, 1993, 1995, 1996, 1997, 1999, 2000, 2002, 2003
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
|
@ -33,16 +33,13 @@ void
|
|||
perror_with_name (char *string)
|
||||
{
|
||||
#ifndef STDC_HEADERS
|
||||
extern int sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
extern int errno;
|
||||
#endif
|
||||
const char *err;
|
||||
char *combined;
|
||||
|
||||
if (errno < sys_nerr)
|
||||
err = sys_errlist[errno];
|
||||
else
|
||||
err = strerror (errno);
|
||||
if (err == NULL)
|
||||
err = "unknown error";
|
||||
|
||||
combined = (char *) alloca (strlen (err) + strlen (string) + 3);
|
||||
|
|
@ -57,7 +54,7 @@ perror_with_name (char *string)
|
|||
STRING is the error message, used as a fprintf string,
|
||||
and ARG is passed as an argument to it. */
|
||||
|
||||
NORETURN void
|
||||
void
|
||||
error (const char *string,...)
|
||||
{
|
||||
extern jmp_buf toplevel;
|
||||
|
|
@ -74,7 +71,7 @@ error (const char *string,...)
|
|||
STRING and ARG are passed to fprintf. */
|
||||
|
||||
/* VARARGS */
|
||||
NORETURN void
|
||||
void
|
||||
fatal (const char *string,...)
|
||||
{
|
||||
va_list args;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
/* Native-dependent code for modern i386 BSD's.
|
||||
Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
|
|
@ -43,6 +43,7 @@ typedef struct fpreg fpregset_t;
|
|||
#endif
|
||||
|
||||
#include "gregset.h"
|
||||
#include "i386-tdep.h"
|
||||
|
||||
|
||||
/* In older BSD versions we cannot get at some of the segment
|
||||
|
|
@ -125,7 +126,7 @@ supply_gregset (gregset_t *gregsetp)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_GREGS; i++)
|
||||
for (i = 0; i < I386_NUM_GREGS; i++)
|
||||
{
|
||||
if (CANNOT_FETCH_REGISTER (i))
|
||||
supply_register (i, NULL);
|
||||
|
|
@ -143,12 +144,12 @@ fill_gregset (gregset_t *gregsetp, int regno)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_GREGS; i++)
|
||||
for (i = 0; i < I386_NUM_GREGS; i++)
|
||||
if ((regno == -1 || regno == i) && ! CANNOT_STORE_REGISTER (i))
|
||||
regcache_collect (i, REG_ADDR (gregsetp, i));
|
||||
}
|
||||
|
||||
#include "i387-nat.h"
|
||||
#include "i387-tdep.h"
|
||||
|
||||
/* Fill GDB's register array with the floating-point register values
|
||||
in *FPREGSETP. */
|
||||
|
|
@ -156,7 +157,7 @@ fill_gregset (gregset_t *gregsetp, int regno)
|
|||
void
|
||||
supply_fpregset (fpregset_t *fpregsetp)
|
||||
{
|
||||
i387_supply_fsave ((char *) fpregsetp);
|
||||
i387_supply_fsave (current_regcache, -1, fpregsetp);
|
||||
}
|
||||
|
||||
/* Fill register REGNO (if it is a floating-point register) in
|
||||
|
|
@ -175,7 +176,6 @@ fill_fpregset (fpregset_t *fpregsetp, int regno)
|
|||
void
|
||||
fetch_inferior_registers (int regno)
|
||||
{
|
||||
|
||||
if (regno == -1 || GETREGS_SUPPLIES (regno))
|
||||
{
|
||||
gregset_t gregs;
|
||||
|
|
@ -195,12 +195,12 @@ fetch_inferior_registers (int regno)
|
|||
#ifdef HAVE_PT_GETXMMREGS
|
||||
char xmmregs[512];
|
||||
|
||||
if (have_ptrace_xmmregs != 0 &&
|
||||
ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) xmmregs, 0) == 0)
|
||||
if (have_ptrace_xmmregs != 0
|
||||
&& ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) xmmregs, 0) == 0)
|
||||
{
|
||||
have_ptrace_xmmregs = 1;
|
||||
i387_supply_fxsave (xmmregs);
|
||||
i387_supply_fxsave (current_regcache, -1, xmmregs);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -208,14 +208,14 @@ fetch_inferior_registers (int regno)
|
|||
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
|
||||
perror_with_name ("Couldn't get floating point status");
|
||||
|
||||
supply_fpregset (&fpregs);
|
||||
i387_supply_fsave (current_regcache, -1, &fpregs);
|
||||
}
|
||||
#else
|
||||
if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
|
||||
perror_with_name ("Couldn't get floating point status");
|
||||
|
||||
supply_fpregset (&fpregs);
|
||||
i387_supply_fsave (current_regcache, -1, &fpregs);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -226,7 +226,6 @@ fetch_inferior_registers (int regno)
|
|||
void
|
||||
store_inferior_registers (int regno)
|
||||
{
|
||||
|
||||
if (regno == -1 || GETREGS_SUPPLIES (regno))
|
||||
{
|
||||
gregset_t gregs;
|
||||
|
|
@ -251,9 +250,9 @@ store_inferior_registers (int regno)
|
|||
#ifdef HAVE_PT_GETXMMREGS
|
||||
char xmmregs[512];
|
||||
|
||||
if (have_ptrace_xmmregs != 0 &&
|
||||
ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) xmmregs, 0) == 0)
|
||||
if (have_ptrace_xmmregs != 0
|
||||
&& ptrace(PT_GETXMMREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) xmmregs, 0) == 0)
|
||||
{
|
||||
have_ptrace_xmmregs = 1;
|
||||
|
||||
|
|
@ -271,7 +270,7 @@ store_inferior_registers (int regno)
|
|||
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
|
||||
perror_with_name ("Couldn't get floating point status");
|
||||
|
||||
fill_fpregset (&fpregs, regno);
|
||||
i387_fill_fsave ((char *) &fpregs, regno);
|
||||
|
||||
if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
|
||||
|
|
@ -305,7 +304,7 @@ i386bsd_dr_set (int regnum, unsigned int value)
|
|||
/* For some mysterious reason, some of the reserved bits in the
|
||||
debug control register get set. Mask these off, otherwise the
|
||||
ptrace call below will fail. */
|
||||
dbregs.dr7 &= ~(0x0000fc00);
|
||||
DBREG_DRX ((&dbregs), 7) &= ~(0x0000fc00);
|
||||
|
||||
DBREG_DRX ((&dbregs), regnum) = value;
|
||||
|
||||
|
|
@ -354,7 +353,7 @@ i386bsd_dr_get_status (void)
|
|||
return 0;
|
||||
#endif
|
||||
|
||||
return dbregs.dr6;
|
||||
return DBREG_DRX ((&dbregs), 6);
|
||||
}
|
||||
|
||||
#endif /* PT_GETDBREGS */
|
||||
|
|
@ -382,19 +381,76 @@ kernel_u_size (void)
|
|||
return (sizeof (struct user));
|
||||
}
|
||||
|
||||
/* See i386bsd-tdep.c. */
|
||||
extern int i386bsd_sigcontext_pc_offset;
|
||||
|
||||
void
|
||||
_initialize_i386bsd_nat (void)
|
||||
{
|
||||
int offset;
|
||||
|
||||
/* To support the recognition of signal handlers, i386bsd-tdep.c
|
||||
hardcodes some constants. Inclusion of this file means that we
|
||||
are compiling a native debugger, which means that we can use the
|
||||
system header files and sysctl(3) to get at the relevant
|
||||
information. */
|
||||
|
||||
#if defined (__FreeBSD_version) && __FreeBSD_version >= 400011
|
||||
#define SC_REG_OFFSET i386fbsd4_sc_reg_offset
|
||||
#elif defined (__FreeBSD_version) && __FreeBSD_version >= 300005
|
||||
#define SC_REG_OFFSET i386fbsd_sc_reg_offset
|
||||
#elif defined (NetBSD) || defined (__NetBSD_Version__)
|
||||
#define SC_REG_OFFSET i386nbsd_sc_reg_offset
|
||||
#elif defined (OpenBSD)
|
||||
#define SC_REG_OFFSET i386obsd_sc_reg_offset
|
||||
#else
|
||||
#define SC_REG_OFFSET i386bsd_sc_reg_offset
|
||||
#endif
|
||||
|
||||
/* We only check the program counter, stack pointer and frame
|
||||
pointer since these members of `struct sigcontext' are essential
|
||||
for providing backtraces. More checks could be added, but would
|
||||
involve adding configure checks for the appropriate structure
|
||||
members, since older BSD's don't provide all of them. */
|
||||
|
||||
#define SC_PC_OFFSET SC_REG_OFFSET[I386_EIP_REGNUM]
|
||||
#define SC_SP_OFFSET SC_REG_OFFSET[I386_ESP_REGNUM]
|
||||
#define SC_FP_OFFSET SC_REG_OFFSET[I386_EBP_REGNUM]
|
||||
|
||||
/* Override the default value for the offset of the program counter
|
||||
in the sigcontext structure. */
|
||||
i386bsd_sigcontext_pc_offset = offsetof (struct sigcontext, sc_pc);
|
||||
offset = offsetof (struct sigcontext, sc_pc);
|
||||
|
||||
if (SC_PC_OFFSET != offset)
|
||||
{
|
||||
warning ("\
|
||||
offsetof (struct sigcontext, sc_pc) yields %d instead of %d.\n\
|
||||
Please report this to <bug-gdb@gnu.org>.",
|
||||
offset, SC_PC_OFFSET);
|
||||
}
|
||||
|
||||
SC_PC_OFFSET = offset;
|
||||
|
||||
/* Likewise for the stack pointer. */
|
||||
offset = offsetof (struct sigcontext, sc_sp);
|
||||
|
||||
if (SC_SP_OFFSET != offset)
|
||||
{
|
||||
warning ("\
|
||||
offsetof (struct sigcontext, sc_sp) yields %d instead of %d.\n\
|
||||
Please report this to <bug-gdb@gnu.org>.",
|
||||
offset, SC_SP_OFFSET);
|
||||
}
|
||||
|
||||
SC_SP_OFFSET = offset;
|
||||
|
||||
/* And the frame pointer. */
|
||||
offset = offsetof (struct sigcontext, sc_fp);
|
||||
|
||||
if (SC_FP_OFFSET != offset)
|
||||
{
|
||||
warning ("\
|
||||
offsetof (struct sigcontext, sc_fp) yields %d instead of %d.\n\
|
||||
Please report this to <bug-gdb@gnu.org>.",
|
||||
offset, SC_FP_OFFSET);
|
||||
}
|
||||
|
||||
SC_FP_OFFSET = offset;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -208,6 +208,7 @@ ptrace_wait (ptid_t ptid, int *status)
|
|||
return wstate;
|
||||
}
|
||||
|
||||
#ifndef KILL_INFERIOR
|
||||
void
|
||||
kill_inferior (void)
|
||||
{
|
||||
|
|
@ -229,6 +230,7 @@ kill_inferior (void)
|
|||
ptrace_wait (null_ptid, &status);
|
||||
target_mourn_inferior ();
|
||||
}
|
||||
#endif /* KILL_INFERIOR */
|
||||
|
||||
#ifndef CHILD_RESUME
|
||||
|
||||
|
|
@ -302,7 +304,7 @@ detach (int signal)
|
|||
ptrace (PT_DETACH, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) 1,
|
||||
signal);
|
||||
if (errno)
|
||||
perror_with_name ("ptrace");
|
||||
print_sys_errmsg ("ptrace", errno);
|
||||
attach_flag = 0;
|
||||
}
|
||||
#endif /* ATTACH_DETACH */
|
||||
|
|
@ -357,14 +359,14 @@ fetch_register (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;
|
||||
int i;
|
||||
unsigned int offset; /* Offset of registers within the u area. */
|
||||
char *buf = alloca (MAX_REGISTER_RAW_SIZE);
|
||||
char buf[MAX_REGISTER_SIZE];
|
||||
int tid;
|
||||
|
||||
if (CANNOT_FETCH_REGISTER (regno))
|
||||
{
|
||||
memset (buf, '\0', REGISTER_RAW_SIZE (regno)); /* Supply zeroes */
|
||||
memset (buf, '\0', DEPRECATED_REGISTER_RAW_SIZE (regno)); /* Supply zeroes */
|
||||
supply_register (regno, buf);
|
||||
return;
|
||||
}
|
||||
|
|
@ -376,7 +378,7 @@ fetch_register (int regno)
|
|||
offset = U_REGS_OFFSET;
|
||||
|
||||
regaddr = register_addr (regno, offset);
|
||||
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
|
||||
for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
|
||||
{
|
||||
errno = 0;
|
||||
*(PTRACE_XFER_TYPE *) & buf[i] = ptrace (PT_READ_U, tid,
|
||||
|
|
@ -421,10 +423,10 @@ store_register (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;
|
||||
int i;
|
||||
unsigned int offset; /* Offset of registers within the u area. */
|
||||
int tid;
|
||||
char *buf = alloca (MAX_REGISTER_RAW_SIZE);
|
||||
char buf[MAX_REGISTER_SIZE];
|
||||
|
||||
if (CANNOT_STORE_REGISTER (regno))
|
||||
{
|
||||
|
|
@ -443,7 +445,7 @@ store_register (int regno)
|
|||
regcache_collect (regno, buf);
|
||||
|
||||
/* Store the local buffer into the inferior a chunk at the time. */
|
||||
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
|
||||
for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
|
||||
{
|
||||
errno = 0;
|
||||
ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr,
|
||||
|
|
@ -514,6 +516,37 @@ child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
|
|||
PTRACE_XFER_TYPE *buffer;
|
||||
struct cleanup *old_chain = NULL;
|
||||
|
||||
#ifdef PT_IO
|
||||
/* OpenBSD 3.1, NetBSD 1.6 and FreeBSD 5.0 have a new PT_IO request
|
||||
that promises to be much more efficient in reading and writing
|
||||
data in the traced process's address space. */
|
||||
|
||||
{
|
||||
struct ptrace_io_desc piod;
|
||||
|
||||
/* NOTE: We assume that there are no distinct address spaces for
|
||||
instruction and data. */
|
||||
piod.piod_op = write ? PIOD_WRITE_D : PIOD_READ_D;
|
||||
piod.piod_offs = (void *) memaddr;
|
||||
piod.piod_addr = myaddr;
|
||||
piod.piod_len = len;
|
||||
|
||||
if (ptrace (PT_IO, PIDGET (inferior_ptid), (caddr_t) &piod, 0) == -1)
|
||||
{
|
||||
/* If the PT_IO request is somehow not supported, fallback on
|
||||
using PT_WRITE_D/PT_READ_D. Otherwise we will return zero
|
||||
to indicate failure. */
|
||||
if (errno != EINVAL)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return the actual number of bytes read or written. */
|
||||
return piod.piod_len;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate buffer of that many longwords. */
|
||||
if (len < GDB_MAX_ALLOCA)
|
||||
{
|
||||
|
|
@ -598,7 +631,7 @@ static void
|
|||
udot_info (char *dummy1, int dummy2)
|
||||
{
|
||||
#if defined (KERNEL_U_SIZE)
|
||||
int udot_off; /* Offset into user struct */
|
||||
long udot_off; /* Offset into user struct */
|
||||
int udot_val; /* Value from user struct at udot_off */
|
||||
char mess[128]; /* For messages */
|
||||
#endif
|
||||
|
|
@ -626,12 +659,13 @@ udot_info (char *dummy1, int dummy2)
|
|||
{
|
||||
printf_filtered ("\n");
|
||||
}
|
||||
printf_filtered ("%04x:", udot_off);
|
||||
printf_filtered ("%s:", paddr (udot_off));
|
||||
}
|
||||
udot_val = ptrace (PT_READ_U, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) udot_off, 0);
|
||||
if (errno != 0)
|
||||
{
|
||||
sprintf (mess, "\nreading user struct at offset 0x%x", udot_off);
|
||||
sprintf (mess, "\nreading user struct at offset 0x%s",
|
||||
paddr_nz (udot_off));
|
||||
perror_with_name (mess);
|
||||
}
|
||||
/* Avoid using nonportable (?) "*" in print specs */
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
/* Top level stuff for GDB, the GNU debugger.
|
||||
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
|
||||
1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
|
||||
1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
|
|
@ -37,6 +38,9 @@
|
|||
#include "event-loop.h"
|
||||
#include "ui-out.h"
|
||||
|
||||
#include "interps.h"
|
||||
#include "main.h"
|
||||
|
||||
/* If nonzero, display time usage both at startup and for each command. */
|
||||
|
||||
int display_time;
|
||||
|
|
@ -51,26 +55,28 @@ int display_space;
|
|||
processes UI events asynchronously. */
|
||||
int event_loop_p = 1;
|
||||
|
||||
/* Has an interpreter been specified and if so, which. */
|
||||
/* The selected interpreter. This will be used as a set command
|
||||
variable, so it should always be malloc'ed - since
|
||||
do_setshow_command will free it. */
|
||||
char *interpreter_p;
|
||||
|
||||
/* Whether this is the command line version or not */
|
||||
int tui_version = 0;
|
||||
|
||||
/* Whether xdb commands will be handled */
|
||||
int xdb_commands = 0;
|
||||
|
||||
/* Whether dbx commands will be handled */
|
||||
int dbx_commands = 0;
|
||||
|
||||
/* System root path, used to find libraries etc. */
|
||||
char *gdb_sysroot = 0;
|
||||
|
||||
struct ui_file *gdb_stdout;
|
||||
struct ui_file *gdb_stderr;
|
||||
struct ui_file *gdb_stdlog;
|
||||
struct ui_file *gdb_stdin;
|
||||
/* target IO streams */
|
||||
struct ui_file *gdb_stdtargin;
|
||||
struct ui_file *gdb_stdtarg;
|
||||
|
||||
/* Used to initialize error() - defined in utils.c */
|
||||
|
||||
extern void error_init (void);
|
||||
struct ui_file *gdb_stdtargerr;
|
||||
|
||||
/* Whether to enable writing into executable and core files */
|
||||
extern int write_files;
|
||||
|
|
@ -88,10 +94,7 @@ extern char *external_editor_command;
|
|||
static int
|
||||
captured_command_loop (void *data)
|
||||
{
|
||||
if (command_loop_hook == NULL)
|
||||
command_loop ();
|
||||
else
|
||||
command_loop_hook ();
|
||||
current_interp_command_loop ();
|
||||
/* FIXME: cagney/1999-11-05: A correct command_loop() implementaton
|
||||
would clean things up (restoring the cleanup chain) to the state
|
||||
they were just prior to the call. Technically, this means that
|
||||
|
|
@ -108,12 +111,6 @@ captured_command_loop (void *data)
|
|||
return 1;
|
||||
}
|
||||
|
||||
struct captured_main_args
|
||||
{
|
||||
int argc;
|
||||
char **argv;
|
||||
};
|
||||
|
||||
static int
|
||||
captured_main (void *data)
|
||||
{
|
||||
|
|
@ -153,19 +150,25 @@ captured_main (void *data)
|
|||
struct stat homebuf, cwdbuf;
|
||||
char *homedir, *homeinit;
|
||||
|
||||
register int i;
|
||||
int i;
|
||||
|
||||
long time_at_startup = get_run_time ();
|
||||
|
||||
START_PROGRESS (argv[0], 0);
|
||||
|
||||
#ifdef MPW
|
||||
/* Do all Mac-specific setup. */
|
||||
mac_init ();
|
||||
#endif /* MPW */
|
||||
#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
|
||||
setlocale (LC_MESSAGES, "");
|
||||
#endif
|
||||
#if defined (HAVE_SETLOCALE)
|
||||
setlocale (LC_CTYPE, "");
|
||||
#endif
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
/* This needs to happen before the first use of malloc. */
|
||||
init_malloc ((PTR) NULL);
|
||||
init_malloc (NULL);
|
||||
|
||||
#ifdef HAVE_SBRK
|
||||
lim_at_start = (char *) sbrk (0);
|
||||
#endif
|
||||
|
||||
#if defined (ALIGN_STACK_ON_STARTUP)
|
||||
i = (int) &count & 0x3;
|
||||
|
|
@ -192,29 +195,73 @@ captured_main (void *data)
|
|||
gdb_stderr = stdio_fileopen (stderr);
|
||||
gdb_stdlog = gdb_stderr; /* for moment */
|
||||
gdb_stdtarg = gdb_stderr; /* for moment */
|
||||
gdb_stdin = stdio_fileopen (stdin);
|
||||
gdb_stdtargerr = gdb_stderr; /* for moment */
|
||||
gdb_stdtargin = gdb_stdin; /* for moment */
|
||||
|
||||
/* initialize error() */
|
||||
error_init ();
|
||||
|
||||
/* Set the sysroot path. */
|
||||
#ifdef TARGET_SYSTEM_ROOT_RELOCATABLE
|
||||
gdb_sysroot = make_relative_prefix (argv[0], BINDIR, TARGET_SYSTEM_ROOT);
|
||||
if (gdb_sysroot)
|
||||
{
|
||||
struct stat s;
|
||||
int res = 0;
|
||||
|
||||
if (stat (gdb_sysroot, &s) == 0)
|
||||
if (S_ISDIR (s.st_mode))
|
||||
res = 1;
|
||||
|
||||
if (res == 0)
|
||||
{
|
||||
xfree (gdb_sysroot);
|
||||
gdb_sysroot = TARGET_SYSTEM_ROOT;
|
||||
}
|
||||
}
|
||||
else
|
||||
gdb_sysroot = TARGET_SYSTEM_ROOT;
|
||||
#else
|
||||
#if defined (TARGET_SYSTEM_ROOT)
|
||||
gdb_sysroot = TARGET_SYSTEM_ROOT;
|
||||
#else
|
||||
gdb_sysroot = "";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* There will always be an interpreter. Either the one passed into
|
||||
this captured main, or one specified by the user at start up, or
|
||||
the console. Initialize the interpreter to the one requested by
|
||||
the application. */
|
||||
interpreter_p = xstrdup (context->interpreter_p);
|
||||
|
||||
/* Parse arguments and options. */
|
||||
{
|
||||
int c;
|
||||
/* When var field is 0, use flag field to record the equivalent
|
||||
short option (or arbitrary numbers starting at 10 for those
|
||||
with no equivalent). */
|
||||
enum {
|
||||
OPT_SE = 10,
|
||||
OPT_CD,
|
||||
OPT_ANNOTATE,
|
||||
OPT_STATISTICS,
|
||||
OPT_TUI,
|
||||
OPT_NOWINDOWS,
|
||||
OPT_WINDOWS
|
||||
};
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"async", no_argument, &event_loop_p, 1},
|
||||
{"noasync", no_argument, &event_loop_p, 0},
|
||||
#if defined(TUI)
|
||||
{"tui", no_argument, &tui_version, 1},
|
||||
{"tui", no_argument, 0, OPT_TUI},
|
||||
#endif
|
||||
{"xdb", no_argument, &xdb_commands, 1},
|
||||
{"dbx", no_argument, &dbx_commands, 1},
|
||||
{"readnow", no_argument, &readnow_symbol_files, 1},
|
||||
{"r", no_argument, &readnow_symbol_files, 1},
|
||||
{"mapped", no_argument, &mapped_symbol_files, 1},
|
||||
{"m", no_argument, &mapped_symbol_files, 1},
|
||||
{"quiet", no_argument, &quiet, 1},
|
||||
{"q", no_argument, &quiet, 1},
|
||||
{"silent", no_argument, &quiet, 1},
|
||||
|
|
@ -229,9 +276,9 @@ captured_main (void *data)
|
|||
{"fullname", no_argument, 0, 'f'},
|
||||
{"f", no_argument, 0, 'f'},
|
||||
|
||||
{"annotate", required_argument, 0, 12},
|
||||
{"annotate", required_argument, 0, OPT_ANNOTATE},
|
||||
{"help", no_argument, &print_help, 1},
|
||||
{"se", required_argument, 0, 10},
|
||||
{"se", required_argument, 0, OPT_SE},
|
||||
{"symbols", required_argument, 0, 's'},
|
||||
{"s", required_argument, 0, 's'},
|
||||
{"exec", required_argument, 0, 'e'},
|
||||
|
|
@ -253,21 +300,17 @@ captured_main (void *data)
|
|||
{"i", required_argument, 0, 'i'},
|
||||
{"directory", required_argument, 0, 'd'},
|
||||
{"d", required_argument, 0, 'd'},
|
||||
{"cd", required_argument, 0, 11},
|
||||
{"cd", required_argument, 0, OPT_CD},
|
||||
{"tty", required_argument, 0, 't'},
|
||||
{"baud", required_argument, 0, 'b'},
|
||||
{"b", required_argument, 0, 'b'},
|
||||
{"nw", no_argument, &use_windows, 0},
|
||||
{"nowindows", no_argument, &use_windows, 0},
|
||||
{"w", no_argument, &use_windows, 1},
|
||||
{"windows", no_argument, &use_windows, 1},
|
||||
{"statistics", no_argument, 0, 13},
|
||||
{"nw", no_argument, NULL, OPT_NOWINDOWS},
|
||||
{"nowindows", no_argument, NULL, OPT_NOWINDOWS},
|
||||
{"w", no_argument, NULL, OPT_WINDOWS},
|
||||
{"windows", no_argument, NULL, OPT_WINDOWS},
|
||||
{"statistics", no_argument, 0, OPT_STATISTICS},
|
||||
{"write", no_argument, &write_files, 1},
|
||||
{"args", no_argument, &set_args, 1},
|
||||
/* Allow machine descriptions to add more options... */
|
||||
#ifdef ADDITIONAL_OPTIONS
|
||||
ADDITIONAL_OPTIONS
|
||||
#endif
|
||||
{0, no_argument, 0, 0}
|
||||
};
|
||||
|
||||
|
|
@ -289,22 +332,38 @@ captured_main (void *data)
|
|||
case 0:
|
||||
/* Long option that just sets a flag. */
|
||||
break;
|
||||
case 10:
|
||||
case OPT_SE:
|
||||
symarg = optarg;
|
||||
execarg = optarg;
|
||||
break;
|
||||
case 11:
|
||||
case OPT_CD:
|
||||
cdarg = optarg;
|
||||
break;
|
||||
case 12:
|
||||
case OPT_ANNOTATE:
|
||||
/* FIXME: what if the syntax is wrong (e.g. not digits)? */
|
||||
annotation_level = atoi (optarg);
|
||||
break;
|
||||
case 13:
|
||||
case OPT_STATISTICS:
|
||||
/* Enable the display of both time and space usage. */
|
||||
display_time = 1;
|
||||
display_space = 1;
|
||||
break;
|
||||
case OPT_TUI:
|
||||
/* --tui is equivalent to -i=tui. */
|
||||
xfree (interpreter_p);
|
||||
interpreter_p = xstrdup ("tui");
|
||||
break;
|
||||
case OPT_WINDOWS:
|
||||
/* FIXME: cagney/2003-03-01: Not sure if this option is
|
||||
actually useful, and if it is, what it should do. */
|
||||
use_windows = 1;
|
||||
break;
|
||||
case OPT_NOWINDOWS:
|
||||
/* -nw is equivalent to -i=console. */
|
||||
xfree (interpreter_p);
|
||||
interpreter_p = xstrdup (INTERP_CONSOLE);
|
||||
use_windows = 0;
|
||||
break;
|
||||
case 'f':
|
||||
annotation_level = 1;
|
||||
/* We have probably been invoked from emacs. Disable window interface. */
|
||||
|
|
@ -338,7 +397,7 @@ captured_main (void *data)
|
|||
extern int gdbtk_test (char *);
|
||||
if (!gdbtk_test (optarg))
|
||||
{
|
||||
fprintf_unfiltered (gdb_stderr, "%s: unable to load tclcommand file \"%s\"",
|
||||
fprintf_unfiltered (gdb_stderr, _("%s: unable to load tclcommand file \"%s\""),
|
||||
argv[0], optarg);
|
||||
exit (1);
|
||||
}
|
||||
|
|
@ -354,7 +413,8 @@ extern int gdbtk_test (char *);
|
|||
}
|
||||
#endif /* GDBTK */
|
||||
case 'i':
|
||||
interpreter_p = optarg;
|
||||
xfree (interpreter_p);
|
||||
interpreter_p = xstrdup (optarg);
|
||||
break;
|
||||
case 'd':
|
||||
dirarg[ndir++] = optarg;
|
||||
|
|
@ -384,10 +444,11 @@ extern int gdbtk_test (char *);
|
|||
|
||||
fprintf_unfiltered
|
||||
(gdb_stderr,
|
||||
"warning: could not set baud rate to `%s'.\n", optarg);
|
||||
_("warning: could not set baud rate to `%s'.\n"), optarg);
|
||||
else
|
||||
baud_rate = i;
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
{
|
||||
int i;
|
||||
|
|
@ -401,18 +462,15 @@ extern int gdbtk_test (char *);
|
|||
|
||||
fprintf_unfiltered
|
||||
(gdb_stderr,
|
||||
"warning: could not set timeout limit to `%s'.\n", optarg);
|
||||
_("warning: could not set timeout limit to `%s'.\n"), optarg);
|
||||
else
|
||||
remote_timeout = i;
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef ADDITIONAL_OPTION_CASES
|
||||
ADDITIONAL_OPTION_CASES
|
||||
#endif
|
||||
case '?':
|
||||
fprintf_unfiltered (gdb_stderr,
|
||||
"Use `%s --help' for a complete list of options.\n",
|
||||
_("Use `%s --help' for a complete list of options.\n"),
|
||||
argv[0]);
|
||||
exit (1);
|
||||
}
|
||||
|
|
@ -422,19 +480,8 @@ extern int gdbtk_test (char *);
|
|||
if (print_help || print_version)
|
||||
{
|
||||
use_windows = 0;
|
||||
#ifdef TUI
|
||||
/* Disable the TUI as well. */
|
||||
tui_version = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef TUI
|
||||
/* An explicit --tui flag overrides the default UI, which is the
|
||||
window system. */
|
||||
if (tui_version)
|
||||
use_windows = 0;
|
||||
#endif
|
||||
|
||||
if (set_args)
|
||||
{
|
||||
/* The remaining options are the command-line options for the
|
||||
|
|
@ -443,7 +490,7 @@ extern int gdbtk_test (char *);
|
|||
if (optind >= argc)
|
||||
{
|
||||
fprintf_unfiltered (gdb_stderr,
|
||||
"%s: `--args' specified but no program specified\n",
|
||||
_("%s: `--args' specified but no program specified\n"),
|
||||
argv[0]);
|
||||
exit (1);
|
||||
}
|
||||
|
|
@ -470,7 +517,7 @@ extern int gdbtk_test (char *);
|
|||
break;
|
||||
case 3:
|
||||
fprintf_unfiltered (gdb_stderr,
|
||||
"Excess command line arguments ignored. (%s%s)\n",
|
||||
_("Excess command line arguments ignored. (%s%s)\n"),
|
||||
argv[optind], (optind == argc - 1) ? "" : " ...");
|
||||
break;
|
||||
}
|
||||
|
|
@ -484,7 +531,10 @@ extern int gdbtk_test (char *);
|
|||
gdb_init (argv[0]);
|
||||
|
||||
/* Do these (and anything which might call wrap_here or *_filtered)
|
||||
after initialize_all_files. */
|
||||
after initialize_all_files() but before the interpreter has been
|
||||
installed. Otherwize the help/version messages will be eaten by
|
||||
the interpreter's output handler. */
|
||||
|
||||
if (print_version)
|
||||
{
|
||||
print_gdb_version (gdb_stdout);
|
||||
|
|
@ -500,7 +550,45 @@ extern int gdbtk_test (char *);
|
|||
exit (0);
|
||||
}
|
||||
|
||||
if (!quiet)
|
||||
/* FIXME: cagney/2003-02-03: The big hack (part 1 of 2) that lets
|
||||
GDB retain the old MI1 interpreter startup behavior. Output the
|
||||
copyright message before the interpreter is installed. That way
|
||||
it isn't encapsulated in MI output. */
|
||||
if (!quiet && strcmp (interpreter_p, INTERP_MI1) == 0)
|
||||
{
|
||||
/* Print all the junk at the top, with trailing "..." if we are about
|
||||
to read a symbol file (possibly slowly). */
|
||||
print_gdb_version (gdb_stdout);
|
||||
if (symarg)
|
||||
printf_filtered ("..");
|
||||
wrap_here ("");
|
||||
gdb_flush (gdb_stdout); /* Force to screen during slow operations */
|
||||
}
|
||||
|
||||
|
||||
/* Install the default UI. All the interpreters should have had a
|
||||
look at things by now. Initialize the default interpreter. */
|
||||
|
||||
{
|
||||
/* Find it. */
|
||||
struct interp *interp = interp_lookup (interpreter_p);
|
||||
if (interp == NULL)
|
||||
error ("Interpreter `%s' unrecognized", interpreter_p);
|
||||
/* Install it. */
|
||||
if (!interp_set (interp))
|
||||
{
|
||||
fprintf_unfiltered (gdb_stderr,
|
||||
"Interpreter `%s' failed to initialize.\n",
|
||||
interpreter_p);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: cagney/2003-02-03: The big hack (part 2 of 2) that lets
|
||||
GDB retain the old MI1 interpreter startup behavior. Output the
|
||||
copyright message after the interpreter is installed when it is
|
||||
any sane interpreter. */
|
||||
if (!quiet && !current_interp_named_p (INTERP_MI1))
|
||||
{
|
||||
/* Print all the junk at the top, with trailing "..." if we are about
|
||||
to read a symbol file (possibly slowly). */
|
||||
|
|
@ -515,7 +603,7 @@ extern int gdbtk_test (char *);
|
|||
quit_pre_print = error_pre_print;
|
||||
|
||||
/* We may get more than one warning, don't double space all of them... */
|
||||
warning_pre_print = "\nwarning: ";
|
||||
warning_pre_print = _("\nwarning: ");
|
||||
|
||||
/* Read and execute $HOME/.gdbinit file, if it exists. This is done
|
||||
*before* all the command line arguments are processed; it sets
|
||||
|
|
@ -560,7 +648,7 @@ extern int gdbtk_test (char *);
|
|||
|
||||
if (execarg != NULL
|
||||
&& symarg != NULL
|
||||
&& STREQ (execarg, symarg))
|
||||
&& strcmp (execarg, symarg) == 0)
|
||||
{
|
||||
/* The exec file and the symbol-file are the same. If we can't
|
||||
open it, better only print one error message.
|
||||
|
|
@ -583,7 +671,7 @@ extern int gdbtk_test (char *);
|
|||
printf_filtered ("\n");
|
||||
error_pre_print = "\n";
|
||||
quit_pre_print = error_pre_print;
|
||||
warning_pre_print = "\nwarning: ";
|
||||
warning_pre_print = _("\nwarning: ");
|
||||
|
||||
if (corearg != NULL)
|
||||
{
|
||||
|
|
@ -606,14 +694,10 @@ extern int gdbtk_test (char *);
|
|||
if (ttyarg != NULL)
|
||||
catch_command_errors (tty_command, ttyarg, !batch, RETURN_MASK_ALL);
|
||||
|
||||
#ifdef ADDITIONAL_OPTION_HANDLER
|
||||
ADDITIONAL_OPTION_HANDLER;
|
||||
#endif
|
||||
|
||||
/* Error messages should no longer be distinguished with extra output. */
|
||||
error_pre_print = NULL;
|
||||
quit_pre_print = NULL;
|
||||
warning_pre_print = "warning: ";
|
||||
warning_pre_print = _("warning: ");
|
||||
|
||||
/* Read the .gdbinit file in the current directory, *if* it isn't
|
||||
the same as the $HOME/.gdbinit file (it should exist, also). */
|
||||
|
|
@ -664,15 +748,13 @@ extern int gdbtk_test (char *);
|
|||
BEFORE_MAIN_LOOP_HOOK;
|
||||
#endif
|
||||
|
||||
END_PROGRESS (argv[0]);
|
||||
|
||||
/* Show time and/or space usage. */
|
||||
|
||||
if (display_time)
|
||||
{
|
||||
long init_time = get_run_time () - time_at_startup;
|
||||
|
||||
printf_unfiltered ("Startup time: %ld.%06ld\n",
|
||||
printf_unfiltered (_("Startup time: %ld.%06ld\n"),
|
||||
init_time / 1000000, init_time % 1000000);
|
||||
}
|
||||
|
||||
|
|
@ -682,7 +764,7 @@ extern int gdbtk_test (char *);
|
|||
extern char **environ;
|
||||
char *lim = (char *) sbrk (0);
|
||||
|
||||
printf_unfiltered ("Startup size: data size %ld\n",
|
||||
printf_unfiltered (_("Startup size: data size %ld\n"),
|
||||
(long) (lim - (char *) &environ));
|
||||
#endif
|
||||
}
|
||||
|
|
@ -726,13 +808,13 @@ extern int gdbtk_test (char *);
|
|||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
gdb_main (struct captured_main_args *args)
|
||||
{
|
||||
struct captured_main_args args;
|
||||
args.argc = argc;
|
||||
args.argv = argv;
|
||||
catch_errors (captured_main, &args, "", RETURN_MASK_ALL);
|
||||
return 0;
|
||||
use_windows = args->use_windows;
|
||||
catch_errors (captured_main, args, "", RETURN_MASK_ALL);
|
||||
/* The only way to end up here is by an error (normal exit is
|
||||
handled by quit_force()), hence always return an error status. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -743,69 +825,66 @@ main (int argc, char **argv)
|
|||
static void
|
||||
print_gdb_help (struct ui_file *stream)
|
||||
{
|
||||
fputs_unfiltered ("\
|
||||
fputs_unfiltered (_("\
|
||||
This is the GNU debugger. Usage:\n\n\
|
||||
gdb [options] [executable-file [core-file or process-id]]\n\
|
||||
gdb [options] --args executable-file [inferior-arguments ...]\n\n\
|
||||
Options:\n\n\
|
||||
", stream);
|
||||
fputs_unfiltered ("\
|
||||
"), stream);
|
||||
fputs_unfiltered (_("\
|
||||
--args Arguments after executable-file are passed to inferior\n\
|
||||
", stream);
|
||||
fputs_unfiltered ("\
|
||||
"), stream);
|
||||
fputs_unfiltered (_("\
|
||||
--[no]async Enable (disable) asynchronous version of CLI\n\
|
||||
", stream);
|
||||
fputs_unfiltered ("\
|
||||
"), stream);
|
||||
fputs_unfiltered (_("\
|
||||
-b BAUDRATE Set serial port baud rate used for remote debugging.\n\
|
||||
--batch Exit after processing options.\n\
|
||||
--cd=DIR Change current directory to DIR.\n\
|
||||
--command=FILE Execute GDB commands from FILE.\n\
|
||||
--core=COREFILE Analyze the core dump COREFILE.\n\
|
||||
--pid=PID Attach to running process PID.\n\
|
||||
", stream);
|
||||
fputs_unfiltered ("\
|
||||
"), stream);
|
||||
fputs_unfiltered (_("\
|
||||
--dbx DBX compatibility mode.\n\
|
||||
--directory=DIR Search for source files in DIR.\n\
|
||||
--epoch Output information used by epoch emacs-GDB interface.\n\
|
||||
--exec=EXECFILE Use EXECFILE as the executable.\n\
|
||||
--fullname Output information used by emacs-GDB interface.\n\
|
||||
--help Print this message.\n\
|
||||
", stream);
|
||||
fputs_unfiltered ("\
|
||||
"), stream);
|
||||
fputs_unfiltered (_("\
|
||||
--interpreter=INTERP\n\
|
||||
Select a specific interpreter / user interface\n\
|
||||
", stream);
|
||||
fputs_unfiltered ("\
|
||||
"), stream);
|
||||
fputs_unfiltered (_("\
|
||||
--mapped Use mapped symbol files if supported on this system.\n\
|
||||
--nw Do not use a window interface.\n\
|
||||
--nx Do not read ", stream);
|
||||
--nx Do not read "), stream);
|
||||
fputs_unfiltered (gdbinit, stream);
|
||||
fputs_unfiltered (" file.\n\
|
||||
fputs_unfiltered (_(" file.\n\
|
||||
--quiet Do not print version number on startup.\n\
|
||||
--readnow Fully read symbol files on first access.\n\
|
||||
", stream);
|
||||
fputs_unfiltered ("\
|
||||
"), stream);
|
||||
fputs_unfiltered (_("\
|
||||
--se=FILE Use FILE as symbol file and executable file.\n\
|
||||
--symbols=SYMFILE Read symbols from SYMFILE.\n\
|
||||
--tty=TTY Use TTY for input/output by the program being debugged.\n\
|
||||
", stream);
|
||||
"), stream);
|
||||
#if defined(TUI)
|
||||
fputs_unfiltered ("\
|
||||
fputs_unfiltered (_("\
|
||||
--tui Use a terminal user interface.\n\
|
||||
", stream);
|
||||
"), stream);
|
||||
#endif
|
||||
fputs_unfiltered ("\
|
||||
fputs_unfiltered (_("\
|
||||
--version Print version information and then exit.\n\
|
||||
-w Use a window interface.\n\
|
||||
--write Set writing into executable and core files.\n\
|
||||
--xdb XDB compatibility mode.\n\
|
||||
", stream);
|
||||
#ifdef ADDITIONAL_OPTION_HELP
|
||||
fputs_unfiltered (ADDITIONAL_OPTION_HELP, stream);
|
||||
#endif
|
||||
fputs_unfiltered ("\n\
|
||||
"), stream);
|
||||
fputs_unfiltered (_("\n\
|
||||
For more information, type \"help\" from within GDB, or consult the\n\
|
||||
GDB manual (available as on-line info or a printed manual).\n\
|
||||
Report bugs to \"bug-gdb@gnu.org\".\
|
||||
", stream);
|
||||
"), stream);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
/* GDB routines for manipulating objfiles.
|
||||
Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
||||
2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Cygnus Support, using pieces from other GDB modules.
|
||||
|
||||
This file is part of GDB.
|
||||
|
|
@ -30,30 +32,24 @@
|
|||
#include "objfiles.h"
|
||||
#include "gdb-stabs.h"
|
||||
#include "target.h"
|
||||
#include "bcache.h"
|
||||
|
||||
#include "gdb_assert.h"
|
||||
#include <sys/types.h>
|
||||
#include "gdb_stat.h"
|
||||
#include <fcntl.h>
|
||||
#include "obstack.h"
|
||||
#include "gdb_obstack.h"
|
||||
#include "gdb_string.h"
|
||||
#include "hashtab.h"
|
||||
|
||||
#include "breakpoint.h"
|
||||
#include "block.h"
|
||||
#include "dictionary.h"
|
||||
|
||||
/* Prototypes for local functions */
|
||||
|
||||
#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
|
||||
|
||||
#include "mmalloc.h"
|
||||
|
||||
static int open_existing_mapped_file (char *, long, int);
|
||||
|
||||
static int open_mapped_file (char *filename, long mtime, int flags);
|
||||
|
||||
static PTR map_to_file (int);
|
||||
|
||||
#endif /* defined(USE_MMALLOC) && defined(HAVE_MMAP) */
|
||||
|
||||
static void add_to_objfile_sections (bfd *, sec_ptr, PTR);
|
||||
static void objfile_alloc_data (struct objfile *objfile);
|
||||
static void objfile_free_data (struct objfile *objfile);
|
||||
|
||||
/* Externally visible variables that are owned by this module.
|
||||
See declarations in objfile.h for more info. */
|
||||
|
|
@ -63,8 +59,6 @@ struct objfile *current_objfile; /* For symbol file being read in */
|
|||
struct objfile *symfile_objfile; /* Main symbol table loaded from */
|
||||
struct objfile *rt_common_objfile; /* For runtime common symbols */
|
||||
|
||||
int mapped_symbol_files; /* Try to use mapped symbol files */
|
||||
|
||||
/* Locate all mappable sections of a BFD file.
|
||||
objfile_p_char is a char * to get it through
|
||||
bfd_map_over_sections; we cast it back to its proper type. */
|
||||
|
|
@ -79,7 +73,8 @@ int mapped_symbol_files; /* Try to use mapped symbol files */
|
|||
the end of the table (objfile->sections_end). */
|
||||
|
||||
static void
|
||||
add_to_objfile_sections (bfd *abfd, sec_ptr asect, PTR objfile_p_char)
|
||||
add_to_objfile_sections (struct bfd *abfd, struct bfd_section *asect,
|
||||
void *objfile_p_char)
|
||||
{
|
||||
struct objfile *objfile = (struct objfile *) objfile_p_char;
|
||||
struct obj_section section;
|
||||
|
|
@ -98,7 +93,7 @@ add_to_objfile_sections (bfd *abfd, sec_ptr asect, PTR objfile_p_char)
|
|||
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));
|
||||
obstack_grow (&objfile->objfile_obstack, (char *) §ion, sizeof (section));
|
||||
objfile->sections_end = (struct obj_section *) (((unsigned long) objfile->sections_end) + 1);
|
||||
}
|
||||
|
||||
|
|
@ -124,13 +119,13 @@ build_objfile_section_table (struct objfile *objfile)
|
|||
/* objfile->sections can be already set when reading a mapped symbol
|
||||
file. I believe that we do need to rebuild the section table in
|
||||
this case (we rebuild other things derived from the bfd), but we
|
||||
can't free the old one (it's in the psymbol_obstack). So we just
|
||||
can't free the old one (it's in the objfile_obstack). So we just
|
||||
waste some memory. */
|
||||
|
||||
objfile->sections_end = 0;
|
||||
bfd_map_over_sections (objfile->obfd, add_to_objfile_sections, (char *) objfile);
|
||||
objfile->sections = (struct obj_section *)
|
||||
obstack_finish (&objfile->psymbol_obstack);
|
||||
obstack_finish (&objfile->objfile_obstack);
|
||||
objfile->sections_end = objfile->sections + (unsigned long) objfile->sections_end;
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -141,10 +136,17 @@ build_objfile_section_table (struct objfile *objfile)
|
|||
new objfile struct.
|
||||
|
||||
The FLAGS word contains various bits (OBJF_*) that can be taken as
|
||||
requests for specific operations, like trying to open a mapped
|
||||
version of the objfile (OBJF_MAPPED). Other bits like
|
||||
OBJF_SHARED are simply copied through to the new objfile flags
|
||||
member. */
|
||||
requests for specific operations. Other bits like OBJF_SHARED are
|
||||
simply copied through to the new objfile flags member. */
|
||||
|
||||
/* NOTE: carlton/2003-02-04: This function is called with args NULL, 0
|
||||
by jv-lang.c, to create an artificial objfile used to hold
|
||||
information about dynamically-loaded Java classes. Unfortunately,
|
||||
that branch of this function doesn't get tested very frequently, so
|
||||
it's prone to breakage. (E.g. at one time the name was set to NULL
|
||||
in that situation, which broke a loop over all names in the dynamic
|
||||
library loader.) If you change this function, please try to leave
|
||||
things in a consistent state even if abfd is NULL. */
|
||||
|
||||
struct objfile *
|
||||
allocate_objfile (bfd *abfd, int flags)
|
||||
|
|
@ -152,109 +154,6 @@ allocate_objfile (bfd *abfd, int flags)
|
|||
struct objfile *objfile = NULL;
|
||||
struct objfile *last_one = NULL;
|
||||
|
||||
if (mapped_symbol_files)
|
||||
flags |= OBJF_MAPPED;
|
||||
|
||||
#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
|
||||
if (abfd != NULL)
|
||||
{
|
||||
|
||||
/* If we can support mapped symbol files, try to open/reopen the
|
||||
mapped file that corresponds to the file from which we wish to
|
||||
read symbols. If the objfile is to be mapped, we must malloc
|
||||
the structure itself using the mmap version, and arrange that
|
||||
all memory allocation for the objfile uses the mmap routines.
|
||||
If we are reusing an existing mapped file, from which we get
|
||||
our objfile pointer, we have to make sure that we update the
|
||||
pointers to the alloc/free functions in the obstack, in case
|
||||
these functions have moved within the current gdb. */
|
||||
|
||||
int fd;
|
||||
|
||||
fd = open_mapped_file (bfd_get_filename (abfd), bfd_get_mtime (abfd),
|
||||
flags);
|
||||
if (fd >= 0)
|
||||
{
|
||||
PTR md;
|
||||
|
||||
if ((md = map_to_file (fd)) == NULL)
|
||||
{
|
||||
close (fd);
|
||||
}
|
||||
else if ((objfile = (struct objfile *) mmalloc_getkey (md, 0)) != NULL)
|
||||
{
|
||||
/* Update memory corruption handler function addresses. */
|
||||
init_malloc (md);
|
||||
objfile->md = md;
|
||||
objfile->mmfd = fd;
|
||||
/* Update pointers to functions to *our* copies */
|
||||
obstack_chunkfun (&objfile->psymbol_cache.cache, xmmalloc);
|
||||
obstack_freefun (&objfile->psymbol_cache.cache, xmfree);
|
||||
obstack_chunkfun (&objfile->psymbol_obstack, xmmalloc);
|
||||
obstack_freefun (&objfile->psymbol_obstack, xmfree);
|
||||
obstack_chunkfun (&objfile->symbol_obstack, xmmalloc);
|
||||
obstack_freefun (&objfile->symbol_obstack, xmfree);
|
||||
obstack_chunkfun (&objfile->type_obstack, xmmalloc);
|
||||
obstack_freefun (&objfile->type_obstack, xmfree);
|
||||
/* If already in objfile list, unlink it. */
|
||||
unlink_objfile (objfile);
|
||||
/* Forget things specific to a particular gdb, may have changed. */
|
||||
objfile->sf = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Set up to detect internal memory corruption. MUST be
|
||||
done before the first malloc. See comments in
|
||||
init_malloc() and mmcheck(). */
|
||||
|
||||
init_malloc (md);
|
||||
|
||||
objfile = (struct objfile *)
|
||||
xmmalloc (md, sizeof (struct objfile));
|
||||
memset (objfile, 0, sizeof (struct objfile));
|
||||
objfile->md = md;
|
||||
objfile->mmfd = fd;
|
||||
objfile->flags |= OBJF_MAPPED;
|
||||
mmalloc_setkey (objfile->md, 0, objfile);
|
||||
obstack_specify_allocation_with_arg (&objfile->psymbol_cache.cache,
|
||||
0, 0, xmmalloc, xmfree,
|
||||
objfile->md);
|
||||
obstack_specify_allocation_with_arg (&objfile->psymbol_obstack,
|
||||
0, 0, xmmalloc, xmfree,
|
||||
objfile->md);
|
||||
obstack_specify_allocation_with_arg (&objfile->symbol_obstack,
|
||||
0, 0, xmmalloc, xmfree,
|
||||
objfile->md);
|
||||
obstack_specify_allocation_with_arg (&objfile->type_obstack,
|
||||
0, 0, xmmalloc, xmfree,
|
||||
objfile->md);
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & OBJF_MAPPED) && (objfile == NULL))
|
||||
{
|
||||
warning ("symbol table for '%s' will not be mapped",
|
||||
bfd_get_filename (abfd));
|
||||
flags &= ~OBJF_MAPPED;
|
||||
}
|
||||
}
|
||||
#else /* !defined(USE_MMALLOC) || !defined(HAVE_MMAP) */
|
||||
|
||||
if (flags & OBJF_MAPPED)
|
||||
{
|
||||
warning ("mapped symbol tables are not supported on this machine; missing or broken mmap().");
|
||||
|
||||
/* Turn off the global flag so we don't try to do mapped symbol tables
|
||||
any more, which shuts up gdb unless the user specifically gives the
|
||||
"mapped" keyword again. */
|
||||
|
||||
mapped_symbol_files = 0;
|
||||
flags &= ~OBJF_MAPPED;
|
||||
}
|
||||
|
||||
#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
|
||||
back to an unmapped objfile. */
|
||||
|
|
@ -264,17 +163,16 @@ allocate_objfile (bfd *abfd, int flags)
|
|||
objfile = (struct objfile *) xmalloc (sizeof (struct objfile));
|
||||
memset (objfile, 0, sizeof (struct objfile));
|
||||
objfile->md = NULL;
|
||||
obstack_specify_allocation (&objfile->psymbol_cache.cache, 0, 0,
|
||||
xmalloc, xfree);
|
||||
obstack_specify_allocation (&objfile->psymbol_obstack, 0, 0, xmalloc,
|
||||
xfree);
|
||||
obstack_specify_allocation (&objfile->symbol_obstack, 0, 0, xmalloc,
|
||||
xfree);
|
||||
obstack_specify_allocation (&objfile->type_obstack, 0, 0, xmalloc,
|
||||
xfree);
|
||||
flags &= ~OBJF_MAPPED;
|
||||
objfile->psymbol_cache = bcache_xmalloc ();
|
||||
objfile->macro_cache = bcache_xmalloc ();
|
||||
/* We could use obstack_specify_allocation here instead, but
|
||||
gdb_obstack.h specifies the alloc/dealloc functions. */
|
||||
obstack_init (&objfile->objfile_obstack);
|
||||
terminate_minimal_symbol_table (objfile);
|
||||
}
|
||||
|
||||
objfile_alloc_data (objfile);
|
||||
|
||||
/* Update the per-objfile information that comes from the bfd, ensuring
|
||||
that any data that is reference is saved in the per-objfile data
|
||||
region. */
|
||||
|
|
@ -297,14 +195,22 @@ allocate_objfile (bfd *abfd, int flags)
|
|||
objfile->name, bfd_errmsg (bfd_get_error ()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
objfile->name = mstrsave (objfile->md, "<<anonymous objfile>>");
|
||||
}
|
||||
|
||||
/* Initialize the section indexes for this objfile, so that we can
|
||||
later detect if they are used w/o being properly assigned to. */
|
||||
|
||||
objfile->sect_index_text = -1;
|
||||
objfile->sect_index_data = -1;
|
||||
objfile->sect_index_bss = -1;
|
||||
objfile->sect_index_rodata = -1;
|
||||
objfile->sect_index_text = -1;
|
||||
objfile->sect_index_data = -1;
|
||||
objfile->sect_index_bss = -1;
|
||||
objfile->sect_index_rodata = -1;
|
||||
|
||||
/* We don't yet have a C++-specific namespace symtab. */
|
||||
|
||||
objfile->cp_namespace_symtab = NULL;
|
||||
|
||||
/* Add this file onto the tail of the linked list of other such files. */
|
||||
|
||||
|
|
@ -325,6 +231,89 @@ allocate_objfile (bfd *abfd, int flags)
|
|||
return (objfile);
|
||||
}
|
||||
|
||||
/* Initialize entry point information for this objfile. */
|
||||
|
||||
void
|
||||
init_entry_point_info (struct objfile *objfile)
|
||||
{
|
||||
/* Save startup file's range of PC addresses to help blockframe.c
|
||||
decide where the bottom of the stack is. */
|
||||
|
||||
if (bfd_get_file_flags (objfile->obfd) & EXEC_P)
|
||||
{
|
||||
/* Executable file -- record its entry point so we'll recognize
|
||||
the startup file because it contains the entry point. */
|
||||
objfile->ei.entry_point = bfd_get_start_address (objfile->obfd);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Examination of non-executable.o files. Short-circuit this stuff. */
|
||||
objfile->ei.entry_point = INVALID_ENTRY_POINT;
|
||||
}
|
||||
objfile->ei.deprecated_entry_file_lowpc = INVALID_ENTRY_LOWPC;
|
||||
objfile->ei.deprecated_entry_file_highpc = INVALID_ENTRY_HIGHPC;
|
||||
objfile->ei.entry_func_lowpc = INVALID_ENTRY_LOWPC;
|
||||
objfile->ei.entry_func_highpc = INVALID_ENTRY_HIGHPC;
|
||||
objfile->ei.main_func_lowpc = INVALID_ENTRY_LOWPC;
|
||||
objfile->ei.main_func_highpc = INVALID_ENTRY_HIGHPC;
|
||||
}
|
||||
|
||||
/* Get current entry point address. */
|
||||
|
||||
CORE_ADDR
|
||||
entry_point_address (void)
|
||||
{
|
||||
return symfile_objfile ? symfile_objfile->ei.entry_point : 0;
|
||||
}
|
||||
|
||||
/* Create the terminating entry of OBJFILE's minimal symbol table.
|
||||
If OBJFILE->msymbols is zero, allocate a single entry from
|
||||
OBJFILE->objfile_obstack; otherwise, just initialize
|
||||
OBJFILE->msymbols[OBJFILE->minimal_symbol_count]. */
|
||||
void
|
||||
terminate_minimal_symbol_table (struct objfile *objfile)
|
||||
{
|
||||
if (! objfile->msymbols)
|
||||
objfile->msymbols = ((struct minimal_symbol *)
|
||||
obstack_alloc (&objfile->objfile_obstack,
|
||||
sizeof (objfile->msymbols[0])));
|
||||
|
||||
{
|
||||
struct minimal_symbol *m
|
||||
= &objfile->msymbols[objfile->minimal_symbol_count];
|
||||
|
||||
memset (m, 0, sizeof (*m));
|
||||
/* Don't rely on these enumeration values being 0's. */
|
||||
MSYMBOL_TYPE (m) = mst_unknown;
|
||||
SYMBOL_INIT_LANGUAGE_SPECIFIC (m, language_unknown);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Put one object file before a specified on in the global list.
|
||||
This can be used to make sure an object file is destroyed before
|
||||
another when using ALL_OBJFILES_SAFE to free all objfiles. */
|
||||
void
|
||||
put_objfile_before (struct objfile *objfile, struct objfile *before_this)
|
||||
{
|
||||
struct objfile **objp;
|
||||
|
||||
unlink_objfile (objfile);
|
||||
|
||||
for (objp = &object_files; *objp != NULL; objp = &((*objp)->next))
|
||||
{
|
||||
if (*objp == before_this)
|
||||
{
|
||||
objfile->next = *objp;
|
||||
*objp = objfile;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"put_objfile_before: before objfile not in list");
|
||||
}
|
||||
|
||||
/* Put OBJFILE at the front of the list. */
|
||||
|
||||
void
|
||||
|
|
@ -379,8 +368,8 @@ unlink_objfile (struct objfile *objfile)
|
|||
|
||||
|
||||
/* Destroy an objfile and all the symtabs and psymtabs under it. Note
|
||||
that as much as possible is allocated on the symbol_obstack and
|
||||
psymbol_obstack, so that the memory can be efficiently freed.
|
||||
that as much as possible is allocated on the objfile_obstack
|
||||
so that the memory can be efficiently freed.
|
||||
|
||||
Things which we do NOT free because they are not in malloc'd memory
|
||||
or not in memory specific to the objfile include:
|
||||
|
|
@ -397,6 +386,18 @@ unlink_objfile (struct objfile *objfile)
|
|||
void
|
||||
free_objfile (struct objfile *objfile)
|
||||
{
|
||||
if (objfile->separate_debug_objfile)
|
||||
{
|
||||
free_objfile (objfile->separate_debug_objfile);
|
||||
}
|
||||
|
||||
if (objfile->separate_debug_objfile_backlink)
|
||||
{
|
||||
/* We freed the separate debug file, make sure the base objfile
|
||||
doesn't reference it. */
|
||||
objfile->separate_debug_objfile_backlink->separate_debug_objfile = NULL;
|
||||
}
|
||||
|
||||
/* First do any symbol file specific actions required when we are
|
||||
finished with a particular symbol file. Note that if the objfile
|
||||
is using reusable symbol information (via mmalloc) then each of
|
||||
|
|
@ -441,48 +442,25 @@ free_objfile (struct objfile *objfile)
|
|||
to call this here. */
|
||||
clear_pc_function_cache ();
|
||||
|
||||
/* The last thing we do is free the objfile struct itself for the
|
||||
non-reusable case, or detach from the mapped file for the
|
||||
reusable case. Note that the mmalloc_detach or the xmfree() is
|
||||
the last thing we can do with this objfile. */
|
||||
/* The last thing we do is free the objfile struct itself. */
|
||||
|
||||
#if defined(USE_MMALLOC) && defined(HAVE_MMAP)
|
||||
|
||||
if (objfile->flags & OBJF_MAPPED)
|
||||
objfile_free_data (objfile);
|
||||
if (objfile->name != NULL)
|
||||
{
|
||||
/* Remember the fd so we can close it. We can't close it before
|
||||
doing the detach, and after the detach the objfile is gone. */
|
||||
int mmfd;
|
||||
|
||||
mmfd = objfile->mmfd;
|
||||
mmalloc_detach (objfile->md);
|
||||
objfile = NULL;
|
||||
close (mmfd);
|
||||
}
|
||||
|
||||
#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. */
|
||||
|
||||
if (objfile != NULL)
|
||||
{
|
||||
if (objfile->name != NULL)
|
||||
{
|
||||
xmfree (objfile->md, objfile->name);
|
||||
}
|
||||
if (objfile->global_psymbols.list)
|
||||
xmfree (objfile->md, objfile->global_psymbols.list);
|
||||
if (objfile->static_psymbols.list)
|
||||
xmfree (objfile->md, objfile->static_psymbols.list);
|
||||
/* Free the obstacks for non-reusable objfiles */
|
||||
free_bcache (&objfile->psymbol_cache);
|
||||
obstack_free (&objfile->psymbol_obstack, 0);
|
||||
obstack_free (&objfile->symbol_obstack, 0);
|
||||
obstack_free (&objfile->type_obstack, 0);
|
||||
xmfree (objfile->md, objfile);
|
||||
objfile = NULL;
|
||||
xmfree (objfile->md, objfile->name);
|
||||
}
|
||||
if (objfile->global_psymbols.list)
|
||||
xmfree (objfile->md, objfile->global_psymbols.list);
|
||||
if (objfile->static_psymbols.list)
|
||||
xmfree (objfile->md, objfile->static_psymbols.list);
|
||||
/* Free the obstacks for non-reusable objfiles */
|
||||
bcache_xfree (objfile->psymbol_cache);
|
||||
bcache_xfree (objfile->macro_cache);
|
||||
if (objfile->demangled_names_hash)
|
||||
htab_delete (objfile->demangled_names_hash);
|
||||
obstack_free (&objfile->objfile_obstack, 0);
|
||||
xmfree (objfile->md, objfile);
|
||||
objfile = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -517,7 +495,8 @@ void
|
|||
objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
|
||||
{
|
||||
struct section_offsets *delta =
|
||||
(struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
|
||||
((struct section_offsets *)
|
||||
alloca (SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)));
|
||||
|
||||
{
|
||||
int i;
|
||||
|
|
@ -560,18 +539,18 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
|
|||
{
|
||||
struct block *b;
|
||||
struct symbol *sym;
|
||||
int j;
|
||||
struct dict_iterator iter;
|
||||
|
||||
b = BLOCKVECTOR_BLOCK (bv, i);
|
||||
BLOCK_START (b) += ANOFFSET (delta, s->block_line_section);
|
||||
BLOCK_END (b) += ANOFFSET (delta, s->block_line_section);
|
||||
|
||||
ALL_BLOCK_SYMBOLS (b, j, sym)
|
||||
ALL_BLOCK_SYMBOLS (b, iter, sym)
|
||||
{
|
||||
fixup_symbol_section (sym, objfile);
|
||||
|
||||
/* The RS6000 code from which this was taken skipped
|
||||
any symbols in STRUCT_NAMESPACE or UNDEF_NAMESPACE.
|
||||
any symbols in STRUCT_DOMAIN or UNDEF_DOMAIN.
|
||||
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
|
||||
|
|
@ -586,8 +565,8 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
|
|||
/* Relocate Extra Function Info for ecoff. */
|
||||
|
||||
else if (SYMBOL_CLASS (sym) == LOC_CONST
|
||||
&& SYMBOL_NAMESPACE (sym) == LABEL_NAMESPACE
|
||||
&& strcmp (SYMBOL_NAME (sym), MIPS_EFI_SYMBOL_NAME) == 0)
|
||||
&& SYMBOL_DOMAIN (sym) == LABEL_DOMAIN
|
||||
&& strcmp (DEPRECATED_SYMBOL_NAME (sym), MIPS_EFI_SYMBOL_NAME) == 0)
|
||||
ecoff_relocate_efi (sym, ANOFFSET (delta,
|
||||
s->block_line_section));
|
||||
#endif
|
||||
|
|
@ -678,10 +657,10 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
|
|||
objfile->ei.entry_func_highpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
|
||||
}
|
||||
|
||||
if (objfile->ei.entry_file_lowpc != INVALID_ENTRY_LOWPC)
|
||||
if (objfile->ei.deprecated_entry_file_lowpc != INVALID_ENTRY_LOWPC)
|
||||
{
|
||||
objfile->ei.entry_file_lowpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
|
||||
objfile->ei.entry_file_highpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
|
||||
objfile->ei.deprecated_entry_file_lowpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
|
||||
objfile->ei.deprecated_entry_file_highpc += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
|
||||
}
|
||||
|
||||
if (objfile->ei.main_func_lowpc != INVALID_ENTRY_LOWPC)
|
||||
|
|
@ -765,7 +744,7 @@ have_minimal_symbols (void)
|
|||
|
||||
ALL_OBJFILES (ofp)
|
||||
{
|
||||
if (ofp->msymbols != NULL)
|
||||
if (ofp->minimal_symbol_count > 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -773,176 +752,14 @@ have_minimal_symbols (void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#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
|
||||
with the name SYMSFILENAME and verify it is more recent than the base
|
||||
file by checking it's timestamp against MTIME.
|
||||
|
||||
If SYMSFILENAME does not exist (or can't be stat'd), simply returns -1.
|
||||
|
||||
If SYMSFILENAME does exist, but is out of date, we check to see if the
|
||||
user has specified creation of a mapped file. If so, we don't issue
|
||||
any warning message because we will be creating a new mapped file anyway,
|
||||
overwriting the old one. If not, then we issue a warning message so that
|
||||
the user will know why we aren't using this existing mapped symbol file.
|
||||
In either case, we return -1.
|
||||
|
||||
If SYMSFILENAME does exist and is not out of date, but can't be opened for
|
||||
some reason, then prints an appropriate system error message and returns -1.
|
||||
|
||||
Otherwise, returns the open file descriptor. */
|
||||
|
||||
static int
|
||||
open_existing_mapped_file (char *symsfilename, long mtime, int flags)
|
||||
{
|
||||
int fd = -1;
|
||||
struct stat sbuf;
|
||||
|
||||
if (stat (symsfilename, &sbuf) == 0)
|
||||
{
|
||||
if (sbuf.st_mtime < mtime)
|
||||
{
|
||||
if (!(flags & OBJF_MAPPED))
|
||||
{
|
||||
warning ("mapped symbol file `%s' is out of date, ignored it",
|
||||
symsfilename);
|
||||
}
|
||||
}
|
||||
else if ((fd = open (symsfilename, O_RDWR)) < 0)
|
||||
{
|
||||
if (error_pre_print)
|
||||
{
|
||||
printf_unfiltered (error_pre_print);
|
||||
}
|
||||
print_sys_errmsg (symsfilename, errno);
|
||||
}
|
||||
}
|
||||
return (fd);
|
||||
}
|
||||
|
||||
/* Look for a mapped symbol file that corresponds to FILENAME and is more
|
||||
recent than MTIME. If MAPPED is nonzero, the user has asked that gdb
|
||||
use a mapped symbol file for this file, so create a new one if one does
|
||||
not currently exist.
|
||||
|
||||
If found, then return an open file descriptor for the file, otherwise
|
||||
return -1.
|
||||
|
||||
This routine is responsible for implementing the policy that generates
|
||||
the name of the mapped symbol file from the name of a file containing
|
||||
symbols that gdb would like to read. Currently this policy is to append
|
||||
".syms" to the name of the file.
|
||||
|
||||
This routine is also responsible for implementing the policy that
|
||||
determines where the mapped symbol file is found (the search path).
|
||||
This policy is that when reading an existing mapped file, a file of
|
||||
the correct name in the current directory takes precedence over a
|
||||
file of the correct name in the same directory as the symbol file.
|
||||
When creating a new mapped file, it is always created in the current
|
||||
directory. This helps to minimize the chances of a user unknowingly
|
||||
creating big mapped files in places like /bin and /usr/local/bin, and
|
||||
allows a local copy to override a manually installed global copy (in
|
||||
/bin for example). */
|
||||
|
||||
static int
|
||||
open_mapped_file (char *filename, long mtime, int flags)
|
||||
{
|
||||
int fd;
|
||||
char *symsfilename;
|
||||
|
||||
/* First try to open an existing file in the current directory, and
|
||||
then try the directory where the symbol file is located. */
|
||||
|
||||
symsfilename = concat ("./", lbasename (filename), ".syms", (char *) NULL);
|
||||
if ((fd = open_existing_mapped_file (symsfilename, mtime, flags)) < 0)
|
||||
{
|
||||
xfree (symsfilename);
|
||||
symsfilename = concat (filename, ".syms", (char *) NULL);
|
||||
fd = open_existing_mapped_file (symsfilename, mtime, flags);
|
||||
}
|
||||
|
||||
/* If we don't have an open file by now, then either the file does not
|
||||
already exist, or the base file has changed since it was created. In
|
||||
either case, if the user has specified use of a mapped file, then
|
||||
create a new mapped file, truncating any existing one. If we can't
|
||||
create one, print a system error message saying why we can't.
|
||||
|
||||
By default the file is rw for everyone, with the user's umask taking
|
||||
care of turning off the permissions the user wants off. */
|
||||
|
||||
if ((fd < 0) && (flags & OBJF_MAPPED))
|
||||
{
|
||||
xfree (symsfilename);
|
||||
symsfilename = concat ("./", lbasename (filename), ".syms",
|
||||
(char *) NULL);
|
||||
if ((fd = open (symsfilename, O_RDWR | O_CREAT | O_TRUNC, 0666)) < 0)
|
||||
{
|
||||
if (error_pre_print)
|
||||
{
|
||||
printf_unfiltered (error_pre_print);
|
||||
}
|
||||
print_sys_errmsg (symsfilename, errno);
|
||||
}
|
||||
}
|
||||
|
||||
xfree (symsfilename);
|
||||
return (fd);
|
||||
}
|
||||
|
||||
static PTR
|
||||
map_to_file (int fd)
|
||||
{
|
||||
PTR md;
|
||||
CORE_ADDR mapto;
|
||||
|
||||
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(USE_MMALLOC) && defined(HAVE_MMAP) */
|
||||
|
||||
/* 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. */
|
||||
/* 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
|
||||
bfd_section" (which is a bfd-defined data type). The obj_section
|
||||
contains a pointer to the "struct bfd_section". */
|
||||
|
||||
struct obj_section *
|
||||
find_pc_sect_section (CORE_ADDR pc, struct sec *section)
|
||||
find_pc_sect_section (CORE_ADDR pc, struct bfd_section *section)
|
||||
{
|
||||
struct obj_section *s;
|
||||
struct objfile *objfile;
|
||||
|
|
@ -979,7 +796,7 @@ in_plt_section (CORE_ADDR pc, char *name)
|
|||
|
||||
retval = (s != NULL
|
||||
&& s->the_bfd_section->name != NULL
|
||||
&& STREQ (s->the_bfd_section->name, ".plt"));
|
||||
&& strcmp (s->the_bfd_section->name, ".plt") == 0);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
|
|
@ -989,14 +806,91 @@ in_plt_section (CORE_ADDR pc, char *name)
|
|||
int
|
||||
is_in_import_list (char *name, struct objfile *objfile)
|
||||
{
|
||||
register int i;
|
||||
int i;
|
||||
|
||||
if (!objfile || !name || !*name)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < objfile->import_list_size; i++)
|
||||
if (objfile->import_list[i] && STREQ (name, objfile->import_list[i]))
|
||||
if (objfile->import_list[i] && DEPRECATED_STREQ (name, objfile->import_list[i]))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Keep a registry of per-objfile data-pointers required by other GDB
|
||||
modules. */
|
||||
|
||||
struct objfile_data
|
||||
{
|
||||
unsigned index;
|
||||
};
|
||||
|
||||
struct objfile_data_registration
|
||||
{
|
||||
struct objfile_data *data;
|
||||
struct objfile_data_registration *next;
|
||||
};
|
||||
|
||||
struct objfile_data_registry
|
||||
{
|
||||
struct objfile_data_registration *registrations;
|
||||
unsigned num_registrations;
|
||||
};
|
||||
|
||||
static struct objfile_data_registry objfile_data_registry = { NULL, 0 };
|
||||
|
||||
const struct objfile_data *
|
||||
register_objfile_data (void)
|
||||
{
|
||||
struct objfile_data_registration **curr;
|
||||
|
||||
/* Append new registration. */
|
||||
for (curr = &objfile_data_registry.registrations;
|
||||
*curr != NULL; curr = &(*curr)->next);
|
||||
|
||||
*curr = XMALLOC (struct objfile_data_registration);
|
||||
(*curr)->next = NULL;
|
||||
(*curr)->data = XMALLOC (struct objfile_data);
|
||||
(*curr)->data->index = objfile_data_registry.num_registrations++;
|
||||
|
||||
return (*curr)->data;
|
||||
}
|
||||
|
||||
static void
|
||||
objfile_alloc_data (struct objfile *objfile)
|
||||
{
|
||||
gdb_assert (objfile->data == NULL);
|
||||
objfile->num_data = objfile_data_registry.num_registrations;
|
||||
objfile->data = XCALLOC (objfile->num_data, void *);
|
||||
}
|
||||
|
||||
static void
|
||||
objfile_free_data (struct objfile *objfile)
|
||||
{
|
||||
gdb_assert (objfile->data != NULL);
|
||||
xfree (objfile->data);
|
||||
objfile->data = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
clear_objfile_data (struct objfile *objfile)
|
||||
{
|
||||
gdb_assert (objfile->data != NULL);
|
||||
memset (objfile->data, 0, objfile->num_data * sizeof (void *));
|
||||
}
|
||||
|
||||
void
|
||||
set_objfile_data (struct objfile *objfile, const struct objfile_data *data,
|
||||
void *value)
|
||||
{
|
||||
gdb_assert (data->index < objfile->num_data);
|
||||
objfile->data[data->index] = value;
|
||||
}
|
||||
|
||||
void *
|
||||
objfile_data (struct objfile *objfile, const struct objfile_data *data)
|
||||
{
|
||||
gdb_assert (data->index < objfile->num_data);
|
||||
return objfile->data[data->index];
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,7 @@
|
|||
/* Serial interface for local (hardwired) serial ports on Un*x like systems
|
||||
Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||
2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
|
|
@ -1324,7 +1325,7 @@ ser_unix_async (struct serial *scb,
|
|||
case FD_SCHEDULED:
|
||||
delete_file_handler (scb->fd);
|
||||
break;
|
||||
NOTHING_SCHEDULED:
|
||||
case NOTHING_SCHEDULED:
|
||||
break;
|
||||
default: /* TIMER SCHEDULED */
|
||||
delete_timer (scb->async_state);
|
||||
|
|
@ -1337,7 +1338,7 @@ void
|
|||
_initialize_ser_hardwire (void)
|
||||
{
|
||||
struct serial_ops *ops = XMALLOC (struct serial_ops);
|
||||
memset (ops, sizeof (struct serial_ops), 0);
|
||||
memset (ops, 0, sizeof (struct serial_ops));
|
||||
ops->name = "hardwire";
|
||||
ops->next = 0;
|
||||
ops->open = hardwire_open;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* Handle shared libraries for GDB, the GNU Debugger.
|
||||
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
2000, 2001
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
|
|
@ -40,8 +40,9 @@
|
|||
#include "gdbcmd.h"
|
||||
#include "completer.h"
|
||||
#include "filenames.h" /* for DOSish file names */
|
||||
|
||||
#include "exec.h"
|
||||
#include "solist.h"
|
||||
#include "readline/readline.h"
|
||||
|
||||
/* external data declarations */
|
||||
|
||||
|
|
@ -56,7 +57,7 @@ static int solib_cleanup_queued = 0; /* make_run_cleanup called */
|
|||
|
||||
/* Local function prototypes */
|
||||
|
||||
static void do_clear_solib (PTR);
|
||||
static void do_clear_solib (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. */
|
||||
|
|
@ -86,12 +87,19 @@ static char *solib_search_path = NULL;
|
|||
(or set of directories, as in LD_LIBRARY_PATH) to search for all
|
||||
shared libraries if not found in SOLIB_ABSOLUTE_PREFIX.
|
||||
|
||||
Search order:
|
||||
* If path is absolute, look in SOLIB_ABSOLUTE_PREFIX.
|
||||
* If path is absolute or relative, look for it literally (unmodified).
|
||||
Search algorithm:
|
||||
* If there is a solib_absolute_prefix and path is absolute:
|
||||
* Search for solib_absolute_prefix/path.
|
||||
* else
|
||||
* Look for it literally (unmodified).
|
||||
* Look in SOLIB_SEARCH_PATH.
|
||||
* Look in inferior's $PATH.
|
||||
* Look in inferior's $LD_LIBRARY_PATH.
|
||||
* If available, use target defined search function.
|
||||
* If solib_absolute_prefix is NOT set, perform the following two searches:
|
||||
* Look in inferior's $PATH.
|
||||
* Look in inferior's $LD_LIBRARY_PATH.
|
||||
*
|
||||
* The last check avoids doing this search when targetting remote
|
||||
* machines since solib_absolute_prefix will almost always be set.
|
||||
|
||||
RETURNS
|
||||
|
||||
|
|
@ -146,7 +154,7 @@ solib_open (char *in_pathname, char **found_pathname)
|
|||
in_pathname++;
|
||||
}
|
||||
|
||||
/* If not found, next search the solib_search_path (if any). */
|
||||
/* If not found, search the solib_search_path (if any). */
|
||||
if (found_file < 0 && solib_search_path != NULL)
|
||||
found_file = openp (solib_search_path,
|
||||
1, in_pathname, O_RDONLY, 0, &temp_pathname);
|
||||
|
|
@ -159,14 +167,19 @@ solib_open (char *in_pathname, char **found_pathname)
|
|||
1, lbasename (in_pathname), O_RDONLY, 0,
|
||||
&temp_pathname);
|
||||
|
||||
/* If not found, try to use target supplied solib search method */
|
||||
if (found_file < 0 && TARGET_SO_FIND_AND_OPEN_SOLIB != NULL)
|
||||
found_file = TARGET_SO_FIND_AND_OPEN_SOLIB
|
||||
(in_pathname, O_RDONLY, &temp_pathname);
|
||||
|
||||
/* If not found, next search the inferior's $PATH environment variable. */
|
||||
if (found_file < 0 && solib_search_path != NULL)
|
||||
if (found_file < 0 && solib_absolute_prefix == NULL)
|
||||
found_file = openp (get_in_environ (inferior_environ, "PATH"),
|
||||
1, in_pathname, O_RDONLY, 0, &temp_pathname);
|
||||
|
||||
/* If not found, next search the inferior's $LD_LIBRARY_PATH
|
||||
environment variable. */
|
||||
if (found_file < 0 && solib_search_path != NULL)
|
||||
if (found_file < 0 && solib_absolute_prefix == NULL)
|
||||
found_file = openp (get_in_environ (inferior_environ, "LD_LIBRARY_PATH"),
|
||||
1, in_pathname, O_RDONLY, 0, &temp_pathname);
|
||||
|
||||
|
|
@ -206,7 +219,7 @@ solib_open (char *in_pathname, char **found_pathname)
|
|||
*/
|
||||
|
||||
static int
|
||||
solib_map_sections (PTR arg)
|
||||
solib_map_sections (void *arg)
|
||||
{
|
||||
struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */
|
||||
char *filename;
|
||||
|
|
@ -237,7 +250,7 @@ solib_map_sections (PTR arg)
|
|||
|
||||
/* Leave bfd open, core_xfer_memory and "info files" need it. */
|
||||
so->abfd = abfd;
|
||||
abfd->cacheable = 1;
|
||||
bfd_set_cacheable (abfd, 1);
|
||||
|
||||
/* copy full path name into so_name, so that later symbol_file_add
|
||||
can find it */
|
||||
|
|
@ -262,7 +275,7 @@ solib_map_sections (PTR arg)
|
|||
object's file by the base address to which the object was actually
|
||||
mapped. */
|
||||
TARGET_SO_RELOCATE_SECTION_ADDRESSES (so, p);
|
||||
if (STREQ (p->the_bfd_section->name, ".text"))
|
||||
if (strcmp (p->the_bfd_section->name, ".text") == 0)
|
||||
{
|
||||
so->textsection = p;
|
||||
}
|
||||
|
|
@ -323,9 +336,9 @@ free_so (struct so_list *so)
|
|||
/* A small stub to get us past the arg-passing pinhole of catch_errors. */
|
||||
|
||||
static int
|
||||
symbol_add_stub (PTR arg)
|
||||
symbol_add_stub (void *arg)
|
||||
{
|
||||
register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */
|
||||
struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */
|
||||
struct section_addr_info *sap;
|
||||
|
||||
/* Have we already loaded this shared object? */
|
||||
|
|
@ -375,7 +388,7 @@ symbol_add_stub (PTR arg)
|
|||
the section table. But we only use this for core files and
|
||||
processes we've just attached to, so that's okay. */
|
||||
|
||||
void
|
||||
static void
|
||||
update_solib_list (int from_tty, struct target_ops *target)
|
||||
{
|
||||
struct so_list *inferior = TARGET_SO_CURRENT_SOS ();
|
||||
|
|
@ -386,7 +399,7 @@ update_solib_list (int from_tty, struct target_ops *target)
|
|||
symbols now! */
|
||||
if (attach_flag &&
|
||||
symfile_objfile == NULL)
|
||||
catch_errors (TARGET_SO_OPEN_SYMBOL_FILE_OBJECT, (PTR) &from_tty,
|
||||
catch_errors (TARGET_SO_OPEN_SYMBOL_FILE_OBJECT, &from_tty,
|
||||
"Error reading attached process's symbol file.\n",
|
||||
RETURN_MASK_ALL);
|
||||
|
||||
|
|
@ -614,7 +627,7 @@ solib_add (char *pattern, int from_tty, struct target_ops *target, int readsyms)
|
|||
static void
|
||||
info_sharedlibrary_command (char *ignore, int from_tty)
|
||||
{
|
||||
register struct so_list *so = NULL; /* link map state variable */
|
||||
struct so_list *so = NULL; /* link map state variable */
|
||||
int header_done = 0;
|
||||
int addr_width;
|
||||
char *addr_fmt;
|
||||
|
|
@ -652,13 +665,13 @@ info_sharedlibrary_command (char *ignore, int from_tty)
|
|||
|
||||
printf_unfiltered ("%-*s", addr_width,
|
||||
so->textsection != NULL
|
||||
? longest_local_hex_string_custom (
|
||||
? local_hex_string_custom (
|
||||
(LONGEST) so->textsection->addr,
|
||||
addr_fmt)
|
||||
: "");
|
||||
printf_unfiltered ("%-*s", addr_width,
|
||||
so->textsection != NULL
|
||||
? longest_local_hex_string_custom (
|
||||
? local_hex_string_custom (
|
||||
(LONGEST) so->textsection->endaddr,
|
||||
addr_fmt)
|
||||
: "");
|
||||
|
|
@ -696,7 +709,7 @@ info_sharedlibrary_command (char *ignore, int from_tty)
|
|||
char *
|
||||
solib_address (CORE_ADDR address)
|
||||
{
|
||||
register struct so_list *so = 0; /* link map state variable */
|
||||
struct so_list *so = 0; /* link map state variable */
|
||||
|
||||
for (so = so_list_head; so; so = so->next)
|
||||
{
|
||||
|
|
@ -754,7 +767,7 @@ clear_solib (void)
|
|||
}
|
||||
|
||||
static void
|
||||
do_clear_solib (PTR dummy)
|
||||
do_clear_solib (void *dummy)
|
||||
{
|
||||
solib_cleanup_queued = 0;
|
||||
clear_solib ();
|
||||
|
|
@ -843,6 +856,15 @@ no_shared_libraries (char *ignored, int from_tty)
|
|||
do_clear_solib (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
reload_shared_libraries (char *ignored, int from_tty)
|
||||
{
|
||||
no_shared_libraries (NULL, from_tty);
|
||||
solib_add (NULL, from_tty, NULL, auto_solib_add);
|
||||
}
|
||||
|
||||
extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */
|
||||
|
||||
void
|
||||
_initialize_solib (void)
|
||||
{
|
||||
|
|
@ -872,7 +894,12 @@ inferior. Otherwise, symbols must be loaded manually, using `sharedlibrary'.",
|
|||
For other (relative) files, you can add values using `set solib-search-path'.",
|
||||
&setlist);
|
||||
add_show_from_set (c, &showlist);
|
||||
c->completer = filename_completer;
|
||||
set_cmd_cfunc (c, reload_shared_libraries);
|
||||
set_cmd_completer (c, filename_completer);
|
||||
|
||||
/* Set the default value of "solib-absolute-prefix" from the sysroot, if
|
||||
one is set. */
|
||||
solib_absolute_prefix = xstrdup (gdb_sysroot);
|
||||
|
||||
c = add_set_cmd ("solib-search-path", class_support, var_string,
|
||||
(char *) &solib_search_path,
|
||||
|
|
@ -880,5 +907,6 @@ For other (relative) files, you can add values using `set solib-search-path'.",
|
|||
This takes precedence over the environment variables PATH and LD_LIBRARY_PATH.",
|
||||
&setlist);
|
||||
add_show_from_set (c, &showlist);
|
||||
c->completer = filename_completer;
|
||||
set_cmd_cfunc (c, reload_shared_libraries);
|
||||
set_cmd_completer (c, filename_completer);
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,8 @@
|
|||
/* Interface between GDB and target environments, including files and processes
|
||||
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Cygnus Support. Written by John Gilmore.
|
||||
|
||||
This file is part of GDB.
|
||||
|
|
@ -23,13 +25,18 @@
|
|||
#if !defined (TARGET_H)
|
||||
#define TARGET_H
|
||||
|
||||
struct objfile;
|
||||
struct ui_file;
|
||||
struct mem_attrib;
|
||||
struct target_ops;
|
||||
|
||||
/* This include file defines the interface between the main part
|
||||
of the debugger, and the part which is target-specific, or
|
||||
specific to the communications interface between us and the
|
||||
target.
|
||||
|
||||
A TARGET is an interface between the debugger and a particular
|
||||
kind of file or process. Targets can be STACKED in STRATA,
|
||||
A TARGET is an interface between the debugger and a particular
|
||||
kind of file or process. Targets can be STACKED in STRATA,
|
||||
so that more than one target can potentially respond to a request.
|
||||
In particular, memory accesses will walk down the stack of targets
|
||||
until they find a target that is interested in handling that particular
|
||||
|
|
@ -112,8 +119,8 @@ enum target_waitkind
|
|||
inferior. */
|
||||
TARGET_WAITKIND_SPURIOUS,
|
||||
|
||||
/* This is used for target async and extended-async
|
||||
only. Remote_async_wait() returns this when there is an event
|
||||
/* An event has occured, but we should wait again.
|
||||
Remote_async_wait() returns this when there is an event
|
||||
on the inferior, but the rest of the world is not interested in
|
||||
it. The inferior has not stopped, but has just sent some output
|
||||
to the console, for instance. In this case, we want to go back
|
||||
|
|
@ -148,7 +155,7 @@ enum inferior_event_type
|
|||
INF_QUIT_REQ,
|
||||
/* Process a normal inferior event which will result in target_wait
|
||||
being called. */
|
||||
INF_REG_EVENT,
|
||||
INF_REG_EVENT,
|
||||
/* Deal with an error on the inferior. */
|
||||
INF_ERROR,
|
||||
/* We are called because a timer went off. */
|
||||
|
|
@ -171,6 +178,95 @@ extern char *target_signal_to_name (enum target_signal);
|
|||
/* Given a name (SIGHUP, etc.), return its signal. */
|
||||
enum target_signal target_signal_from_name (char *);
|
||||
|
||||
/* Request the transfer of up to LEN 8-bit bytes of the target's
|
||||
OBJECT. The OFFSET, for a seekable object, specifies the starting
|
||||
point. The ANNEX can be used to provide additional data-specific
|
||||
information to the target.
|
||||
|
||||
Return the number of bytes actually transfered, zero when no
|
||||
further transfer is possible, and -1 when the transfer is not
|
||||
supported.
|
||||
|
||||
NOTE: cagney/2003-10-17: The current interface does not support a
|
||||
"retry" mechanism. Instead it assumes that at least one byte will
|
||||
be transfered on each call.
|
||||
|
||||
NOTE: cagney/2003-10-17: The current interface can lead to
|
||||
fragmented transfers. Lower target levels should not implement
|
||||
hacks, such as enlarging the transfer, in an attempt to compensate
|
||||
for this. Instead, the target stack should be extended so that it
|
||||
implements supply/collect methods and a look-aside object cache.
|
||||
With that available, the lowest target can safely and freely "push"
|
||||
data up the stack.
|
||||
|
||||
NOTE: cagney/2003-10-17: Unlike the old query and the memory
|
||||
transfer mechanisms, these methods are explicitly parameterized by
|
||||
the target that it should be applied to.
|
||||
|
||||
NOTE: cagney/2003-10-17: Just like the old query and memory xfer
|
||||
methods, these new methods perform partial transfers. The only
|
||||
difference is that these new methods thought to include "partial"
|
||||
in the name. The old code's failure to do this lead to much
|
||||
confusion and duplication of effort as each target object attempted
|
||||
to locally take responsibility for something it didn't have to
|
||||
worry about.
|
||||
|
||||
NOTE: cagney/2003-10-17: With a TARGET_OBJECT_KOD object, for
|
||||
backward compatibility with the "target_query" method that this
|
||||
replaced, when OFFSET and LEN are both zero, return the "minimum"
|
||||
buffer size. See "remote.c" for further information. */
|
||||
|
||||
enum target_object
|
||||
{
|
||||
/* Kernel Object Display transfer. See "kod.c" and "remote.c". */
|
||||
TARGET_OBJECT_KOD,
|
||||
/* AVR target specific transfer. See "avr-tdep.c" and "remote.c". */
|
||||
TARGET_OBJECT_AVR,
|
||||
/* Transfer up-to LEN bytes of memory starting at OFFSET. */
|
||||
TARGET_OBJECT_MEMORY,
|
||||
/* Kernel Unwind Table. See "ia64-tdep.c". */
|
||||
TARGET_OBJECT_UNWIND_TABLE,
|
||||
/* Transfer auxilliary vector. */
|
||||
TARGET_OBJECT_AUXV,
|
||||
/* StackGhost cookie. See "sparc-tdep.c". */
|
||||
TARGET_OBJECT_WCOOKIE
|
||||
|
||||
/* Possible future objects: TARGET_OBJECT_FILE, TARGET_OBJECT_PROC, ... */
|
||||
};
|
||||
|
||||
extern LONGEST target_read_partial (struct target_ops *ops,
|
||||
enum target_object object,
|
||||
const char *annex, void *buf,
|
||||
ULONGEST offset, LONGEST len);
|
||||
|
||||
extern LONGEST target_write_partial (struct target_ops *ops,
|
||||
enum target_object object,
|
||||
const char *annex, const void *buf,
|
||||
ULONGEST offset, LONGEST len);
|
||||
|
||||
/* Wrappers to perform the full transfer. */
|
||||
extern LONGEST target_read (struct target_ops *ops,
|
||||
enum target_object object,
|
||||
const char *annex, void *buf,
|
||||
ULONGEST offset, LONGEST len);
|
||||
|
||||
extern LONGEST target_write (struct target_ops *ops,
|
||||
enum target_object object,
|
||||
const char *annex, const void *buf,
|
||||
ULONGEST offset, LONGEST len);
|
||||
|
||||
/* Wrappers to target read/write that perform memory transfers. They
|
||||
throw an error if the memory transfer fails.
|
||||
|
||||
NOTE: cagney/2003-10-23: The naming schema is lifted from
|
||||
"frame.h". The parameter order is lifted from get_frame_memory,
|
||||
which in turn lifted it from read_memory. */
|
||||
|
||||
extern void get_target_memory (struct target_ops *ops, CORE_ADDR addr,
|
||||
void *buf, LONGEST len);
|
||||
extern ULONGEST get_target_memory_unsigned (struct target_ops *ops,
|
||||
CORE_ADDR addr, int len);
|
||||
|
||||
|
||||
/* If certain kinds of activity happen, target_wait should perform
|
||||
callbacks. */
|
||||
|
|
@ -184,18 +280,28 @@ struct thread_info; /* fwd decl for parameter list below: */
|
|||
|
||||
struct target_ops
|
||||
{
|
||||
struct target_ops *beneath; /* To the target under this one. */
|
||||
char *to_shortname; /* Name this target type */
|
||||
char *to_longname; /* Name for printing */
|
||||
char *to_doc; /* Documentation. Does not include trailing
|
||||
newline, and starts with a one-line descrip-
|
||||
tion (probably similar to to_longname). */
|
||||
/* Per-target scratch pad. */
|
||||
void *to_data;
|
||||
/* The open routine takes the rest of the parameters from the
|
||||
command, and (if successful) pushes a new target onto the
|
||||
stack. Targets should supply this routine, if only to provide
|
||||
an error message. */
|
||||
void (*to_open) (char *, int);
|
||||
/* Old targets with a static target vector provide "to_close".
|
||||
New re-entrant targets provide "to_xclose" and that is expected
|
||||
to xfree everything (including the "struct target_ops"). */
|
||||
void (*to_xclose) (struct target_ops *targ, int quitting);
|
||||
void (*to_close) (int);
|
||||
void (*to_attach) (char *, int);
|
||||
void (*to_post_attach) (int);
|
||||
void (*to_require_attach) (char *, int);
|
||||
void (*to_detach) (char *, int);
|
||||
void (*to_require_detach) (int, char *, int);
|
||||
void (*to_disconnect) (char *, int);
|
||||
void (*to_resume) (ptid_t, int, enum target_signal);
|
||||
ptid_t (*to_wait) (ptid_t, struct target_waitstatus *);
|
||||
void (*to_post_wait) (ptid_t, int);
|
||||
|
|
@ -222,40 +328,27 @@ struct target_ops
|
|||
something at MEMADDR + N. */
|
||||
|
||||
int (*to_xfer_memory) (CORE_ADDR memaddr, char *myaddr,
|
||||
int len, int write,
|
||||
int len, int write,
|
||||
struct mem_attrib *attrib,
|
||||
struct target_ops *target);
|
||||
|
||||
#if 0
|
||||
/* Enable this after 4.12. */
|
||||
|
||||
/* Search target memory. Start at STARTADDR and take LEN bytes of
|
||||
target memory, and them with MASK, and compare to DATA. If they
|
||||
match, set *ADDR_FOUND to the address we found it at, store the data
|
||||
we found at LEN bytes starting at DATA_FOUND, and return. If
|
||||
not, add INCREMENT to the search address and keep trying until
|
||||
the search address is outside of the range [LORANGE,HIRANGE).
|
||||
|
||||
If we don't find anything, set *ADDR_FOUND to (CORE_ADDR)0 and
|
||||
return. */
|
||||
|
||||
void (*to_search) (int len, char *data, char *mask,
|
||||
CORE_ADDR startaddr, int increment,
|
||||
CORE_ADDR lorange, CORE_ADDR hirange,
|
||||
CORE_ADDR * addr_found, char *data_found);
|
||||
|
||||
#define target_search(len, data, mask, startaddr, increment, lorange, hirange, addr_found, data_found) \
|
||||
(*current_target.to_search) (len, data, mask, startaddr, increment, \
|
||||
lorange, hirange, addr_found, data_found)
|
||||
#endif /* 0 */
|
||||
|
||||
void (*to_files_info) (struct target_ops *);
|
||||
int (*to_insert_breakpoint) (CORE_ADDR, char *);
|
||||
int (*to_remove_breakpoint) (CORE_ADDR, char *);
|
||||
int (*to_can_use_hw_breakpoint) (int, int, int);
|
||||
int (*to_insert_hw_breakpoint) (CORE_ADDR, char *);
|
||||
int (*to_remove_hw_breakpoint) (CORE_ADDR, char *);
|
||||
int (*to_remove_watchpoint) (CORE_ADDR, int, int);
|
||||
int (*to_insert_watchpoint) (CORE_ADDR, int, int);
|
||||
int (*to_stopped_by_watchpoint) (void);
|
||||
int to_have_continuable_watchpoint;
|
||||
CORE_ADDR (*to_stopped_data_address) (void);
|
||||
int (*to_region_size_ok_for_hw_watchpoint) (int);
|
||||
void (*to_terminal_init) (void);
|
||||
void (*to_terminal_inferior) (void);
|
||||
void (*to_terminal_ours_for_output) (void);
|
||||
void (*to_terminal_ours) (void);
|
||||
void (*to_terminal_save_ours) (void);
|
||||
void (*to_terminal_info) (char *, int);
|
||||
void (*to_kill) (void);
|
||||
void (*to_load) (char *, int);
|
||||
|
|
@ -263,21 +356,14 @@ struct target_ops
|
|||
void (*to_create_inferior) (char *, char *, char **);
|
||||
void (*to_post_startup_inferior) (ptid_t);
|
||||
void (*to_acknowledge_created_inferior) (int);
|
||||
void (*to_clone_and_follow_inferior) (int, int *);
|
||||
void (*to_post_follow_inferior_by_clone) (void);
|
||||
int (*to_insert_fork_catchpoint) (int);
|
||||
int (*to_remove_fork_catchpoint) (int);
|
||||
int (*to_insert_vfork_catchpoint) (int);
|
||||
int (*to_remove_vfork_catchpoint) (int);
|
||||
int (*to_has_forked) (int, int *);
|
||||
int (*to_has_vforked) (int, int *);
|
||||
int (*to_can_follow_vfork_prior_to_exec) (void);
|
||||
void (*to_post_follow_vfork) (int, int, int, int);
|
||||
int (*to_follow_fork) (int);
|
||||
int (*to_insert_exec_catchpoint) (int);
|
||||
int (*to_remove_exec_catchpoint) (int);
|
||||
int (*to_has_execd) (int, char **);
|
||||
int (*to_reported_exec_events_per_exec_call) (void);
|
||||
int (*to_has_syscall_event) (int, enum target_waitkind *, int *);
|
||||
int (*to_has_exited) (int, int, int *);
|
||||
void (*to_mourn_inferior) (void);
|
||||
int (*to_can_run) (void);
|
||||
|
|
@ -287,7 +373,6 @@ struct target_ops
|
|||
char *(*to_pid_to_str) (ptid_t);
|
||||
char *(*to_extra_thread_info) (struct thread_info *);
|
||||
void (*to_stop) (void);
|
||||
int (*to_query) (int /*char */ , char *, char *, int *);
|
||||
void (*to_rcmd) (char *command, struct ui_file *output);
|
||||
struct symtab_and_line *(*to_enable_exception_callback) (enum
|
||||
exception_event_kind,
|
||||
|
|
@ -295,8 +380,6 @@ struct target_ops
|
|||
struct exception_event_record *(*to_get_current_exception_event) (void);
|
||||
char *(*to_pid_to_exec_file) (int pid);
|
||||
enum strata to_stratum;
|
||||
struct target_ops
|
||||
*DONT_USE; /* formerly to_next */
|
||||
int to_has_all_memory;
|
||||
int to_has_memory;
|
||||
int to_has_stack;
|
||||
|
|
@ -313,12 +396,30 @@ struct target_ops
|
|||
void (*to_async) (void (*cb) (enum inferior_event_type, void *context),
|
||||
void *context);
|
||||
int to_async_mask_value;
|
||||
int (*to_find_memory_regions) (int (*) (CORE_ADDR,
|
||||
unsigned long,
|
||||
int, int, int,
|
||||
void *),
|
||||
int (*to_find_memory_regions) (int (*) (CORE_ADDR,
|
||||
unsigned long,
|
||||
int, int, int,
|
||||
void *),
|
||||
void *);
|
||||
char * (*to_make_corefile_notes) (bfd *, int *);
|
||||
|
||||
/* Return the thread-local address at OFFSET in the
|
||||
thread-local storage for the thread PTID and the shared library
|
||||
or executable file given by OBJFILE. If that block of
|
||||
thread-local storage hasn't been allocated yet, this function
|
||||
may return an error. */
|
||||
CORE_ADDR (*to_get_thread_local_address) (ptid_t ptid,
|
||||
struct objfile *objfile,
|
||||
CORE_ADDR offset);
|
||||
|
||||
/* Perform partial transfers on OBJECT. See target_read_partial
|
||||
and target_write_partial for details of each variant. One, and
|
||||
only one, of readbuf or writebuf must be non-NULL. */
|
||||
LONGEST (*to_xfer_partial) (struct target_ops *ops,
|
||||
enum target_object object, const char *annex,
|
||||
void *readbuf, const void *writebuf,
|
||||
ULONGEST offset, LONGEST len);
|
||||
|
||||
int to_magic;
|
||||
/* Need sub-structure for target machine related rather than comm related?
|
||||
*/
|
||||
|
|
@ -335,50 +436,28 @@ struct target_ops
|
|||
|
||||
extern struct target_ops current_target;
|
||||
|
||||
/* An item on the target stack. */
|
||||
|
||||
struct target_stack_item
|
||||
{
|
||||
struct target_stack_item *next;
|
||||
struct target_ops *target_ops;
|
||||
};
|
||||
|
||||
/* The target stack. */
|
||||
|
||||
extern struct target_stack_item *target_stack;
|
||||
|
||||
/* Define easy words for doing these operations on our current target. */
|
||||
|
||||
#define target_shortname (current_target.to_shortname)
|
||||
#define target_longname (current_target.to_longname)
|
||||
|
||||
/* The open routine takes the rest of the parameters from the command,
|
||||
and (if successful) pushes a new target onto the stack.
|
||||
Targets should supply this routine, if only to provide an error message. */
|
||||
/* Does whatever cleanup is required for a target that we are no
|
||||
longer going to be calling. QUITTING indicates that GDB is exiting
|
||||
and should not get hung on an error (otherwise it is important to
|
||||
perform clean termination, even if it takes a while). This routine
|
||||
is automatically always called when popping the target off the
|
||||
target stack (to_beneath is undefined). Closing file descriptors
|
||||
and freeing all memory allocated memory are typical things it
|
||||
should do. */
|
||||
|
||||
#define target_open(name, from_tty) \
|
||||
do { \
|
||||
dcache_invalidate (target_dcache); \
|
||||
(*current_target.to_open) (name, from_tty); \
|
||||
} while (0)
|
||||
|
||||
/* Does whatever cleanup is required for a target that we are no longer
|
||||
going to be calling. Argument says whether we are quitting gdb and
|
||||
should not get hung in case of errors, or whether we want a clean
|
||||
termination even if it takes a while. This routine is automatically
|
||||
always called just before a routine is popped off the target stack.
|
||||
Closing file descriptors and freeing memory are typical things it should
|
||||
do. */
|
||||
|
||||
#define target_close(quitting) \
|
||||
(*current_target.to_close) (quitting)
|
||||
void target_close (struct target_ops *targ, int quitting);
|
||||
|
||||
/* Attaches to a process on the target side. Arguments are as passed
|
||||
to the `attach' command by the user. This routine can be called
|
||||
when the target is not on the target-stack, if the target_can_run
|
||||
routine returns 1; in that case, it must push itself onto the stack.
|
||||
routine returns 1; in that case, it must push itself onto the stack.
|
||||
Upon exit, the target should be ready for normal operations, and
|
||||
should be ready to deliver the status of the process immediately
|
||||
should be ready to deliver the status of the process immediately
|
||||
(without waiting) to an upcoming target_wait call. */
|
||||
|
||||
#define target_attach(args, from_tty) \
|
||||
|
|
@ -392,17 +471,6 @@ extern struct target_stack_item *target_stack;
|
|||
#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
|
||||
|
|
@ -412,20 +480,10 @@ extern struct target_stack_item *target_stack;
|
|||
|
||||
extern void target_detach (char *, int);
|
||||
|
||||
/* Detaches from a process on the target side, if not already dettached.
|
||||
(If already detached, takes no action.)
|
||||
/* Disconnect from the current target without resuming it (leaving it
|
||||
waiting for a debugger). */
|
||||
|
||||
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)
|
||||
extern void target_disconnect (char *, int);
|
||||
|
||||
/* Resume execution of the target process PTID. STEP says whether to
|
||||
single-step or to run free; SIGGNAL is the signal to be given to
|
||||
|
|
@ -494,10 +552,10 @@ extern int target_read_memory (CORE_ADDR memaddr, char *myaddr, int len);
|
|||
|
||||
extern int target_write_memory (CORE_ADDR memaddr, char *myaddr, int len);
|
||||
|
||||
extern int xfer_memory (CORE_ADDR, char *, int, int,
|
||||
extern int xfer_memory (CORE_ADDR, char *, int, int,
|
||||
struct mem_attrib *, struct target_ops *);
|
||||
|
||||
extern int child_xfer_memory (CORE_ADDR, char *, int, int,
|
||||
extern int child_xfer_memory (CORE_ADDR, char *, int, int,
|
||||
struct mem_attrib *, struct target_ops *);
|
||||
|
||||
/* Make a single attempt at transfering LEN bytes. On a successful
|
||||
|
|
@ -506,11 +564,11 @@ extern int child_xfer_memory (CORE_ADDR, char *, int, int,
|
|||
of bytes actually transfered is not defined) and ERR is set to a
|
||||
non-zero error indication. */
|
||||
|
||||
extern int
|
||||
target_read_memory_partial (CORE_ADDR addr, char *buf, int len, int *err);
|
||||
extern int target_read_memory_partial (CORE_ADDR addr, char *buf, int len,
|
||||
int *err);
|
||||
|
||||
extern int
|
||||
target_write_memory_partial (CORE_ADDR addr, char *buf, int len, int *err);
|
||||
extern int target_write_memory_partial (CORE_ADDR addr, char *buf, int len,
|
||||
int *err);
|
||||
|
||||
extern char *child_pid_to_exec_file (int);
|
||||
|
||||
|
|
@ -526,10 +584,6 @@ extern void child_post_startup_inferior (ptid_t);
|
|||
|
||||
extern void child_acknowledge_created_inferior (int);
|
||||
|
||||
extern void child_clone_and_follow_inferior (int, int *);
|
||||
|
||||
extern void child_post_follow_inferior_by_clone (void);
|
||||
|
||||
extern int child_insert_fork_catchpoint (int);
|
||||
|
||||
extern int child_remove_fork_catchpoint (int);
|
||||
|
|
@ -538,30 +592,28 @@ extern int child_insert_vfork_catchpoint (int);
|
|||
|
||||
extern int child_remove_vfork_catchpoint (int);
|
||||
|
||||
extern int child_has_forked (int, int *);
|
||||
|
||||
extern int child_has_vforked (int, int *);
|
||||
|
||||
extern void child_acknowledge_created_inferior (int);
|
||||
|
||||
extern int child_can_follow_vfork_prior_to_exec (void);
|
||||
|
||||
extern void child_post_follow_vfork (int, int, int, int);
|
||||
extern int child_follow_fork (int);
|
||||
|
||||
extern int child_insert_exec_catchpoint (int);
|
||||
|
||||
extern int child_remove_exec_catchpoint (int);
|
||||
|
||||
extern int child_has_execd (int, char **);
|
||||
|
||||
extern int child_reported_exec_events_per_exec_call (void);
|
||||
|
||||
extern int child_has_syscall_event (int, enum target_waitkind *, int *);
|
||||
|
||||
extern int child_has_exited (int, int, int *);
|
||||
|
||||
extern int child_thread_alive (ptid_t);
|
||||
|
||||
/* From infrun.c. */
|
||||
|
||||
extern int inferior_has_forked (int pid, int *child_pid);
|
||||
|
||||
extern int inferior_has_vforked (int pid, int *child_pid);
|
||||
|
||||
extern int inferior_has_execd (int pid, char **execd_pathname);
|
||||
|
||||
/* From exec.c */
|
||||
|
||||
extern void print_section_info (struct target_ops *, bfd *);
|
||||
|
|
@ -571,18 +623,18 @@ extern void print_section_info (struct target_ops *, bfd *);
|
|||
#define target_files_info() \
|
||||
(*current_target.to_files_info) (¤t_target)
|
||||
|
||||
/* Insert a breakpoint at address ADDR in the target machine.
|
||||
SAVE is a pointer to memory allocated for saving the
|
||||
target contents. It is guaranteed by the caller to be long enough
|
||||
to save "sizeof BREAKPOINT" bytes. Result is 0 for success, or
|
||||
an errno value. */
|
||||
/* Insert a breakpoint at address ADDR in the target machine. SAVE is
|
||||
a pointer to memory allocated for saving the target contents. It
|
||||
is guaranteed by the caller to be long enough to save the number of
|
||||
breakpoint bytes indicated by BREAKPOINT_FROM_PC. Result is 0 for
|
||||
success, or an errno value. */
|
||||
|
||||
#define target_insert_breakpoint(addr, save) \
|
||||
(*current_target.to_insert_breakpoint) (addr, save)
|
||||
|
||||
/* Remove a breakpoint at address ADDR in the target machine.
|
||||
SAVE is a pointer to the same save area
|
||||
that was previously passed to target_insert_breakpoint.
|
||||
SAVE is a pointer to the same save area
|
||||
that was previously passed to target_insert_breakpoint.
|
||||
Result is 0 for success, or an errno value. */
|
||||
|
||||
#define target_remove_breakpoint(addr, save) \
|
||||
|
|
@ -618,6 +670,14 @@ extern void print_section_info (struct target_ops *, bfd *);
|
|||
#define target_terminal_ours() \
|
||||
(*current_target.to_terminal_ours) ()
|
||||
|
||||
/* Save our terminal settings.
|
||||
This is called from TUI after entering or leaving the curses
|
||||
mode. Since curses modifies our terminal this call is here
|
||||
to take this change into account. */
|
||||
|
||||
#define target_terminal_save_ours() \
|
||||
(*current_target.to_terminal_save_ours) ()
|
||||
|
||||
/* Print useful information about our terminal status, if such a thing
|
||||
exists. */
|
||||
|
||||
|
|
@ -675,33 +735,6 @@ extern void target_load (char *arg, int from_tty);
|
|||
#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. */
|
||||
|
|
@ -718,42 +751,16 @@ extern void target_load (char *arg, int from_tty);
|
|||
#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. */
|
||||
/* If the inferior forks or vforks, this function will be called at
|
||||
the next resume in order to perform any bookkeeping and fiddling
|
||||
necessary to continue debugging either the parent or child, as
|
||||
requested, and releasing the other. Information about the fork
|
||||
or vfork event is available via get_last_target_status ().
|
||||
This function returns 1 if the inferior should not be resumed
|
||||
(i.e. there is another event pending). */
|
||||
|
||||
#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)
|
||||
#define target_follow_fork(follow_child) \
|
||||
(*current_target.to_follow_fork) (follow_child)
|
||||
|
||||
/* On some targets, we can catch an inferior exec event when it
|
||||
occurs. These functions insert/remove an already-created
|
||||
|
|
@ -765,13 +772,6 @@ extern void target_load (char *arg, int from_tty);
|
|||
#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. */
|
||||
|
|
@ -779,13 +779,6 @@ extern void target_load (char *arg, int from_tty);
|
|||
#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. */
|
||||
|
||||
|
|
@ -793,7 +786,7 @@ extern void target_load (char *arg, int from_tty);
|
|||
(*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
|
||||
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. */
|
||||
|
||||
|
|
@ -828,16 +821,6 @@ extern void target_load (char *arg, int from_tty);
|
|||
|
||||
#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)
|
||||
|
||||
/* Send the specified COMMAND to the target's monitor
|
||||
(shell,interpreter) for execution. The result of the query is
|
||||
placed in OUTBUF. */
|
||||
|
|
@ -847,7 +830,7 @@ extern void target_load (char *arg, int from_tty);
|
|||
|
||||
|
||||
/* Get the symbol information for a breakpointable routine called when
|
||||
an exception event occurs.
|
||||
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
|
||||
|
|
@ -861,11 +844,6 @@ extern void target_load (char *arg, int from_tty);
|
|||
#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. */
|
||||
|
||||
#define target_next \
|
||||
(current_target.to_next)
|
||||
|
||||
/* Does the target include all of memory, or only part of it? This
|
||||
determines whether we look up the target chain for other parts of
|
||||
memory if this target can't satisfy a request. */
|
||||
|
|
@ -919,15 +897,15 @@ extern void target_load (char *arg, int from_tty);
|
|||
#define target_async(CALLBACK,CONTEXT) \
|
||||
(current_target.to_async((CALLBACK), (CONTEXT)))
|
||||
|
||||
/* This is to be used ONLY within run_stack_dummy(). It
|
||||
provides a workaround, to have inferior function calls done in
|
||||
sychronous mode, even though the target is asynchronous. After
|
||||
/* This is to be used ONLY within call_function_by_hand(). It provides
|
||||
a workaround, to have inferior function calls done in sychronous
|
||||
mode, even though the target is asynchronous. After
|
||||
target_async_mask(0) is called, calls to target_can_async_p() will
|
||||
return FALSE , so that target_resume() will not try to start the
|
||||
target asynchronously. After the inferior stops, we IMMEDIATELY
|
||||
restore the previous nature of the target, by calling
|
||||
target_async_mask(1). After that, target_can_async_p() will return
|
||||
TRUE. ANY OTHER USE OF THIS FEATURE IS DEPRECATED.
|
||||
TRUE. ANY OTHER USE OF THIS FEATURE IS DEPRECATED.
|
||||
|
||||
FIXME ezannoni 1999-12-13: we won't need this once we move
|
||||
the turning async on and off to the single execution commands,
|
||||
|
|
@ -936,7 +914,7 @@ extern void target_load (char *arg, int from_tty);
|
|||
#define target_async_mask_value \
|
||||
(current_target.to_async_mask_value)
|
||||
|
||||
extern int target_async_mask (int mask);
|
||||
extern int target_async_mask (int mask);
|
||||
|
||||
extern void target_link (char *, CORE_ADDR *);
|
||||
|
||||
|
|
@ -964,7 +942,7 @@ extern char *normal_pid_to_str (ptid_t ptid);
|
|||
* New Objfile Event Hook:
|
||||
*
|
||||
* Sometimes a GDB component wants to get notified whenever a new
|
||||
* objfile is loaded. Mainly this is used by thread-debugging
|
||||
* objfile is loaded. Mainly this is used by thread-debugging
|
||||
* implementations that need to know when symbols for the target
|
||||
* thread implemenation are available.
|
||||
*
|
||||
|
|
@ -1009,7 +987,7 @@ extern void (*target_new_objfile_hook) (struct objfile *);
|
|||
* Iterator function for target memory regions.
|
||||
* Calls a callback function once for each memory region 'mapped'
|
||||
* in the child process. Defined as a simple macro rather than
|
||||
* as a function macro so that it can be tested for nullity.
|
||||
* as a function macro so that it can be tested for nullity.
|
||||
*/
|
||||
|
||||
#define target_find_memory_regions(FUNC, DATA) \
|
||||
|
|
@ -1022,11 +1000,11 @@ extern void (*target_new_objfile_hook) (struct objfile *);
|
|||
#define target_make_corefile_notes(BFD, SIZE_P) \
|
||||
(current_target.to_make_corefile_notes) (BFD, SIZE_P)
|
||||
|
||||
/* Hook to call target-dependent code after reading in a new symbol table. */
|
||||
|
||||
#ifndef TARGET_SYMFILE_POSTREAD
|
||||
#define TARGET_SYMFILE_POSTREAD(OBJFILE)
|
||||
#endif
|
||||
/* Thread-local values. */
|
||||
#define target_get_thread_local_address \
|
||||
(current_target.to_get_thread_local_address)
|
||||
#define target_get_thread_local_address_p() \
|
||||
(target_get_thread_local_address != NULL)
|
||||
|
||||
/* Hook to call target dependent code just after inferior target process has
|
||||
started. */
|
||||
|
|
@ -1041,7 +1019,15 @@ extern void (*target_new_objfile_hook) (struct objfile *);
|
|||
write). */
|
||||
|
||||
#ifndef STOPPED_BY_WATCHPOINT
|
||||
#define STOPPED_BY_WATCHPOINT(w) 0
|
||||
#define STOPPED_BY_WATCHPOINT(w) \
|
||||
(*current_target.to_stopped_by_watchpoint) ()
|
||||
#endif
|
||||
|
||||
/* Non-zero if we have continuable watchpoints */
|
||||
|
||||
#ifndef HAVE_CONTINUABLE_WATCHPOINT
|
||||
#define HAVE_CONTINUABLE_WATCHPOINT \
|
||||
(current_target.to_have_continuable_watchpoint)
|
||||
#endif
|
||||
|
||||
/* HP-UX supplies these operations, which respectively disable and enable
|
||||
|
|
@ -1056,20 +1042,24 @@ extern void (*target_new_objfile_hook) (struct objfile *);
|
|||
#define TARGET_ENABLE_HW_WATCHPOINTS(pid)
|
||||
#endif
|
||||
|
||||
/* Provide defaults for systems that don't support hardware watchpoints. */
|
||||
/* Provide defaults for hardware watchpoint functions. */
|
||||
|
||||
#ifndef TARGET_HAS_HARDWARE_WATCHPOINTS
|
||||
/* If the *_hw_beakpoint functions have not been defined
|
||||
elsewhere use the definitions in the target vector. */
|
||||
|
||||
/* Returns non-zero if we can set a hardware watchpoint of type TYPE. TYPE is
|
||||
one of bp_hardware_watchpoint, bp_read_watchpoint, bp_write_watchpoint, or
|
||||
bp_hardware_breakpoint. CNT is the number of such watchpoints used so far
|
||||
(including this one?). OTHERTYPE is who knows what... */
|
||||
|
||||
#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(TYPE,CNT,OTHERTYPE) 0
|
||||
#ifndef TARGET_CAN_USE_HARDWARE_WATCHPOINT
|
||||
#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(TYPE,CNT,OTHERTYPE) \
|
||||
(*current_target.to_can_use_hw_breakpoint) (TYPE, CNT, OTHERTYPE);
|
||||
#endif
|
||||
|
||||
#if !defined(TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT)
|
||||
#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(byte_count) \
|
||||
((LONGEST)(byte_count) <= REGISTER_SIZE)
|
||||
(*current_target.to_region_size_ok_for_hw_watchpoint) (byte_count)
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -1077,25 +1067,25 @@ extern void (*target_new_objfile_hook) (struct objfile *);
|
|||
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
|
||||
#ifndef target_insert_watchpoint
|
||||
#define target_insert_watchpoint(addr, len, type) \
|
||||
(*current_target.to_insert_watchpoint) (addr, len, type)
|
||||
|
||||
#endif /* TARGET_HAS_HARDWARE_WATCHPOINTS */
|
||||
#define target_remove_watchpoint(addr, len, type) \
|
||||
(*current_target.to_remove_watchpoint) (addr, len, type)
|
||||
#endif
|
||||
|
||||
#ifndef target_insert_hw_breakpoint
|
||||
#define target_remove_hw_breakpoint(ADDR,SHADOW) -1
|
||||
#define target_insert_hw_breakpoint(ADDR,SHADOW) -1
|
||||
#define target_insert_hw_breakpoint(addr, save) \
|
||||
(*current_target.to_insert_hw_breakpoint) (addr, save)
|
||||
|
||||
#define target_remove_hw_breakpoint(addr, save) \
|
||||
(*current_target.to_remove_hw_breakpoint) (addr, save)
|
||||
#endif
|
||||
|
||||
#ifndef target_stopped_data_address
|
||||
#define target_stopped_data_address() 0
|
||||
#endif
|
||||
|
||||
/* If defined, then we need to decr pc by this much after a hardware break-
|
||||
point. Presumably this overrides DECR_PC_AFTER_BREAK... */
|
||||
|
||||
#ifndef DECR_PC_AFTER_HW_BREAK
|
||||
#define DECR_PC_AFTER_HW_BREAK 0
|
||||
#define target_stopped_data_address() \
|
||||
(*current_target.to_stopped_data_address) ()
|
||||
#endif
|
||||
|
||||
/* Sometimes gdb may pick up what appears to be a valid target address
|
||||
|
|
@ -1163,16 +1153,15 @@ struct section_table
|
|||
CORE_ADDR addr; /* Lowest address in section */
|
||||
CORE_ADDR endaddr; /* 1+highest address in section */
|
||||
|
||||
sec_ptr the_bfd_section;
|
||||
struct bfd_section *the_bfd_section;
|
||||
|
||||
bfd *bfd; /* BFD file pointer */
|
||||
};
|
||||
|
||||
/* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR.
|
||||
Returns 0 if OK, 1 on error. */
|
||||
/* Return the "section" containing the specified address. */
|
||||
struct section_table *target_section_by_addr (struct target_ops *target,
|
||||
CORE_ADDR addr);
|
||||
|
||||
extern int
|
||||
build_section_table (bfd *, struct section_table **, struct section_table **);
|
||||
|
||||
/* From mem-break.c */
|
||||
|
||||
|
|
@ -1184,8 +1173,6 @@ extern int default_memory_remove_breakpoint (CORE_ADDR, char *);
|
|||
|
||||
extern int default_memory_insert_breakpoint (CORE_ADDR, char *);
|
||||
|
||||
extern breakpoint_from_pc_fn memory_breakpoint_from_pc;
|
||||
|
||||
|
||||
/* From target.c */
|
||||
|
||||
|
|
@ -1195,22 +1182,16 @@ extern void noprocess (void);
|
|||
|
||||
extern void find_default_attach (char *, int);
|
||||
|
||||
extern void find_default_require_attach (char *, int);
|
||||
|
||||
extern void find_default_require_detach (int, char *, int);
|
||||
|
||||
extern void find_default_create_inferior (char *, char *, char **);
|
||||
|
||||
extern void find_default_clone_and_follow_inferior (int, int *);
|
||||
|
||||
extern struct target_ops *find_run_target (void);
|
||||
|
||||
extern struct target_ops *find_core_target (void);
|
||||
|
||||
extern struct target_ops *find_target_beneath (struct target_ops *);
|
||||
|
||||
extern int
|
||||
target_resize_to_sections (struct target_ops *target, int num_added);
|
||||
extern int target_resize_to_sections (struct target_ops *target,
|
||||
int num_added);
|
||||
|
||||
extern void remove_target_sections (bfd *abfd);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* Multi-process/thread control for GDB, the GNU debugger.
|
||||
|
||||
Copyright 1986, 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA.
|
||||
|
||||
|
|
@ -34,6 +34,7 @@
|
|||
#include "gdbcmd.h"
|
||||
#include "regcache.h"
|
||||
#include "gdb.h"
|
||||
#include "gdb_string.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
|
|
@ -254,14 +255,17 @@ in_thread_list (ptid_t ptid)
|
|||
|
||||
/* Print a list of thread ids currently known, and the total number of
|
||||
threads. To be used from within catch_errors. */
|
||||
static int
|
||||
do_captured_list_thread_ids (struct ui_out *uiout,
|
||||
void *arg)
|
||||
static int
|
||||
do_captured_list_thread_ids (struct ui_out *uiout, void *arg)
|
||||
{
|
||||
struct thread_info *tp;
|
||||
int num = 0;
|
||||
struct cleanup *cleanup_chain;
|
||||
|
||||
ui_out_tuple_begin (uiout, "thread-ids");
|
||||
prune_threads ();
|
||||
target_find_new_threads ();
|
||||
|
||||
cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "thread-ids");
|
||||
|
||||
for (tp = thread_list; tp; tp = tp->next)
|
||||
{
|
||||
|
|
@ -269,7 +273,7 @@ do_captured_list_thread_ids (struct ui_out *uiout,
|
|||
ui_out_field_int (uiout, "thread-id", tp->num);
|
||||
}
|
||||
|
||||
ui_out_tuple_end (uiout);
|
||||
do_cleanups (cleanup_chain);
|
||||
ui_out_field_int (uiout, "number-of-threads", num);
|
||||
return GDB_RC_OK;
|
||||
}
|
||||
|
|
@ -286,24 +290,21 @@ gdb_list_thread_ids (struct ui_out *uiout)
|
|||
/* Load infrun state for the thread PID. */
|
||||
|
||||
void
|
||||
load_infrun_state (ptid_t ptid,
|
||||
CORE_ADDR *prev_pc,
|
||||
CORE_ADDR *prev_func_start,
|
||||
char **prev_func_name,
|
||||
load_infrun_state (ptid_t ptid,
|
||||
CORE_ADDR *prev_pc,
|
||||
int *trap_expected,
|
||||
struct breakpoint **step_resume_breakpoint,
|
||||
struct breakpoint **through_sigtramp_breakpoint,
|
||||
CORE_ADDR *step_range_start,
|
||||
CORE_ADDR *step_range_start,
|
||||
CORE_ADDR *step_range_end,
|
||||
CORE_ADDR *step_frame_address,
|
||||
struct frame_id *step_frame_id,
|
||||
int *handling_longjmp,
|
||||
int *another_trap,
|
||||
int *another_trap,
|
||||
int *stepping_through_solib_after_catch,
|
||||
bpstat *stepping_through_solib_catchpoints,
|
||||
int *stepping_through_sigtramp,
|
||||
int *current_line,
|
||||
struct symtab **current_symtab,
|
||||
CORE_ADDR *step_sp)
|
||||
int *current_line,
|
||||
struct symtab **current_symtab, CORE_ADDR *step_sp)
|
||||
{
|
||||
struct thread_info *tp;
|
||||
|
||||
|
|
@ -314,18 +315,18 @@ load_infrun_state (ptid_t ptid,
|
|||
return;
|
||||
|
||||
*prev_pc = tp->prev_pc;
|
||||
*prev_func_start = tp->prev_func_start;
|
||||
*prev_func_name = tp->prev_func_name;
|
||||
*trap_expected = tp->trap_expected;
|
||||
*step_resume_breakpoint = tp->step_resume_breakpoint;
|
||||
*through_sigtramp_breakpoint = tp->through_sigtramp_breakpoint;
|
||||
*step_range_start = tp->step_range_start;
|
||||
*step_range_end = tp->step_range_end;
|
||||
*step_frame_address = tp->step_frame_address;
|
||||
*step_frame_id = tp->step_frame_id;
|
||||
*handling_longjmp = tp->handling_longjmp;
|
||||
*another_trap = tp->another_trap;
|
||||
*stepping_through_solib_after_catch = tp->stepping_through_solib_after_catch;
|
||||
*stepping_through_solib_catchpoints = tp->stepping_through_solib_catchpoints;
|
||||
*stepping_through_solib_after_catch =
|
||||
tp->stepping_through_solib_after_catch;
|
||||
*stepping_through_solib_catchpoints =
|
||||
tp->stepping_through_solib_catchpoints;
|
||||
*stepping_through_sigtramp = tp->stepping_through_sigtramp;
|
||||
*current_line = tp->current_line;
|
||||
*current_symtab = tp->current_symtab;
|
||||
|
|
@ -335,24 +336,21 @@ load_infrun_state (ptid_t ptid,
|
|||
/* Save infrun state for the thread PID. */
|
||||
|
||||
void
|
||||
save_infrun_state (ptid_t ptid,
|
||||
CORE_ADDR prev_pc,
|
||||
CORE_ADDR prev_func_start,
|
||||
char *prev_func_name,
|
||||
save_infrun_state (ptid_t ptid,
|
||||
CORE_ADDR prev_pc,
|
||||
int trap_expected,
|
||||
struct breakpoint *step_resume_breakpoint,
|
||||
struct breakpoint *through_sigtramp_breakpoint,
|
||||
CORE_ADDR step_range_start,
|
||||
CORE_ADDR step_range_start,
|
||||
CORE_ADDR step_range_end,
|
||||
CORE_ADDR step_frame_address,
|
||||
const struct frame_id *step_frame_id,
|
||||
int handling_longjmp,
|
||||
int another_trap,
|
||||
int another_trap,
|
||||
int stepping_through_solib_after_catch,
|
||||
bpstat stepping_through_solib_catchpoints,
|
||||
int stepping_through_sigtramp,
|
||||
int stepping_through_sigtramp,
|
||||
int current_line,
|
||||
struct symtab *current_symtab,
|
||||
CORE_ADDR step_sp)
|
||||
struct symtab *current_symtab, CORE_ADDR step_sp)
|
||||
{
|
||||
struct thread_info *tp;
|
||||
|
||||
|
|
@ -363,14 +361,12 @@ save_infrun_state (ptid_t ptid,
|
|||
return;
|
||||
|
||||
tp->prev_pc = prev_pc;
|
||||
tp->prev_func_start = prev_func_start;
|
||||
tp->prev_func_name = prev_func_name;
|
||||
tp->trap_expected = trap_expected;
|
||||
tp->step_resume_breakpoint = step_resume_breakpoint;
|
||||
tp->through_sigtramp_breakpoint = through_sigtramp_breakpoint;
|
||||
tp->step_range_start = step_range_start;
|
||||
tp->step_range_end = step_range_end;
|
||||
tp->step_frame_address = step_frame_address;
|
||||
tp->step_frame_id = (*step_frame_id);
|
||||
tp->handling_longjmp = handling_longjmp;
|
||||
tp->another_trap = another_trap;
|
||||
tp->stepping_through_solib_after_catch = stepping_through_solib_after_catch;
|
||||
|
|
@ -421,14 +417,14 @@ info_threads_command (char *arg, int from_tty)
|
|||
struct thread_info *tp;
|
||||
ptid_t current_ptid;
|
||||
struct frame_info *cur_frame;
|
||||
int saved_frame_level = selected_frame_level;
|
||||
int saved_frame_level = frame_relative_level (get_selected_frame ());
|
||||
int counter;
|
||||
char *extra_info;
|
||||
|
||||
/* Avoid coredumps which would happen if we tried to access a NULL
|
||||
selected_frame. */
|
||||
if (!target_has_stack)
|
||||
error ("No stack.");
|
||||
/* Check that there really is a frame. This happens when a simulator
|
||||
is connected but not loaded or running, for instance. */
|
||||
if (legacy_frame_p (current_gdbarch) && saved_frame_level < 0)
|
||||
error ("No frame.");
|
||||
|
||||
prune_threads ();
|
||||
target_find_new_threads ();
|
||||
|
|
@ -452,10 +448,7 @@ info_threads_command (char *arg, int from_tty)
|
|||
puts_filtered (" ");
|
||||
|
||||
switch_to_thread (tp->ptid);
|
||||
if (selected_frame)
|
||||
print_only_stack_frame (selected_frame, -1, 0);
|
||||
else
|
||||
printf_filtered ("[No stack.]\n");
|
||||
print_stack_frame (get_selected_frame (), -1, 0);
|
||||
}
|
||||
|
||||
switch_to_thread (current_ptid);
|
||||
|
|
@ -467,16 +460,16 @@ info_threads_command (char *arg, int from_tty)
|
|||
* of the stack (leaf frame).
|
||||
*/
|
||||
counter = saved_frame_level;
|
||||
cur_frame = find_relative_frame (selected_frame, &counter);
|
||||
cur_frame = find_relative_frame (get_selected_frame (), &counter);
|
||||
if (counter != 0)
|
||||
{
|
||||
/* Ooops, can't restore, tell user where we are. */
|
||||
warning ("Couldn't restore frame in current thread, at frame 0");
|
||||
print_stack_frame (selected_frame, -1, 0);
|
||||
print_stack_frame (get_selected_frame (), -1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
select_frame (cur_frame, saved_frame_level);
|
||||
select_frame (cur_frame);
|
||||
}
|
||||
|
||||
/* re-show current frame. */
|
||||
|
|
@ -495,13 +488,13 @@ switch_to_thread (ptid_t ptid)
|
|||
flush_cached_frames ();
|
||||
registers_changed ();
|
||||
stop_pc = read_pc ();
|
||||
select_frame (get_current_frame (), 0);
|
||||
select_frame (get_current_frame ());
|
||||
}
|
||||
|
||||
static void
|
||||
restore_current_thread (ptid_t ptid)
|
||||
{
|
||||
if (! ptid_equal (ptid, inferior_ptid))
|
||||
if (!ptid_equal (ptid, inferior_ptid))
|
||||
{
|
||||
switch_to_thread (ptid);
|
||||
print_stack_frame (get_current_frame (), 0, -1);
|
||||
|
|
@ -566,14 +559,13 @@ thread_apply_all_command (char *cmd, int from_tty)
|
|||
switch_to_thread (tp->ptid);
|
||||
#ifdef HPUXHPPA
|
||||
printf_filtered ("\nThread %d (%s):\n",
|
||||
tp->num,
|
||||
target_tid_to_str (inferior_ptid));
|
||||
tp->num, target_tid_to_str (inferior_ptid));
|
||||
#else
|
||||
printf_filtered ("\nThread %d (%s):\n", tp->num,
|
||||
target_pid_to_str (inferior_ptid));
|
||||
#endif
|
||||
execute_command (cmd, from_tty);
|
||||
strcpy (cmd, saved_cmd); /* Restore exact command used previously */
|
||||
strcpy (cmd, saved_cmd); /* Restore exact command used previously */
|
||||
}
|
||||
|
||||
do_cleanups (saved_cmd_cleanup_chain);
|
||||
|
|
@ -685,8 +677,7 @@ thread_command (char *tidstr, int from_tty)
|
|||
}
|
||||
|
||||
static int
|
||||
do_captured_thread_select (struct ui_out *uiout,
|
||||
void *tidstr)
|
||||
do_captured_thread_select (struct ui_out *uiout, void *tidstr)
|
||||
{
|
||||
int num;
|
||||
struct thread_info *tp;
|
||||
|
|
@ -713,13 +704,13 @@ do_captured_thread_select (struct ui_out *uiout,
|
|||
#endif
|
||||
ui_out_text (uiout, ")]");
|
||||
|
||||
print_stack_frame (selected_frame, selected_frame_level, 1);
|
||||
print_stack_frame (deprecated_selected_frame,
|
||||
frame_relative_level (deprecated_selected_frame), 1);
|
||||
return GDB_RC_OK;
|
||||
}
|
||||
|
||||
enum gdb_rc
|
||||
gdb_thread_select (struct ui_out *uiout,
|
||||
char *tidstr)
|
||||
gdb_thread_select (struct ui_out *uiout, char *tidstr)
|
||||
{
|
||||
return catch_exceptions (uiout, do_captured_thread_select, tidstr,
|
||||
NULL, RETURN_MASK_ALL);
|
||||
|
|
@ -738,16 +729,14 @@ _initialize_thread (void)
|
|||
|
||||
add_prefix_cmd ("thread", class_run, thread_command,
|
||||
"Use this command to switch between threads.\n\
|
||||
The new thread ID must be currently known.", &thread_cmd_list, "thread ", 1,
|
||||
&cmdlist);
|
||||
The new thread ID must be currently known.", &thread_cmd_list, "thread ", 1, &cmdlist);
|
||||
|
||||
add_prefix_cmd ("apply", class_run, thread_apply_command,
|
||||
"Apply a command to a list of threads.",
|
||||
&thread_apply_list, "apply ", 1, &thread_cmd_list);
|
||||
|
||||
add_cmd ("all", class_run, thread_apply_all_command,
|
||||
"Apply a command to all threads.",
|
||||
&thread_apply_list);
|
||||
"Apply a command to all threads.", &thread_apply_list);
|
||||
|
||||
if (!xdb_commands)
|
||||
add_com_alias ("t", "thread", class_run, 1);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* Top level stuff for GDB, the GNU debugger.
|
||||
|
||||
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
|
||||
1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
|
@ -27,6 +27,7 @@
|
|||
#include "cli/cli-cmds.h"
|
||||
#include "cli/cli-script.h"
|
||||
#include "cli/cli-setshow.h"
|
||||
#include "cli/cli-decode.h"
|
||||
#include "symtab.h"
|
||||
#include "inferior.h"
|
||||
#include <signal.h>
|
||||
|
|
@ -46,8 +47,8 @@
|
|||
#include "gdb_assert.h"
|
||||
|
||||
/* readline include files */
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#include "readline/readline.h"
|
||||
#include "readline/history.h"
|
||||
|
||||
/* readline defines this. */
|
||||
#undef savestring
|
||||
|
|
@ -81,7 +82,7 @@ int inhibit_gdbinit = 0;
|
|||
/* If nonzero, and GDB has been configured to be able to use windows,
|
||||
attempt to open them upon startup. */
|
||||
|
||||
int use_windows = 1;
|
||||
int use_windows = 0;
|
||||
|
||||
extern char lang_frame_mismatch_warn[]; /* language.c */
|
||||
|
||||
|
|
@ -146,7 +147,7 @@ int baud_rate = -1;
|
|||
In mid-1996, remote_timeout was moved from remote.c to top.c and
|
||||
it began being used in other remote-* targets. It appears that the
|
||||
default was changed to 20 seconds at that time, perhaps because the
|
||||
Hitachi E7000 ICE didn't always respond in a timely manner.
|
||||
Renesas E7000 ICE didn't always respond in a timely manner.
|
||||
|
||||
But if 5 seconds is a long time to sit and wait for retransmissions,
|
||||
20 seconds is far worse. This demonstrates the difficulty of using
|
||||
|
|
@ -170,6 +171,11 @@ int target_executing = 0;
|
|||
/* Level of control structure. */
|
||||
static int control_level;
|
||||
|
||||
/* Sbrk location on entry to main. Used for statistics only. */
|
||||
#ifdef HAVE_SBRK
|
||||
char *lim_at_start;
|
||||
#endif
|
||||
|
||||
/* Signal to catch ^Z typed while reading a command: SIGTSTP or SIGCONT. */
|
||||
|
||||
#ifndef STOP_SIGNAL
|
||||
|
|
@ -377,6 +383,7 @@ catcher (catch_exceptions_ftype *func,
|
|||
int *func_val,
|
||||
enum return_reason *func_caught,
|
||||
char *errstring,
|
||||
char **gdberrmsg,
|
||||
return_mask mask)
|
||||
{
|
||||
SIGJMP_BUF *saved_catch;
|
||||
|
|
@ -422,7 +429,14 @@ catcher (catch_exceptions_ftype *func,
|
|||
if (!caught)
|
||||
val = (*func) (func_uiout, func_args);
|
||||
else
|
||||
val = 0;
|
||||
{
|
||||
val = 0;
|
||||
/* If caller wants a copy of the low-level error message, make one.
|
||||
This is used in the case of a silent error whereby the caller
|
||||
may optionally want to issue the message. */
|
||||
if (gdberrmsg)
|
||||
*gdberrmsg = error_last_message ();
|
||||
}
|
||||
catch_return = saved_catch;
|
||||
|
||||
/* FIXME: cagney/1999-11-05: A correct FUNC implementation will
|
||||
|
|
@ -470,7 +484,25 @@ catch_exceptions (struct ui_out *uiout,
|
|||
{
|
||||
int val;
|
||||
enum return_reason caught;
|
||||
catcher (func, uiout, func_args, &val, &caught, errstring, mask);
|
||||
catcher (func, uiout, func_args, &val, &caught, errstring, NULL, mask);
|
||||
gdb_assert (val >= 0);
|
||||
gdb_assert (caught <= 0);
|
||||
if (caught < 0)
|
||||
return caught;
|
||||
return val;
|
||||
}
|
||||
|
||||
int
|
||||
catch_exceptions_with_msg (struct ui_out *uiout,
|
||||
catch_exceptions_ftype *func,
|
||||
void *func_args,
|
||||
char *errstring,
|
||||
char **gdberrmsg,
|
||||
return_mask mask)
|
||||
{
|
||||
int val;
|
||||
enum return_reason caught;
|
||||
catcher (func, uiout, func_args, &val, &caught, errstring, gdberrmsg, mask);
|
||||
gdb_assert (val >= 0);
|
||||
gdb_assert (caught <= 0);
|
||||
if (caught < 0)
|
||||
|
|
@ -484,7 +516,7 @@ struct catch_errors_args
|
|||
void *func_args;
|
||||
};
|
||||
|
||||
int
|
||||
static int
|
||||
do_catch_errors (struct ui_out *uiout, void *data)
|
||||
{
|
||||
struct catch_errors_args *args = data;
|
||||
|
|
@ -500,7 +532,8 @@ catch_errors (catch_errors_ftype *func, void *func_args, char *errstring,
|
|||
struct catch_errors_args args;
|
||||
args.func = func;
|
||||
args.func_args = func_args;
|
||||
catcher (do_catch_errors, uiout, &args, &val, &caught, errstring, mask);
|
||||
catcher (do_catch_errors, uiout, &args, &val, &caught, errstring,
|
||||
NULL, mask);
|
||||
if (caught != 0)
|
||||
return 0;
|
||||
return val;
|
||||
|
|
@ -634,8 +667,8 @@ do_chdir_cleanup (void *old_dir)
|
|||
void
|
||||
execute_command (char *p, int from_tty)
|
||||
{
|
||||
register struct cmd_list_element *c;
|
||||
register enum language flang;
|
||||
struct cmd_list_element *c;
|
||||
enum language flang;
|
||||
static int warned = 0;
|
||||
char *line;
|
||||
|
||||
|
|
@ -663,10 +696,10 @@ execute_command (char *p, int from_tty)
|
|||
/* If the target is running, we allow only a limited set of
|
||||
commands. */
|
||||
if (event_loop_p && target_can_async_p () && target_executing)
|
||||
if (!strcmp (c->name, "help")
|
||||
&& !strcmp (c->name, "pwd")
|
||||
&& !strcmp (c->name, "show")
|
||||
&& !strcmp (c->name, "stop"))
|
||||
if (strcmp (c->name, "help") != 0
|
||||
&& strcmp (c->name, "pwd") != 0
|
||||
&& strcmp (c->name, "show") != 0
|
||||
&& strcmp (c->name, "stop") != 0)
|
||||
error ("Cannot execute this command while the target is running.");
|
||||
|
||||
/* Pass null arg rather than an empty one. */
|
||||
|
|
@ -693,12 +726,7 @@ execute_command (char *p, int from_tty)
|
|||
}
|
||||
|
||||
/* If this command has been pre-hooked, run the hook first. */
|
||||
if ((c->hook_pre) && (!c->hook_in))
|
||||
{
|
||||
c->hook_in = 1; /* Prevent recursive hooking */
|
||||
execute_user_command (c->hook_pre, (char *) 0);
|
||||
c->hook_in = 0; /* Allow hook to work again once it is complete */
|
||||
}
|
||||
execute_cmd_pre_hook (c);
|
||||
|
||||
if (c->flags & DEPRECATED_WARN_USER)
|
||||
deprecated_cmd_warning (&line);
|
||||
|
|
@ -707,20 +735,15 @@ execute_command (char *p, int from_tty)
|
|||
execute_user_command (c, arg);
|
||||
else if (c->type == set_cmd || c->type == show_cmd)
|
||||
do_setshow_command (arg, from_tty & caution, c);
|
||||
else if (c->func == NULL)
|
||||
else if (!cmd_func_p (c))
|
||||
error ("That is not a command, just a help topic.");
|
||||
else if (call_command_hook)
|
||||
call_command_hook (c, arg, from_tty & caution);
|
||||
else
|
||||
(*c->func) (c, arg, from_tty & caution);
|
||||
cmd_func (c, arg, from_tty & caution);
|
||||
|
||||
/* If this command has been post-hooked, run the hook last. */
|
||||
if ((c->hook_post) && (!c->hook_in))
|
||||
{
|
||||
c->hook_in = 1; /* Prevent recursive hooking */
|
||||
execute_user_command (c->hook_post, (char *) 0);
|
||||
c->hook_in = 0; /* allow hook to work again once it is complete */
|
||||
}
|
||||
execute_cmd_post_hook (c);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -791,10 +814,8 @@ command_loop (void)
|
|||
if (display_space)
|
||||
{
|
||||
#ifdef HAVE_SBRK
|
||||
extern char **environ;
|
||||
char *lim = (char *) sbrk (0);
|
||||
|
||||
space_at_cmd_start = (long) (lim - (char *) &environ);
|
||||
space_at_cmd_start = lim - lim_at_start;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -814,9 +835,8 @@ command_loop (void)
|
|||
if (display_space)
|
||||
{
|
||||
#ifdef HAVE_SBRK
|
||||
extern char **environ;
|
||||
char *lim = (char *) sbrk (0);
|
||||
long space_now = lim - (char *) &environ;
|
||||
long space_now = lim - lim_at_start;
|
||||
long space_diff = space_now - space_at_cmd_start;
|
||||
|
||||
printf_unfiltered ("Space used: %ld (%c%ld for this command)\n",
|
||||
|
|
@ -956,6 +976,29 @@ static int write_history_p;
|
|||
static int history_size;
|
||||
static char *history_filename;
|
||||
|
||||
/* This is like readline(), but it has some gdb-specific behavior.
|
||||
gdb can use readline in both the synchronous and async modes during
|
||||
a single gdb invocation. At the ordinary top-level prompt we might
|
||||
be using the async readline. That means we can't use
|
||||
rl_pre_input_hook, since it doesn't work properly in async mode.
|
||||
However, for a secondary prompt (" >", such as occurs during a
|
||||
`define'), gdb just calls readline() directly, running it in
|
||||
synchronous mode. So for operate-and-get-next to work in this
|
||||
situation, we have to switch the hooks around. That is what
|
||||
gdb_readline_wrapper is for. */
|
||||
char *
|
||||
gdb_readline_wrapper (char *prompt)
|
||||
{
|
||||
/* Set the hook that works in this case. */
|
||||
if (event_loop_p && after_char_processing_hook)
|
||||
{
|
||||
rl_pre_input_hook = (Function *) after_char_processing_hook;
|
||||
after_char_processing_hook = NULL;
|
||||
}
|
||||
|
||||
return readline (prompt);
|
||||
}
|
||||
|
||||
|
||||
#ifdef STOP_SIGNAL
|
||||
static void
|
||||
|
|
@ -1045,8 +1088,8 @@ static int operate_saved_history = -1;
|
|||
|
||||
/* This is put on the appropriate hook and helps operate-and-get-next
|
||||
do its work. */
|
||||
void
|
||||
gdb_rl_operate_and_get_next_completion ()
|
||||
static void
|
||||
gdb_rl_operate_and_get_next_completion (void)
|
||||
{
|
||||
int delta = where_history () - operate_saved_history;
|
||||
/* The `key' argument to rl_get_previous_history is ignored. */
|
||||
|
|
@ -1068,6 +1111,8 @@ gdb_rl_operate_and_get_next_completion ()
|
|||
static int
|
||||
gdb_rl_operate_and_get_next (int count, int key)
|
||||
{
|
||||
int where;
|
||||
|
||||
if (event_loop_p)
|
||||
{
|
||||
/* Use the async hook. */
|
||||
|
|
@ -1080,8 +1125,20 @@ gdb_rl_operate_and_get_next (int count, int key)
|
|||
rl_pre_input_hook = (Function *) gdb_rl_operate_and_get_next_completion;
|
||||
}
|
||||
|
||||
/* Add 1 because we eventually want the next line. */
|
||||
operate_saved_history = where_history () + 1;
|
||||
/* Find the current line, and find the next line to use. */
|
||||
where = where_history();
|
||||
|
||||
/* FIXME: kettenis/20020817: max_input_history is renamed into
|
||||
history_max_entries in readline-4.2. When we do a new readline
|
||||
import, we should probably change it here too, even though
|
||||
readline maintains backwards compatibility for now by still
|
||||
defining max_input_history. */
|
||||
if ((history_is_stifled () && (history_length >= max_input_history)) ||
|
||||
(where >= history_length - 1))
|
||||
operate_saved_history = where;
|
||||
else
|
||||
operate_saved_history = where + 1;
|
||||
|
||||
return rl_newline (1, key);
|
||||
}
|
||||
|
||||
|
|
@ -1105,7 +1162,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
|
|||
{
|
||||
static char *linebuffer = 0;
|
||||
static unsigned linelength = 0;
|
||||
register char *p;
|
||||
char *p;
|
||||
char *p1;
|
||||
char *rl;
|
||||
char *local_prompt = prompt_arg;
|
||||
|
|
@ -1171,9 +1228,9 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
|
|||
|
||||
if (annotation_level > 1 && instream == stdin)
|
||||
{
|
||||
printf_unfiltered ("\n\032\032pre-");
|
||||
printf_unfiltered (annotation_suffix);
|
||||
printf_unfiltered ("\n");
|
||||
puts_unfiltered ("\n\032\032pre-");
|
||||
puts_unfiltered (annotation_suffix);
|
||||
puts_unfiltered ("\n");
|
||||
}
|
||||
|
||||
/* Don't use fancy stuff if not talking to stdin. */
|
||||
|
|
@ -1183,7 +1240,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
|
|||
}
|
||||
else if (command_editing_p && instream == stdin && ISATTY (instream))
|
||||
{
|
||||
rl = readline (local_prompt);
|
||||
rl = gdb_readline_wrapper (local_prompt);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1192,9 +1249,9 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
|
|||
|
||||
if (annotation_level > 1 && instream == stdin)
|
||||
{
|
||||
printf_unfiltered ("\n\032\032post-");
|
||||
printf_unfiltered (annotation_suffix);
|
||||
printf_unfiltered ("\n");
|
||||
puts_unfiltered ("\n\032\032post-");
|
||||
puts_unfiltered (annotation_suffix);
|
||||
puts_unfiltered ("\n");
|
||||
}
|
||||
|
||||
if (!rl || rl == (char *) EOF)
|
||||
|
|
@ -1236,7 +1293,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
|
|||
#define SERVER_COMMAND_LENGTH 7
|
||||
server_command =
|
||||
(p - linebuffer > SERVER_COMMAND_LENGTH)
|
||||
&& STREQN (linebuffer, "server ", SERVER_COMMAND_LENGTH);
|
||||
&& strncmp (linebuffer, "server ", SERVER_COMMAND_LENGTH) == 0;
|
||||
if (server_command)
|
||||
{
|
||||
/* Note that we don't set `line'. Between this and the check in
|
||||
|
|
@ -1329,7 +1386,7 @@ print_gdb_version (struct ui_file *stream)
|
|||
|
||||
/* Second line is a copyright notice. */
|
||||
|
||||
fprintf_filtered (stream, "Copyright 2002 Free Software Foundation, Inc.\n");
|
||||
fprintf_filtered (stream, "Copyright 2004 Free Software Foundation, Inc.\n");
|
||||
|
||||
/* Following the copyright is a brief statement that the program is
|
||||
free software, that users are free to copy and change it on
|
||||
|
|
@ -1345,7 +1402,7 @@ There is absolutely no warranty for GDB. Type \"show warranty\" for details.\n"
|
|||
/* After the required info we print the configuration information. */
|
||||
|
||||
fprintf_filtered (stream, "This GDB was configured as \"");
|
||||
if (!STREQ (host_name, target_name))
|
||||
if (strcmp (host_name, target_name) != 0)
|
||||
{
|
||||
fprintf_filtered (stream, "--host=%s --target=%s", host_name, target_name);
|
||||
}
|
||||
|
|
@ -1358,267 +1415,13 @@ There is absolutely no warranty for GDB. Type \"show warranty\" for details.\n"
|
|||
|
||||
/* get_prompt: access method for the GDB prompt string. */
|
||||
|
||||
#define MAX_PROMPT_SIZE 256
|
||||
|
||||
/*
|
||||
* int get_prompt_1 (char * buf);
|
||||
*
|
||||
* Work-horse for get_prompt (called via catch_errors).
|
||||
* Argument is buffer to hold the formatted prompt.
|
||||
*
|
||||
* Returns: 1 for success (use formatted prompt)
|
||||
* 0 for failure (use gdb_prompt_string).
|
||||
*/
|
||||
|
||||
static int gdb_prompt_escape;
|
||||
|
||||
static int
|
||||
get_prompt_1 (void *data)
|
||||
{
|
||||
char *formatted_prompt = data;
|
||||
char *local_prompt;
|
||||
|
||||
if (event_loop_p)
|
||||
local_prompt = PROMPT (0);
|
||||
else
|
||||
local_prompt = gdb_prompt_string;
|
||||
|
||||
|
||||
if (gdb_prompt_escape == 0)
|
||||
{
|
||||
return 0; /* do no formatting */
|
||||
}
|
||||
else
|
||||
/* formatted prompt */
|
||||
{
|
||||
char fmt[40], *promptp, *outp, *tmp;
|
||||
struct value *arg_val;
|
||||
DOUBLEST doubleval;
|
||||
LONGEST longval;
|
||||
CORE_ADDR addrval;
|
||||
|
||||
int i, len;
|
||||
struct type *arg_type, *elt_type;
|
||||
|
||||
promptp = local_prompt;
|
||||
outp = formatted_prompt;
|
||||
|
||||
while (*promptp != '\0')
|
||||
{
|
||||
int available = MAX_PROMPT_SIZE - (outp - formatted_prompt) - 1;
|
||||
|
||||
if (*promptp != gdb_prompt_escape)
|
||||
{
|
||||
if (available >= 1) /* overflow protect */
|
||||
*outp++ = *promptp++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* GDB prompt string contains escape char. Parse for arg.
|
||||
Two consecutive escape chars followed by arg followed by
|
||||
a comma means to insert the arg using a default format.
|
||||
Otherwise a printf format string may be included between
|
||||
the two escape chars. eg:
|
||||
%%foo, insert foo using default format
|
||||
%2.2f%foo, insert foo using "%2.2f" format
|
||||
A mismatch between the format string and the data type
|
||||
of "foo" is an error (which we don't know how to protect
|
||||
against). */
|
||||
|
||||
fmt[0] = '\0'; /* assume null format string */
|
||||
if (promptp[1] == gdb_prompt_escape) /* double esc char */
|
||||
{
|
||||
promptp += 2; /* skip past two escape chars. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* extract format string from between two esc chars */
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
fmt[i++] = *promptp++; /* copy format string */
|
||||
}
|
||||
while (i < sizeof (fmt) - 1 &&
|
||||
*promptp != gdb_prompt_escape &&
|
||||
*promptp != '\0');
|
||||
|
||||
if (*promptp != gdb_prompt_escape)
|
||||
error ("Syntax error at prompt position %d",
|
||||
promptp - local_prompt);
|
||||
else
|
||||
{
|
||||
promptp++; /* skip second escape char */
|
||||
fmt[i++] = '\0'; /* terminate the format string */
|
||||
}
|
||||
}
|
||||
|
||||
arg_val = parse_to_comma_and_eval (&promptp);
|
||||
if (*promptp == ',')
|
||||
promptp++; /* skip past the comma */
|
||||
arg_type = check_typedef (VALUE_TYPE (arg_val));
|
||||
switch (TYPE_CODE (arg_type))
|
||||
{
|
||||
case TYPE_CODE_ARRAY:
|
||||
elt_type = check_typedef (TYPE_TARGET_TYPE (arg_type));
|
||||
if (TYPE_LENGTH (arg_type) > 0 &&
|
||||
TYPE_LENGTH (elt_type) == 1 &&
|
||||
TYPE_CODE (elt_type) == TYPE_CODE_INT)
|
||||
{
|
||||
int len = TYPE_LENGTH (arg_type);
|
||||
|
||||
if (VALUE_LAZY (arg_val))
|
||||
value_fetch_lazy (arg_val);
|
||||
tmp = VALUE_CONTENTS (arg_val);
|
||||
|
||||
if (len > available)
|
||||
len = available; /* overflow protect */
|
||||
|
||||
/* FIXME: how to protect GDB from crashing
|
||||
from bad user-supplied format string? */
|
||||
if (fmt[0] != 0)
|
||||
sprintf (outp, fmt, tmp);
|
||||
else
|
||||
strncpy (outp, tmp, len);
|
||||
outp[len] = '\0';
|
||||
}
|
||||
break;
|
||||
case TYPE_CODE_PTR:
|
||||
elt_type = check_typedef (TYPE_TARGET_TYPE (arg_type));
|
||||
addrval = value_as_address (arg_val);
|
||||
|
||||
if (TYPE_LENGTH (elt_type) == 1 &&
|
||||
TYPE_CODE (elt_type) == TYPE_CODE_INT &&
|
||||
addrval != 0)
|
||||
{
|
||||
/* display it as a string */
|
||||
char *default_fmt = "%s";
|
||||
char *tmp;
|
||||
int err = 0;
|
||||
|
||||
/* Limiting the number of bytes that the following call
|
||||
will read protects us from sprintf overflow later. */
|
||||
i = target_read_string (addrval, /* src */
|
||||
&tmp, /* dest */
|
||||
available, /* len */
|
||||
&err);
|
||||
if (err) /* read failed */
|
||||
error ("%s on target_read", safe_strerror (err));
|
||||
|
||||
tmp[i] = '\0'; /* force-terminate string */
|
||||
/* FIXME: how to protect GDB from crashing
|
||||
from bad user-supplied format string? */
|
||||
sprintf (outp, fmt[0] == 0 ? default_fmt : fmt,
|
||||
tmp);
|
||||
xfree (tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* display it as a pointer */
|
||||
char *default_fmt = "0x%x";
|
||||
|
||||
/* FIXME: how to protect GDB from crashing
|
||||
from bad user-supplied format string? */
|
||||
if (available >= 16 /*? */ ) /* overflow protect */
|
||||
sprintf (outp, fmt[0] == 0 ? default_fmt : fmt,
|
||||
(long) addrval);
|
||||
}
|
||||
break;
|
||||
case TYPE_CODE_FLT:
|
||||
{
|
||||
char *default_fmt = "%g";
|
||||
|
||||
doubleval = value_as_double (arg_val);
|
||||
/* FIXME: how to protect GDB from crashing
|
||||
from bad user-supplied format string? */
|
||||
if (available >= 16 /*? */ ) /* overflow protect */
|
||||
sprintf (outp, fmt[0] == 0 ? default_fmt : fmt,
|
||||
(double) doubleval);
|
||||
break;
|
||||
}
|
||||
case TYPE_CODE_INT:
|
||||
{
|
||||
char *default_fmt = "%d";
|
||||
|
||||
longval = value_as_long (arg_val);
|
||||
/* FIXME: how to protect GDB from crashing
|
||||
from bad user-supplied format string? */
|
||||
if (available >= 16 /*? */ ) /* overflow protect */
|
||||
sprintf (outp, fmt[0] == 0 ? default_fmt : fmt,
|
||||
(long) longval);
|
||||
break;
|
||||
}
|
||||
case TYPE_CODE_BOOL:
|
||||
{
|
||||
/* no default format for bool */
|
||||
longval = value_as_long (arg_val);
|
||||
if (available >= 8 /*? */ ) /* overflow protect */
|
||||
{
|
||||
if (longval)
|
||||
strcpy (outp, "<true>");
|
||||
else
|
||||
strcpy (outp, "<false>");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TYPE_CODE_ENUM:
|
||||
{
|
||||
/* no default format for enum */
|
||||
longval = value_as_long (arg_val);
|
||||
len = TYPE_NFIELDS (arg_type);
|
||||
/* find enum name if possible */
|
||||
for (i = 0; i < len; i++)
|
||||
if (TYPE_FIELD_BITPOS (arg_type, i) == longval)
|
||||
break; /* match -- end loop */
|
||||
|
||||
if (i < len) /* enum name found */
|
||||
{
|
||||
char *name = TYPE_FIELD_NAME (arg_type, i);
|
||||
|
||||
strncpy (outp, name, available);
|
||||
/* in casel available < strlen (name), */
|
||||
outp[available] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (available >= 16 /*? */ ) /* overflow protect */
|
||||
sprintf (outp, "%ld", (long) longval);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TYPE_CODE_VOID:
|
||||
*outp = '\0';
|
||||
break; /* void type -- no output */
|
||||
default:
|
||||
error ("bad data type at prompt position %d",
|
||||
promptp - local_prompt);
|
||||
break;
|
||||
}
|
||||
outp += strlen (outp);
|
||||
}
|
||||
}
|
||||
*outp++ = '\0'; /* terminate prompt string */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
get_prompt (void)
|
||||
{
|
||||
static char buf[MAX_PROMPT_SIZE];
|
||||
|
||||
if (catch_errors (get_prompt_1, buf, "bad formatted prompt: ",
|
||||
RETURN_MASK_ALL))
|
||||
{
|
||||
return &buf[0]; /* successful formatted prompt */
|
||||
}
|
||||
if (event_loop_p)
|
||||
return PROMPT (0);
|
||||
else
|
||||
{
|
||||
/* Prompt could not be formatted. */
|
||||
if (event_loop_p)
|
||||
return PROMPT (0);
|
||||
else
|
||||
return gdb_prompt_string;
|
||||
}
|
||||
return gdb_prompt_string;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1656,19 +1459,53 @@ quit_confirm (void)
|
|||
else
|
||||
s = "The program is running. Exit anyway? ";
|
||||
|
||||
if (!query (s))
|
||||
if (!query ("%s", s))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Helper routine for quit_force that requires error handling. */
|
||||
|
||||
struct qt_args
|
||||
{
|
||||
char *args;
|
||||
int from_tty;
|
||||
};
|
||||
|
||||
static int
|
||||
quit_target (void *arg)
|
||||
{
|
||||
struct qt_args *qt = (struct qt_args *)arg;
|
||||
|
||||
if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution)
|
||||
{
|
||||
if (attach_flag)
|
||||
target_detach (qt->args, qt->from_tty);
|
||||
else
|
||||
target_kill ();
|
||||
}
|
||||
|
||||
/* UDI wants this, to kill the TIP. */
|
||||
target_close (¤t_target, 1);
|
||||
|
||||
/* Save the history information if it is appropriate to do so. */
|
||||
if (write_history_p && history_filename)
|
||||
write_history (history_filename);
|
||||
|
||||
do_final_cleanups (ALL_CLEANUPS); /* Do any final cleanups before exiting */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Quit without asking for confirmation. */
|
||||
|
||||
void
|
||||
quit_force (char *args, int from_tty)
|
||||
{
|
||||
int exit_code = 0;
|
||||
struct qt_args qt;
|
||||
|
||||
/* An optional expression may be used to cause gdb to terminate with the
|
||||
value of that expression. */
|
||||
|
|
@ -1679,22 +1516,12 @@ quit_force (char *args, int from_tty)
|
|||
exit_code = (int) value_as_long (val);
|
||||
}
|
||||
|
||||
if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution)
|
||||
{
|
||||
if (attach_flag)
|
||||
target_detach (args, from_tty);
|
||||
else
|
||||
target_kill ();
|
||||
}
|
||||
qt.args = args;
|
||||
qt.from_tty = from_tty;
|
||||
|
||||
/* UDI wants this, to kill the TIP. */
|
||||
target_close (1);
|
||||
|
||||
/* Save the history information if it is appropriate to do so. */
|
||||
if (write_history_p && history_filename)
|
||||
write_history (history_filename);
|
||||
|
||||
do_final_cleanups (ALL_CLEANUPS); /* Do any final cleanups before exiting */
|
||||
/* We want to handle any quit errors and exit regardless. */
|
||||
catch_errors (quit_target, &qt,
|
||||
"Quitting: ", RETURN_MASK_ALL);
|
||||
|
||||
exit (exit_code);
|
||||
}
|
||||
|
|
@ -1708,7 +1535,6 @@ input_from_terminal_p (void)
|
|||
return gdb_has_a_terminal () && (instream == stdin) & caution;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
dont_repeat_command (char *ignored, int from_tty)
|
||||
{
|
||||
|
|
@ -1794,7 +1620,6 @@ show_commands (char *args, int from_tty)
|
|||
}
|
||||
|
||||
/* Called by do_setshow_command. */
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
set_history_size_command (char *args, int from_tty, struct cmd_list_element *c)
|
||||
{
|
||||
|
|
@ -1809,7 +1634,6 @@ set_history_size_command (char *args, int from_tty, struct cmd_list_element *c)
|
|||
}
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
set_history (char *args, int from_tty)
|
||||
{
|
||||
|
|
@ -1817,7 +1641,6 @@ set_history (char *args, int from_tty)
|
|||
help_list (sethistlist, "set history ", -1, gdb_stdout);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
show_history (char *args, int from_tty)
|
||||
{
|
||||
|
|
@ -1827,7 +1650,6 @@ show_history (char *args, int from_tty)
|
|||
int info_verbose = 0; /* Default verbose msgs off */
|
||||
|
||||
/* Called by do_setshow_command. An elaborate joke. */
|
||||
/* ARGSUSED */
|
||||
void
|
||||
set_verbose (char *args, int from_tty, struct cmd_list_element *c)
|
||||
{
|
||||
|
|
@ -1916,7 +1738,6 @@ init_main (void)
|
|||
if (annotation_level > 1)
|
||||
set_async_annotation_level (NULL, 0, NULL);
|
||||
}
|
||||
gdb_prompt_escape = 0; /* default to none. */
|
||||
|
||||
/* Set the important stuff up for command editing. */
|
||||
command_editing_p = 1;
|
||||
|
|
@ -1924,11 +1745,11 @@ init_main (void)
|
|||
write_history_p = 0;
|
||||
|
||||
/* Setup important stuff for command line editing. */
|
||||
rl_completion_entry_function = (int (*)()) readline_line_completion_function;
|
||||
rl_completer_word_break_characters =
|
||||
get_gdb_completer_word_break_characters ();
|
||||
rl_completion_entry_function = readline_line_completion_function;
|
||||
rl_completer_word_break_characters = default_word_break_characters ();
|
||||
rl_completer_quote_characters = get_gdb_completer_quote_characters ();
|
||||
rl_readline_name = "gdb";
|
||||
rl_terminal_name = getenv ("TERM");
|
||||
|
||||
/* The name for this defun comes from Bash, where it originated.
|
||||
15 is Control-o, the same binding this function has in Bash. */
|
||||
|
|
@ -1955,13 +1776,6 @@ init_main (void)
|
|||
set_cmd_sfunc (c, set_async_prompt);
|
||||
}
|
||||
|
||||
add_show_from_set
|
||||
(add_set_cmd ("prompt-escape-char", class_support, var_zinteger,
|
||||
(char *) &gdb_prompt_escape,
|
||||
"Set escape character for formatting of gdb's prompt",
|
||||
&setlist),
|
||||
&showlist);
|
||||
|
||||
add_com ("dont-repeat", class_support, dont_repeat_command, "Don't repeat this command.\n\
|
||||
Primarily used inside of user-defined commands that should not be repeated when\n\
|
||||
hitting return.");
|
||||
|
|
@ -1999,7 +1813,7 @@ Without an argument, saving is enabled.", &sethistlist),
|
|||
&showhistlist);
|
||||
|
||||
c = add_set_cmd ("size", no_class, var_integer, (char *) &history_size,
|
||||
"Set the size of the command history, \n\
|
||||
"Set the size of the command history,\n\
|
||||
ie. the number of previous commands to keep a record of.", &sethistlist);
|
||||
add_show_from_set (c, &showhistlist);
|
||||
set_cmd_sfunc (c, set_history_size_command);
|
||||
|
|
@ -2007,8 +1821,8 @@ ie. the number of previous commands to keep a record of.", &sethistlist);
|
|||
c = add_set_cmd ("filename", no_class, var_filename,
|
||||
(char *) &history_filename,
|
||||
"Set the filename in which to record the command history\n\
|
||||
(the list of previous commands of which a record is kept).", &sethistlist);
|
||||
c->completer = filename_completer;
|
||||
(the list of previous commands of which a record is kept).", &sethistlist);
|
||||
set_cmd_completer (c, filename_completer);
|
||||
add_show_from_set (c, &showhistlist);
|
||||
|
||||
add_show_from_set
|
||||
|
|
@ -2095,19 +1909,4 @@ gdb_init (char *argv0)
|
|||
it wants GDB to revert to the CLI, it should clear init_ui_hook. */
|
||||
if (init_ui_hook)
|
||||
init_ui_hook (argv0);
|
||||
|
||||
/* Install the default UI */
|
||||
if (!init_ui_hook)
|
||||
{
|
||||
uiout = cli_out_new (gdb_stdout);
|
||||
|
||||
/* All the interpreters should have had a look at things by now.
|
||||
Initialize the selected interpreter. */
|
||||
if (interpreter_p)
|
||||
{
|
||||
fprintf_unfiltered (gdb_stderr, "Interpreter `%s' unrecognized.\n",
|
||||
interpreter_p);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1 +1 @@
|
|||
5.2.1
|
||||
6.1.1
|
||||
|
|
|
|||
Loading…
Reference in a new issue