Update to GDB 6.1.1. These files are identical to the vendor branch.

This commit is contained in:
Marcel Moolenaar 2004-06-20 19:47:29 +00:00
parent cafb9261fd
commit c07ff117d2
29 changed files with 17963 additions and 10565 deletions

File diff suppressed because it is too large Load diff

View file

@ -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),
&current_objfile->symbol_obstack);
&current_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),
&current_objfile->symbol_obstack);
&current_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
(&current_objfile->symbol_obstack,
(&current_objfile->objfile_obstack,
sizeof (struct symbol));
memset (sym, 0, sizeof (struct symbol));
SYMBOL_NAME (sym) =
DEPRECATED_SYMBOL_NAME (sym) =
obsavestring (name, strlen (name),
&current_objfile->symbol_obstack);
&current_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;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 *) &section, sizeof (section));
obstack_grow (&objfile->objfile_obstack, (char *) &section, 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

View file

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

View file

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

View file

@ -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) (&current_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);

View file

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

View file

@ -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 (&current_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

View file

@ -1 +1 @@
5.2.1
6.1.1